aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/sqlite3
diff options
context:
space:
mode:
authorsnermolaev <snermolaev@yandex-team.ru>2022-02-10 16:45:53 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:53 +0300
commit7353a3fdea9c67c256980c00a2b3b67f09b23a27 (patch)
tree1a2c5ffcf89eb53ecd79dbc9bc0a195c27404d0c /contrib/libs/sqlite3
parent2015790ac9fcc04caab83fccc23ab2460310a797 (diff)
downloadydb-7353a3fdea9c67c256980c00a2b3b67f09b23a27.tar.gz
Restoring authorship annotation for <snermolaev@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/sqlite3')
-rw-r--r--contrib/libs/sqlite3/sqlite3.c101620
-rw-r--r--contrib/libs/sqlite3/sqlite3.h6068
-rw-r--r--contrib/libs/sqlite3/sqlite3ext.h136
-rw-r--r--contrib/libs/sqlite3/test_multiplex.c2590
-rw-r--r--contrib/libs/sqlite3/test_multiplex.h198
5 files changed, 55306 insertions, 55306 deletions
diff --git a/contrib/libs/sqlite3/sqlite3.c b/contrib/libs/sqlite3/sqlite3.c
index 5b3db099b4f..3b763874beb 100644
--- a/contrib/libs/sqlite3/sqlite3.c
+++ b/contrib/libs/sqlite3/sqlite3.c
@@ -9,7 +9,7 @@
**
** This file is all you need to compile SQLite. To use SQLite in other
** programs, you need this file and the "sqlite3.h" header file that defines
-** the programming interface to the SQLite library. (If you do not have
+** the programming interface to the SQLite library. (If you do not have
** the "sqlite3.h" header file at hand, you will find a copy embedded within
** the text of this file. Search for "Begin file sqlite3.h" to find the start
** of the embedded sqlite3.h header file.) Additional code files may be needed
@@ -38,45 +38,45 @@
** Internal interface definitions for SQLite.
**
*/
-#ifndef SQLITEINT_H
-#define SQLITEINT_H
-
-/* Special Comments:
-**
-** Some comments have special meaning to the tools that measure test
-** coverage:
-**
-** NO_TEST - The branches on this line are not
-** measured by branch coverage. This is
-** used on lines of code that actually
-** implement parts of coverage testing.
-**
-** OPTIMIZATION-IF-TRUE - This branch is allowed to alway be false
-** and the correct answer is still obtained,
-** though perhaps more slowly.
-**
-** OPTIMIZATION-IF-FALSE - This branch is allowed to alway be true
-** and the correct answer is still obtained,
-** though perhaps more slowly.
-**
-** PREVENTS-HARMLESS-OVERREAD - This branch prevents a buffer overread
-** that would be harmless and undetectable
+#ifndef SQLITEINT_H
+#define SQLITEINT_H
+
+/* Special Comments:
+**
+** Some comments have special meaning to the tools that measure test
+** coverage:
+**
+** NO_TEST - The branches on this line are not
+** measured by branch coverage. This is
+** used on lines of code that actually
+** implement parts of coverage testing.
+**
+** OPTIMIZATION-IF-TRUE - This branch is allowed to alway be false
+** and the correct answer is still obtained,
+** though perhaps more slowly.
+**
+** OPTIMIZATION-IF-FALSE - This branch is allowed to alway be true
+** and the correct answer is still obtained,
+** though perhaps more slowly.
+**
+** PREVENTS-HARMLESS-OVERREAD - This branch prevents a buffer overread
+** that would be harmless and undetectable
** if it did occur.
-**
-** In all cases, the special comment must be enclosed in the usual
+**
+** In all cases, the special comment must be enclosed in the usual
** slash-asterisk...asterisk-slash comment marks, with no spaces between the
-** asterisks and the comment text.
-*/
-
-/*
-** Make sure the Tcl calling convention macro is defined. This macro is
-** only used by test code and Tcl integration code.
-*/
-#ifndef SQLITE_TCLAPI
-# define SQLITE_TCLAPI
-#endif
-
-/*
+** asterisks and the comment text.
+*/
+
+/*
+** Make sure the Tcl calling convention macro is defined. This macro is
+** only used by test code and Tcl integration code.
+*/
+#ifndef SQLITE_TCLAPI
+# define SQLITE_TCLAPI
+#endif
+
+/*
** Include the header file used to customize the compiler options for MSVC.
** This should be done first so that it can successfully prevent spurious
** compiler warnings due to subsequent content in this file and other files
@@ -98,8 +98,8 @@
**
** This file contains code that is specific to MSVC.
*/
-#ifndef SQLITE_MSVC_H
-#define SQLITE_MSVC_H
+#ifndef SQLITE_MSVC_H
+#define SQLITE_MSVC_H
#if defined(_MSC_VER)
#pragma warning(disable : 4054)
@@ -124,7 +124,7 @@
#define SQLITE_4_BYTE_ALIGNED_MALLOC
#endif /* defined(_MSC_VER) && !defined(_WIN64) */
-#endif /* SQLITE_MSVC_H */
+#endif /* SQLITE_MSVC_H */
/************** End of msvc.h ************************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -162,9 +162,9 @@
#else
/* This is not VxWorks. */
#define OS_VXWORKS 0
-#define HAVE_FCHOWN 1
-#define HAVE_READLINK 1
-#define HAVE_LSTAT 1
+#define HAVE_FCHOWN 1
+#define HAVE_READLINK 1
+#define HAVE_LSTAT 1
#endif /* defined(_WRS_KERNEL) */
/************** End of vxworks.h *********************************************/
@@ -202,29 +202,29 @@
# define _LARGEFILE_SOURCE 1
#endif
-/* The GCC_VERSION and MSVC_VERSION macros are used to
-** conditionally include optimizations for each of these compilers. A
-** value of 0 means that compiler is not being used. The
-** SQLITE_DISABLE_INTRINSIC macro means do not use any compiler-specific
-** optimizations, and hence set all compiler macros to 0
-**
-** There was once also a CLANG_VERSION macro. However, we learn that the
-** version numbers in clang are for "marketing" only and are inconsistent
-** and unreliable. Fortunately, all versions of clang also recognize the
-** gcc version numbers and have reasonable settings for gcc version numbers,
-** so the GCC_VERSION macro will be set to a correct non-zero value even
-** when compiling with clang.
-*/
-#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
+/* The GCC_VERSION and MSVC_VERSION macros are used to
+** conditionally include optimizations for each of these compilers. A
+** value of 0 means that compiler is not being used. The
+** SQLITE_DISABLE_INTRINSIC macro means do not use any compiler-specific
+** optimizations, and hence set all compiler macros to 0
+**
+** There was once also a CLANG_VERSION macro. However, we learn that the
+** version numbers in clang are for "marketing" only and are inconsistent
+** and unreliable. Fortunately, all versions of clang also recognize the
+** gcc version numbers and have reasonable settings for gcc version numbers,
+** so the GCC_VERSION macro will be set to a correct non-zero value even
+** when compiling with clang.
+*/
+#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
#else
# define GCC_VERSION 0
#endif
-#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
-# define MSVC_VERSION _MSC_VER
-#else
-# define MSVC_VERSION 0
-#endif
+#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
+# define MSVC_VERSION _MSC_VER
+#else
+# define MSVC_VERSION 0
+#endif
/*
** Some C99 functions in "math.h" are only present for MSVC when its version
@@ -306,7 +306,7 @@
/************** Include sqlite3.h in the middle of sqliteInt.h ***************/
/************** Begin file sqlite3.h *****************************************/
/*
-** 2001-09-15
+** 2001-09-15
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -337,8 +337,8 @@
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
*/
-#ifndef SQLITE3_H
-#define SQLITE3_H
+#ifndef SQLITE3_H
+#define SQLITE3_H
#include <stdarg.h> /* Needed for the definition of va_list */
/*
@@ -384,18 +384,18 @@ extern "C" {
#ifndef SQLITE_CDECL
# define SQLITE_CDECL
#endif
-#ifndef SQLITE_APICALL
-# define SQLITE_APICALL
-#endif
+#ifndef SQLITE_APICALL
+# define SQLITE_APICALL
+#endif
#ifndef SQLITE_STDCALL
-# define SQLITE_STDCALL SQLITE_APICALL
+# define SQLITE_STDCALL SQLITE_APICALL
+#endif
+#ifndef SQLITE_CALLBACK
+# define SQLITE_CALLBACK
+#endif
+#ifndef SQLITE_SYSAPI
+# define SQLITE_SYSAPI
#endif
-#ifndef SQLITE_CALLBACK
-# define SQLITE_CALLBACK
-#endif
-#ifndef SQLITE_SYSAPI
-# define SQLITE_SYSAPI
-#endif
/*
** These no-op macros are used in front of interfaces to mark those
@@ -439,15 +439,15 @@ extern "C" {
** and Z will be reset to zero.
**
** Since [version 3.6.18] ([dateof:3.6.18]),
-** SQLite source code has been stored in the
+** SQLite source code has been stored in the
** <a href="http://www.fossil-scm.org/">Fossil configuration management
** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to
** a string which identifies a particular check-in of SQLite
** within its configuration management system. ^The SQLITE_SOURCE_ID
-** string contains the date and time of the check-in (UTC) and a SHA1
-** or SHA3-256 hash of the entire source tree. If the source code has
-** been edited in any way since it was last checked in, then the last
-** four hexadecimal digits of the hash may be modified.
+** string contains the date and time of the check-in (UTC) and a SHA1
+** or SHA3-256 hash of the entire source tree. If the source code has
+** been edited in any way since it was last checked in, then the last
+** four hexadecimal digits of the hash may be modified.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
@@ -459,19 +459,19 @@ extern "C" {
/*
** CAPI3REF: Run-Time Library Version Numbers
-** KEYWORDS: sqlite3_version sqlite3_sourceid
+** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
** but are associated with the library instead of the header file. ^(Cautious
** programmers might include assert() statements in their application to
** verify that values returned by these interfaces match the macros in
-** the header, and thus ensure that the application is
+** the header, and thus ensure that the application is
** compiled with matching library and header files.
**
** <blockquote><pre>
** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
+** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
** </pre></blockquote>)^
**
@@ -483,16 +483,16 @@ extern "C" {
** sqlite3_libversion_number() function returns an integer equal to
** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns
** a pointer to a string constant whose value is the same as the
-** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built
-** using an edited copy of [the amalgamation], then the last four characters
-** of the hash might be different from [SQLITE_SOURCE_ID].)^
+** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built
+** using an edited copy of [the amalgamation], then the last four characters
+** of the hash might be different from [SQLITE_SOURCE_ID].)^
**
** See also: [sqlite_version()] and [sqlite_source_id()].
*/
SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
-SQLITE_API const char *sqlite3_libversion(void);
-SQLITE_API const char *sqlite3_sourceid(void);
-SQLITE_API int sqlite3_libversion_number(void);
+SQLITE_API const char *sqlite3_libversion(void);
+SQLITE_API const char *sqlite3_sourceid(void);
+SQLITE_API int sqlite3_libversion_number(void);
/*
** CAPI3REF: Run-Time Library Compilation Options Diagnostics
@@ -517,8 +517,8 @@ SQLITE_API int sqlite3_libversion_number(void);
** [sqlite_compileoption_get()] and the [compile_options pragma].
*/
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
-SQLITE_API const char *sqlite3_compileoption_get(int N);
+SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
+SQLITE_API const char *sqlite3_compileoption_get(int N);
#else
# define sqlite3_compileoption_used(X) 0
# define sqlite3_compileoption_get(X) ((void*)0)
@@ -560,7 +560,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N);
**
** See the [threading mode] documentation for additional information.
*/
-SQLITE_API int sqlite3_threadsafe(void);
+SQLITE_API int sqlite3_threadsafe(void);
/*
** CAPI3REF: Database Connection Handle
@@ -596,11 +596,11 @@ typedef struct sqlite3 sqlite3;
*/
#ifdef SQLITE_INT64_TYPE
typedef SQLITE_INT64_TYPE sqlite_int64;
-# ifdef SQLITE_UINT64_TYPE
- typedef SQLITE_UINT64_TYPE sqlite_uint64;
+# ifdef SQLITE_UINT64_TYPE
+ typedef SQLITE_UINT64_TYPE sqlite_uint64;
# else
- typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
-# endif
+ typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
+# endif
#elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 sqlite_int64;
typedef unsigned __int64 sqlite_uint64;
@@ -657,8 +657,8 @@ typedef sqlite_uint64 sqlite3_uint64;
** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
** argument is a harmless no-op.
*/
-SQLITE_API int sqlite3_close(sqlite3*);
-SQLITE_API int sqlite3_close_v2(sqlite3*);
+SQLITE_API int sqlite3_close(sqlite3*);
+SQLITE_API int sqlite3_close_v2(sqlite3*);
/*
** The type for a callback function.
@@ -694,7 +694,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** from [sqlite3_malloc()] and passed back through the 5th parameter.
** To avoid memory leaks, the application should invoke [sqlite3_free()]
** on error message strings returned through the 5th parameter of
-** sqlite3_exec() after the error message string is no longer needed.
+** sqlite3_exec() after the error message string is no longer needed.
** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors
** occur, then sqlite3_exec() sets the pointer in its 5th parameter to
** NULL before returning.
@@ -721,7 +721,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** Restrictions:
**
** <ul>
-** <li> The application must ensure that the 1st parameter to sqlite3_exec()
+** <li> The application must ensure that the 1st parameter to sqlite3_exec()
** is a valid and open [database connection].
** <li> The application must not close the [database connection] specified by
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
@@ -729,7 +729,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
** </ul>
*/
-SQLITE_API int sqlite3_exec(
+SQLITE_API int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
@@ -750,7 +750,7 @@ SQLITE_API int sqlite3_exec(
*/
#define SQLITE_OK 0 /* Successful result */
/* beginning-of-error-codes */
-#define SQLITE_ERROR 1 /* Generic error */
+#define SQLITE_ERROR 1 /* Generic error */
#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */
#define SQLITE_PERM 3 /* Access permission denied */
#define SQLITE_ABORT 4 /* Callback routine requested an abort */
@@ -765,7 +765,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_FULL 13 /* Insertion failed because database is full */
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
-#define SQLITE_EMPTY 16 /* Internal use only */
+#define SQLITE_EMPTY 16 /* Internal use only */
#define SQLITE_SCHEMA 17 /* The database schema changed */
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
@@ -773,7 +773,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_MISUSE 21 /* Library used incorrectly */
#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
#define SQLITE_AUTH 23 /* Authorization denied */
-#define SQLITE_FORMAT 24 /* Not used */
+#define SQLITE_FORMAT 24 /* Not used */
#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */
@@ -790,8 +790,8 @@ SQLITE_API int sqlite3_exec(
** [result codes]. However, experience has shown that many of
** these result codes are too coarse-grained. They do not provide as
** much information about problems as programmers might like. In an effort to
-** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8]
-** and later) include
+** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8]
+** and later) include
** support for additional result codes that provide more detailed information
** about errors. These [extended result codes] are enabled or disabled
** on a per database connection basis using the
@@ -799,8 +799,8 @@ SQLITE_API int sqlite3_exec(
** the most recent error can be obtained using
** [sqlite3_extended_errcode()].
*/
-#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
-#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
+#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
+#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8))
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
@@ -828,11 +828,11 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
-#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
-#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
-#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
-#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
-#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
+#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
+#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
+#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
+#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
+#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
#define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
@@ -853,8 +853,8 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
-#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
-#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8))
+#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
+#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
@@ -872,7 +872,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
-#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
+#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
/*
@@ -946,15 +946,15 @@ SQLITE_API int sqlite3_exec(
** file that were written at the application level might have changed
** and that adjacent bytes, even bytes within the same sector are
** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
-** flag indicates that a file cannot be deleted when open. The
+** flag indicates that a file cannot be deleted when open. The
** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
** read-only media and cannot be changed even by processes with
** elevated privileges.
-**
-** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying
-** filesystem supports doing multiple write operations atomically when those
-** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
-** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
+**
+** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying
+** filesystem supports doing multiple write operations atomically when those
+** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
+** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@@ -970,7 +970,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800
#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
#define SQLITE_IOCAP_IMMUTABLE 0x00002000
-#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000
+#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000
/*
** CAPI3REF: File Locking Levels
@@ -1102,10 +1102,10 @@ struct sqlite3_file {
** <li> [SQLITE_IOCAP_ATOMIC64K]
** <li> [SQLITE_IOCAP_SAFE_APPEND]
** <li> [SQLITE_IOCAP_SEQUENTIAL]
-** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
-** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
-** <li> [SQLITE_IOCAP_IMMUTABLE]
-** <li> [SQLITE_IOCAP_BATCH_ATOMIC]
+** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
+** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
+** <li> [SQLITE_IOCAP_IMMUTABLE]
+** <li> [SQLITE_IOCAP_BATCH_ATOMIC]
** </ul>
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
@@ -1199,14 +1199,14 @@ struct sqlite3_io_methods {
** <li>[[SQLITE_FCNTL_FILE_POINTER]]
** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer
** to the [sqlite3_file] object associated with a particular database
-** connection. See also [SQLITE_FCNTL_JOURNAL_POINTER].
-**
-** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]]
-** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer
-** to the [sqlite3_file] object associated with the journal file (either
-** the [rollback journal] or the [write-ahead log]) for a particular database
-** connection. See also [SQLITE_FCNTL_FILE_POINTER].
-**
+** connection. See also [SQLITE_FCNTL_JOURNAL_POINTER].
+**
+** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]]
+** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer
+** to the [sqlite3_file] object associated with the journal file (either
+** the [rollback journal] or the [write-ahead log]) for a particular database
+** connection. See also [SQLITE_FCNTL_FILE_POINTER].
+**
** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
** No longer in use.
**
@@ -1243,7 +1243,7 @@ struct sqlite3_io_methods {
** opcode allows these two values (10 retries and 25 milliseconds of delay)
** to be adjusted. The values are changed for all database connections
** within the same process. The argument is a pointer to an array of two
-** integers where the first integer is the new retry count and the second
+** integers where the first integer is the new retry count and the second
** integer is the delay. If either integer is negative, then the setting
** is not changed but instead the prior value of that setting is written
** into the array entry, allowing the current retry settings to be
@@ -1293,15 +1293,15 @@ struct sqlite3_io_methods {
** pointer in case this file-control is not implemented. This file-control
** is intended for diagnostic use only.
**
-** <li>[[SQLITE_FCNTL_VFS_POINTER]]
-** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level
-** [VFSes] currently in use. ^(The argument X in
-** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be
-** of type "[sqlite3_vfs] **". This opcodes will set *X
-** to a pointer to the top-level VFS.)^
-** ^When there are multiple VFS shims in the stack, this opcode finds the
-** upper-most shim only.
-**
+** <li>[[SQLITE_FCNTL_VFS_POINTER]]
+** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level
+** [VFSes] currently in use. ^(The argument X in
+** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be
+** of type "[sqlite3_vfs] **". This opcodes will set *X
+** to a pointer to the top-level VFS.)^
+** ^When there are multiple VFS shims in the stack, this opcode finds the
+** upper-most shim only.
+**
** <li>[[SQLITE_FCNTL_PRAGMA]]
** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA]
** file control is sent to the open [sqlite3_file] object corresponding
@@ -1372,12 +1372,12 @@ struct sqlite3_io_methods {
** on whether or not the file has been renamed, moved, or deleted since it
** was first opened.
**
-** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
-** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
-** underlying native file handle associated with a file handle. This file
-** control interprets its argument as a pointer to a native file handle and
-** writes the resulting value there.
-**
+** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
+** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
+** underlying native file handle associated with a file handle. This file
+** control interprets its argument as a pointer to a native file handle and
+** writes the resulting value there.
+**
** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
** opcode causes the xFileControl method to swap the file handle with the one
@@ -1399,40 +1399,40 @@ struct sqlite3_io_methods {
** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for
** this opcode.
-**
-** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]]
-** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then
-** the file descriptor is placed in "batch write mode", which
-** means all subsequent write operations will be deferred and done
-** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. Systems
-** that do not support batch atomic writes will return SQLITE_NOTFOUND.
-** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to
-** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or
-** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make
-** no VFS interface calls on the same [sqlite3_file] file descriptor
-** except for calls to the xWrite method and the xFileControl method
-** with [SQLITE_FCNTL_SIZE_HINT].
-**
-** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]]
-** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write
+**
+** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]]
+** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then
+** the file descriptor is placed in "batch write mode", which
+** means all subsequent write operations will be deferred and done
+** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. Systems
+** that do not support batch atomic writes will return SQLITE_NOTFOUND.
+** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to
+** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or
+** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make
+** no VFS interface calls on the same [sqlite3_file] file descriptor
+** except for calls to the xWrite method and the xFileControl method
+** with [SQLITE_FCNTL_SIZE_HINT].
+**
+** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]]
+** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write
** operations since the previous successful call to
-** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically.
-** This file control returns [SQLITE_OK] if and only if the writes were
-** all performed successfully and have been committed to persistent storage.
-** ^Regardless of whether or not it is successful, this file control takes
-** the file descriptor out of batch write mode so that all subsequent
-** write operations are independent.
-** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without
-** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
-**
-** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]]
-** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write
+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically.
+** This file control returns [SQLITE_OK] if and only if the writes were
+** all performed successfully and have been committed to persistent storage.
+** ^Regardless of whether or not it is successful, this file control takes
+** the file descriptor out of batch write mode so that all subsequent
+** write operations are independent.
+** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without
+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
+**
+** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]]
+** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write
** operations since the previous successful call to
-** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
-** ^This file control takes the file descriptor out of batch write mode
-** so that all subsequent write operations are independent.
-** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
-** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
+** ^This file control takes the file descriptor out of batch write mode
+** so that all subsequent write operations are independent.
+** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
**
** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS
@@ -1516,13 +1516,13 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_WAL_BLOCK 24
#define SQLITE_FCNTL_ZIPVFS 25
#define SQLITE_FCNTL_RBU 26
-#define SQLITE_FCNTL_VFS_POINTER 27
-#define SQLITE_FCNTL_JOURNAL_POINTER 28
-#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
-#define SQLITE_FCNTL_PDB 30
-#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31
-#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
-#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
+#define SQLITE_FCNTL_VFS_POINTER 27
+#define SQLITE_FCNTL_JOURNAL_POINTER 28
+#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
+#define SQLITE_FCNTL_PDB 30
+#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31
+#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
+#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
#define SQLITE_FCNTL_DATA_VERSION 35
#define SQLITE_FCNTL_SIZE_LIMIT 36
@@ -1551,16 +1551,16 @@ struct sqlite3_io_methods {
typedef struct sqlite3_mutex sqlite3_mutex;
/*
-** CAPI3REF: Loadable Extension Thunk
-**
-** A pointer to the opaque sqlite3_api_routines structure is passed as
-** the third parameter to entry points of [loadable extensions]. This
-** structure must be typedefed in order to work around compiler warnings
-** on some platforms.
-*/
-typedef struct sqlite3_api_routines sqlite3_api_routines;
-
-/*
+** CAPI3REF: Loadable Extension Thunk
+**
+** A pointer to the opaque sqlite3_api_routines structure is passed as
+** the third parameter to entry points of [loadable extensions]. This
+** structure must be typedefed in order to work around compiler warnings
+** on some platforms.
+*/
+typedef struct sqlite3_api_routines sqlite3_api_routines;
+
+/*
** CAPI3REF: OS Interface Object
**
** An instance of the sqlite3_vfs object defines the interface between
@@ -1568,17 +1568,17 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** in the name of the object stands for "virtual file system". See
** the [VFS | VFS documentation] for further information.
**
-** The VFS interface is sometimes extended by adding new methods onto
-** the end. Each time such an extension occurs, the iVersion field
-** is incremented. The iVersion value started out as 1 in
-** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
-** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
-** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields
-** may be appended to the sqlite3_vfs object and the iVersion value
-** may increase again in future versions of SQLite.
+** The VFS interface is sometimes extended by adding new methods onto
+** the end. Each time such an extension occurs, the iVersion field
+** is incremented. The iVersion value started out as 1 in
+** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
+** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
+** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields
+** may be appended to the sqlite3_vfs object and the iVersion value
+** may increase again in future versions of SQLite.
** Note that due to an oversight, the structure
** of the sqlite3_vfs object changed in the transition from
-** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
+** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
** and yet the iVersion field was not increased.
**
** The szOsFile field is the size of the subclassed [sqlite3_file]
@@ -1765,7 +1765,7 @@ struct sqlite3_vfs {
const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
/*
** The methods above are in versions 1 through 3 of the sqlite_vfs object.
- ** New fields may be appended in future versions. The iVersion
+ ** New fields may be appended in future versions. The iVersion
** value will increment whenever this happens.
*/
};
@@ -1907,10 +1907,10 @@ struct sqlite3_vfs {
** must return [SQLITE_OK] on success and some other [error code] upon
** failure.
*/
-SQLITE_API int sqlite3_initialize(void);
-SQLITE_API int sqlite3_shutdown(void);
-SQLITE_API int sqlite3_os_init(void);
-SQLITE_API int sqlite3_os_end(void);
+SQLITE_API int sqlite3_initialize(void);
+SQLITE_API int sqlite3_shutdown(void);
+SQLITE_API int sqlite3_os_init(void);
+SQLITE_API int sqlite3_os_end(void);
/*
** CAPI3REF: Configuring The SQLite Library
@@ -1921,11 +1921,11 @@ SQLITE_API int sqlite3_os_end(void);
** applications and so this routine is usually not necessary. It is
** provided to support rare applications with unusual needs.
**
-** <b>The sqlite3_config() interface is not threadsafe. The application
-** must ensure that no other SQLite interfaces are invoked by other
-** threads while sqlite3_config() is running.</b>
-**
-** The sqlite3_config() interface
+** <b>The sqlite3_config() interface is not threadsafe. The application
+** must ensure that no other SQLite interfaces are invoked by other
+** threads while sqlite3_config() is running.</b>
+**
+** The sqlite3_config() interface
** may only be invoked prior to library initialization using
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
@@ -1943,7 +1943,7 @@ SQLITE_API int sqlite3_os_end(void);
** ^If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
*/
-SQLITE_API int sqlite3_config(int, ...);
+SQLITE_API int sqlite3_config(int, ...);
/*
** CAPI3REF: Configure database connections
@@ -1962,7 +1962,7 @@ SQLITE_API int sqlite3_config(int, ...);
** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
** the call is considered successful.
*/
-SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Memory Allocation Routines
@@ -2113,16 +2113,16 @@ struct sqlite3_mem_methods {
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
-** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt>
-** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of
-** type int, interpreted as a boolean, which if true provides a hint to
-** SQLite that it should avoid large memory allocations if possible.
-** SQLite will run faster if it is free to make large memory allocations,
-** but some application might prefer to run slower in exchange for
-** guarantees about memory fragmentation that are possible if large
-** allocations are avoided. This hint is normally off.
-** </dd>
-**
+** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt>
+** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of
+** type int, interpreted as a boolean, which if true provides a hint to
+** SQLite that it should avoid large memory allocations if possible.
+** SQLite will run faster if it is free to make large memory allocations,
+** but some application might prefer to run slower in exchange for
+** guarantees about memory fragmentation that are possible if large
+** allocations are avoided. This hint is normally off.
+** </dd>
+**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
** interpreted as a boolean, which enables or disables the collection of
@@ -2141,43 +2141,43 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
-** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used.
+** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used.
** </dd>
**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
-** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
+** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
** that SQLite can use for the database page cache with the default page
** cache implementation.
** This configuration option is a no-op if an application-defined page
-** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
+** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
-** 8-byte aligned memory (pMem), the size of each page cache line (sz),
-** and the number of cache lines (N).
+** 8-byte aligned memory (pMem), the size of each page cache line (sz),
+** and the number of cache lines (N).
** The sz argument should be the size of the largest database page
** (a power of two between 512 and 65536) plus some extra bytes for each
** page header. ^The number of extra bytes needed by the page header
-** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ].
+** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ].
** ^It is harmless, apart from the wasted memory,
-** for the sz parameter to be larger than necessary. The pMem
-** argument must be either a NULL pointer or a pointer to an 8-byte
-** aligned block of memory of at least sz*N bytes, otherwise
-** subsequent behavior is undefined.
-** ^When pMem is not NULL, SQLite will strive to use the memory provided
-** to satisfy page cache needs, falling back to [sqlite3_malloc()] if
-** a page cache line is larger than sz bytes or if all of the pMem buffer
-** is exhausted.
-** ^If pMem is NULL and N is non-zero, then each database connection
-** does an initial bulk allocation for page cache memory
-** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or
-** of -1024*N bytes if N is negative, . ^If additional
-** page cache memory is needed beyond what is provided by the initial
-** allocation, then SQLite goes to [sqlite3_malloc()] separately for each
-** additional cache line. </dd>
+** for the sz parameter to be larger than necessary. The pMem
+** argument must be either a NULL pointer or a pointer to an 8-byte
+** aligned block of memory of at least sz*N bytes, otherwise
+** subsequent behavior is undefined.
+** ^When pMem is not NULL, SQLite will strive to use the memory provided
+** to satisfy page cache needs, falling back to [sqlite3_malloc()] if
+** a page cache line is larger than sz bytes or if all of the pMem buffer
+** is exhausted.
+** ^If pMem is NULL and N is non-zero, then each database connection
+** does an initial bulk allocation for page cache memory
+** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or
+** of -1024*N bytes if N is negative, . ^If additional
+** page cache memory is needed beyond what is provided by the initial
+** allocation, then SQLite goes to [sqlite3_malloc()] separately for each
+** additional cache line. </dd>
**
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer
** that SQLite will use for all of its dynamic memory allocation needs
-** beyond those provided for by [SQLITE_CONFIG_PAGECACHE].
+** beyond those provided for by [SQLITE_CONFIG_PAGECACHE].
** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
** [SQLITE_ERROR] if invoked otherwise.
@@ -2349,20 +2349,20 @@ struct sqlite3_mem_methods {
** is enabled (using the [PRAGMA threads] command) and the amount of content
** to be sorted exceeds the page size times the minimum of the
** [PRAGMA cache_size] setting and this value.
-**
-** [[SQLITE_CONFIG_STMTJRNL_SPILL]]
-** <dt>SQLITE_CONFIG_STMTJRNL_SPILL
-** <dd>^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which
+**
+** [[SQLITE_CONFIG_STMTJRNL_SPILL]]
+** <dt>SQLITE_CONFIG_STMTJRNL_SPILL
+** <dd>^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which
** becomes the [statement journal] spill-to-disk threshold.
-** [Statement journals] are held in memory until their size (in bytes)
-** exceeds this threshold, at which point they are written to disk.
-** Or if the threshold is -1, statement journals are always held
-** exclusively in memory.
-** Since many statement journals never become large, setting the spill
-** threshold to a value such as 64KiB can greatly reduce the amount of
-** I/O required to support statement rollback.
-** The default value for this setting is controlled by the
-** [SQLITE_STMTJRNL_SPILL] compile-time option.
+** [Statement journals] are held in memory until their size (in bytes)
+** exceeds this threshold, at which point they are written to disk.
+** Or if the threshold is -1, statement journals are always held
+** exclusively in memory.
+** Since many statement journals never become large, setting the spill
+** threshold to a value such as 64KiB can greatly reduce the amount of
+** I/O required to support statement rollback.
+** The default value for this setting is controlled by the
+** [SQLITE_STMTJRNL_SPILL] compile-time option.
**
** [[SQLITE_CONFIG_SORTERREF_SIZE]]
** <dt>SQLITE_CONFIG_SORTERREF_SIZE
@@ -2397,7 +2397,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */
+#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */
#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */
#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */
#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
@@ -2417,8 +2417,8 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
-#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
-#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
+#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
+#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
@@ -2505,87 +2505,87 @@ struct sqlite3_mem_methods {
** databases.)^ </dd>
**
** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
-** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
+** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
** <dd> ^This option is used to enable or disable the
** [fts3_tokenizer()] function which is part of the
-** [FTS3] full-text search engine extension.
-** There should be two additional arguments.
-** The first argument is an integer which is 0 to disable fts3_tokenizer() or
-** positive to enable fts3_tokenizer() or negative to leave the setting
-** unchanged.
-** The second parameter is a pointer to an integer into which
-** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
-** following this call. The second parameter may be a NULL pointer, in
-** which case the new setting is not reported back. </dd>
-**
+** [FTS3] full-text search engine extension.
+** There should be two additional arguments.
+** The first argument is an integer which is 0 to disable fts3_tokenizer() or
+** positive to enable fts3_tokenizer() or negative to leave the setting
+** unchanged.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
+** following this call. The second parameter may be a NULL pointer, in
+** which case the new setting is not reported back. </dd>
+**
** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
-** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
-** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
-** interface independently of the [load_extension()] SQL function.
-** The [sqlite3_enable_load_extension()] API enables or disables both the
-** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
-** There should be two additional arguments.
-** When the first argument to this interface is 1, then only the C-API is
-** enabled and the SQL function remains disabled. If the first argument to
-** this interface is 0, then both the C-API and the SQL function are disabled.
-** If the first argument is -1, then no changes are made to state of either the
-** C-API or the SQL function.
-** The second parameter is a pointer to an integer into which
-** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
-** is disabled or enabled following this call. The second parameter may
-** be a NULL pointer, in which case the new setting is not reported back.
-** </dd>
-**
+** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
+** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
+** interface independently of the [load_extension()] SQL function.
+** The [sqlite3_enable_load_extension()] API enables or disables both the
+** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
+** There should be two additional arguments.
+** When the first argument to this interface is 1, then only the C-API is
+** enabled and the SQL function remains disabled. If the first argument to
+** this interface is 0, then both the C-API and the SQL function are disabled.
+** If the first argument is -1, then no changes are made to state of either the
+** C-API or the SQL function.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
+** is disabled or enabled following this call. The second parameter may
+** be a NULL pointer, in which case the new setting is not reported back.
+** </dd>
+**
** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
-** <dd> ^This option is used to change the name of the "main" database
-** schema. ^The sole argument is a pointer to a constant UTF8 string
-** which will become the new schema name in place of "main". ^SQLite
-** does not make a copy of the new main schema name string, so the application
-** must ensure that the argument passed into this DBCONFIG option is unchanged
-** until after the database connection closes.
-** </dd>
-**
+** <dd> ^This option is used to change the name of the "main" database
+** schema. ^The sole argument is a pointer to a constant UTF8 string
+** which will become the new schema name in place of "main". ^SQLite
+** does not make a copy of the new main schema name string, so the application
+** must ensure that the argument passed into this DBCONFIG option is unchanged
+** until after the database connection closes.
+** </dd>
+**
** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
-** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
+** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
** <dd> Usually, when a database in wal mode is closed or detached from a
** database handle, SQLite checks if this will mean that there are now no
** connections at all to the database. If so, it performs a checkpoint
-** operation before closing the connection. This option may be used to
-** override this behaviour. The first parameter passed to this operation
+** operation before closing the connection. This option may be used to
+** override this behaviour. The first parameter passed to this operation
** is an integer - positive to disable checkpoints-on-close, or zero (the
** default) to enable them, and negative to leave the setting unchanged.
** The second parameter is a pointer to an integer
-** into which is written 0 or 1 to indicate whether checkpoints-on-close
-** have been disabled - 0 if they are not disabled, 1 if they are.
-** </dd>
+** into which is written 0 or 1 to indicate whether checkpoints-on-close
+** have been disabled - 0 if they are not disabled, 1 if they are.
+** </dd>
**
** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
-** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
-** the [query planner stability guarantee] (QPSG). When the QPSG is active,
-** a single SQL query statement will always use the same algorithm regardless
-** of values of [bound parameters].)^ The QPSG disables some query optimizations
-** that look at the values of bound parameters, which can make some queries
-** slower. But the QPSG has the advantage of more predictable behavior. With
-** the QPSG active, SQLite will always use the same query plan in the field as
-** was used during testing in the lab.
+** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
+** the [query planner stability guarantee] (QPSG). When the QPSG is active,
+** a single SQL query statement will always use the same algorithm regardless
+** of values of [bound parameters].)^ The QPSG disables some query optimizations
+** that look at the values of bound parameters, which can make some queries
+** slower. But the QPSG has the advantage of more predictable behavior. With
+** the QPSG active, SQLite will always use the same query plan in the field as
+** was used during testing in the lab.
** The first argument to this setting is an integer which is 0 to disable
** the QPSG, positive to enable QPSG, or negative to leave the setting
** unchanged. The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
** following this call.
-** </dd>
+** </dd>
**
** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
-** include output for any operations performed by trigger programs. This
-** option is used to set or clear (the default) a flag that governs this
-** behavior. The first parameter passed to this operation is an integer -
+** include output for any operations performed by trigger programs. This
+** option is used to set or clear (the default) a flag that governs this
+** behavior. The first parameter passed to this operation is an integer -
** positive to enable output for trigger programs, or zero to disable it,
** or negative to leave the setting unchanged.
** The second parameter is a pointer to an integer into which is written
** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
** it is not disabled, 1 if it is.
-** </dd>
+** </dd>
**
** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
@@ -2703,15 +2703,15 @@ struct sqlite3_mem_methods {
** </dd>
** </dl>
*/
-#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
-#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
-#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
-#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
-#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
+#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
+#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
+#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
+#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
+#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
#define SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011 /* int int* */
@@ -2731,7 +2731,7 @@ struct sqlite3_mem_methods {
** [extended result codes] feature of SQLite. ^The extended result
** codes are disabled by default for historical compatibility.
*/
-SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
+SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
** CAPI3REF: Last Insert Rowid
@@ -2745,31 +2745,31 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
-** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
-** the most recent successful [INSERT] into a rowid table or [virtual table]
-** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
+** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
+** the most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred
** on the database connection D, then sqlite3_last_insert_rowid(D) returns
-** zero.
+** zero.
**
-** As well as being set automatically as rows are inserted into database
-** tables, the value returned by this function may be set explicitly by
-** [sqlite3_set_last_insert_rowid()]
+** As well as being set automatically as rows are inserted into database
+** tables, the value returned by this function may be set explicitly by
+** [sqlite3_set_last_insert_rowid()]
**
-** Some virtual table implementations may INSERT rows into rowid tables as
-** part of committing a transaction (e.g. to flush data accumulated in memory
-** to disk). In this case subsequent calls to this function return the rowid
+** Some virtual table implementations may INSERT rows into rowid tables as
+** part of committing a transaction (e.g. to flush data accumulated in memory
+** to disk). In this case subsequent calls to this function return the rowid
** associated with these internal INSERT operations, which leads to
-** unintuitive results. Virtual table implementations that do write to rowid
+** unintuitive results. Virtual table implementations that do write to rowid
** tables in this way can avoid this problem by restoring the original
** rowid value using [sqlite3_set_last_insert_rowid()] before returning
-** control to the user.
-**
+** control to the user.
+**
** ^(If an [INSERT] occurs within a trigger then this routine will
** return the [rowid] of the inserted row as long as the trigger is
** running. Once the trigger program ends, the value returned
-** by this routine reverts to what it was before the trigger was fired.)^
-**
+** by this routine reverts to what it was before the trigger was fired.)^
+**
** ^An [INSERT] that fails due to a constraint violation is not a
** successful [INSERT] and does not change the value returned by this
** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
@@ -2793,19 +2793,19 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
** unpredictable and might not equal either the old or the new
** last insert [rowid].
*/
-SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
+SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
/*
-** CAPI3REF: Set the Last Insert Rowid value.
-** METHOD: sqlite3
-**
-** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
+** CAPI3REF: Set the Last Insert Rowid value.
+** METHOD: sqlite3
+**
+** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
** set the value returned by calling sqlite3_last_insert_rowid(D) to R
-** without inserting a row into the database.
-*/
-SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
-
-/*
+** without inserting a row into the database.
+*/
+SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
+
+/*
** CAPI3REF: Count The Number Of Rows Modified
** METHOD: sqlite3
**
@@ -2864,7 +2864,7 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
** <li> the [data_version pragma]
** </ul>
*/
-SQLITE_API int sqlite3_changes(sqlite3*);
+SQLITE_API int sqlite3_changes(sqlite3*);
SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3*);
/*
@@ -2906,7 +2906,7 @@ SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3*);
** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
** </ul>
*/
-SQLITE_API int sqlite3_total_changes(sqlite3*);
+SQLITE_API int sqlite3_total_changes(sqlite3*);
SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*);
/*
@@ -2944,7 +2944,7 @@ SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*);
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite3_interrupt() call returns.
*/
-SQLITE_API void sqlite3_interrupt(sqlite3*);
+SQLITE_API void sqlite3_interrupt(sqlite3*);
/*
** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -2979,8 +2979,8 @@ SQLITE_API void sqlite3_interrupt(sqlite3*);
** The input to [sqlite3_complete16()] must be a zero-terminated
** UTF-16 string in native byte order.
*/
-SQLITE_API int sqlite3_complete(const char *sql);
-SQLITE_API int sqlite3_complete16(const void *sql);
+SQLITE_API int sqlite3_complete(const char *sql);
+SQLITE_API int sqlite3_complete16(const void *sql);
/*
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
@@ -3041,7 +3041,7 @@ SQLITE_API int sqlite3_complete16(const void *sql);
** A busy handler must not close the database connection
** or [prepared statement] that invoked the busy handler.
*/
-SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
+SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
/*
** CAPI3REF: Set A Busy Timeout
@@ -3064,7 +3064,7 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
**
** See also: [PRAGMA busy_timeout]
*/
-SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
+SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
/*
** CAPI3REF: Convenience Routines For Running Queries
@@ -3139,7 +3139,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
** reflected in subsequent calls to [sqlite3_errcode()] or
** [sqlite3_errmsg()].
*/
-SQLITE_API int sqlite3_get_table(
+SQLITE_API int sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
@@ -3147,7 +3147,7 @@ SQLITE_API int sqlite3_get_table(
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);
-SQLITE_API void sqlite3_free_table(char **result);
+SQLITE_API void sqlite3_free_table(char **result);
/*
** CAPI3REF: Formatted String Printing Functions
@@ -3189,10 +3189,10 @@ SQLITE_API void sqlite3_free_table(char **result);
**
** See also: [built-in printf()], [printf() SQL function]
*/
-SQLITE_API char *sqlite3_mprintf(const char*,...);
-SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
-SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
+SQLITE_API char *sqlite3_mprintf(const char*,...);
+SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
+SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
+SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
/*
** CAPI3REF: Memory Allocation Subsystem
@@ -3269,12 +3269,12 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
** a block of memory after it has been released using
** [sqlite3_free()] or [sqlite3_realloc()].
*/
-SQLITE_API void *sqlite3_malloc(int);
-SQLITE_API void *sqlite3_malloc64(sqlite3_uint64);
-SQLITE_API void *sqlite3_realloc(void*, int);
-SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64);
-SQLITE_API void sqlite3_free(void*);
-SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
+SQLITE_API void *sqlite3_malloc(int);
+SQLITE_API void *sqlite3_malloc64(sqlite3_uint64);
+SQLITE_API void *sqlite3_realloc(void*, int);
+SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64);
+SQLITE_API void sqlite3_free(void*);
+SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
/*
** CAPI3REF: Memory Allocator Statistics
@@ -3299,8 +3299,8 @@ SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
** by [sqlite3_memory_highwater(1)] is the high-water mark
** prior to the reset.
*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
+SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
+SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
/*
** CAPI3REF: Pseudo-Random Number Generator
@@ -3323,19 +3323,19 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
-SQLITE_API void sqlite3_randomness(int N, void *P);
+SQLITE_API void sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
** METHOD: sqlite3
-** KEYWORDS: {authorizer callback}
+** KEYWORDS: {authorizer callback}
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
** ^The authorizer callback is invoked as SQL statements are being compiled
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
-** [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()],
-** and [sqlite3_prepare16_v3()]. ^At various
+** [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()],
+** and [sqlite3_prepare16_v3()]. ^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
@@ -3357,10 +3357,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
** to the callback is an integer [SQLITE_COPY | action code] that specifies
** the particular action to be authorized. ^The third through sixth parameters
-** to the callback are either NULL pointers or zero-terminated strings
-** that contain additional details about the action to be authorized.
-** Applications must always be prepared to encounter a NULL pointer in any
-** of the third through the sixth parameters of the authorization callback.
+** to the callback are either NULL pointers or zero-terminated strings
+** that contain additional details about the action to be authorized.
+** Applications must always be prepared to encounter a NULL pointer in any
+** of the third through the sixth parameters of the authorization callback.
**
** ^If the action code is [SQLITE_READ]
** and the callback returns [SQLITE_IGNORE] then the
@@ -3369,10 +3369,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** 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.
-** ^When a table is referenced by a [SELECT] but no column values are
-** extracted from that table (for example in a query like
-** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
-** is invoked once for that table with a column name that is an empty string.
+** ^When a table is referenced by a [SELECT] but no column values are
+** extracted from that table (for example in a query like
+** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
+** is invoked once for that table with a column name that is an empty string.
** ^If the action code is [SQLITE_DELETE] and the callback returns
** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
** [truncate optimization] is disabled and all rows are deleted individually.
@@ -3414,7 +3414,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** as stated in the previous paragraph, sqlite3_step() invokes
** sqlite3_prepare_v2() to reprepare a statement after a schema change.
*/
-SQLITE_API int sqlite3_set_authorizer(
+SQLITE_API int sqlite3_set_authorizer(
sqlite3*,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pUserData
@@ -3494,9 +3494,9 @@ SQLITE_API int sqlite3_set_authorizer(
** CAPI3REF: Tracing And Profiling Functions
** METHOD: sqlite3
**
-** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
-** instead of the routines described here.
-**
+** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
+** instead of the routines described here.
+**
** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements.
**
@@ -3522,105 +3522,105 @@ SQLITE_API int sqlite3_set_authorizer(
** either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the
** profile callback.
*/
-SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
- void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
+SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
+ void(*xTrace)(void*,const char*), void*);
+SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
/*
-** CAPI3REF: SQL Trace Event Codes
-** KEYWORDS: SQLITE_TRACE
-**
-** These constants identify classes of events that can be monitored
-** using the [sqlite3_trace_v2()] tracing logic. The M argument
-** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
-** the following constants. ^The first argument to the trace callback
-** is one of the following constants.
-**
-** New tracing constants may be added in future releases.
-**
-** ^A trace callback has four arguments: xCallback(T,C,P,X).
-** ^The T argument is one of the integer type codes above.
-** ^The C argument is a copy of the context pointer passed in as the
-** fourth argument to [sqlite3_trace_v2()].
-** The P and X arguments are pointers whose meanings depend on T.
-**
-** <dl>
-** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt>
-** <dd>^An SQLITE_TRACE_STMT callback is invoked when a prepared statement
-** first begins running and possibly at other times during the
-** execution of the prepared statement, such as at the start of each
-** trigger subprogram. ^The P argument is a pointer to the
-** [prepared statement]. ^The X argument is a pointer to a string which
+** CAPI3REF: SQL Trace Event Codes
+** KEYWORDS: SQLITE_TRACE
+**
+** These constants identify classes of events that can be monitored
+** using the [sqlite3_trace_v2()] tracing logic. The M argument
+** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
+** the following constants. ^The first argument to the trace callback
+** is one of the following constants.
+**
+** New tracing constants may be added in future releases.
+**
+** ^A trace callback has four arguments: xCallback(T,C,P,X).
+** ^The T argument is one of the integer type codes above.
+** ^The C argument is a copy of the context pointer passed in as the
+** fourth argument to [sqlite3_trace_v2()].
+** The P and X arguments are pointers whose meanings depend on T.
+**
+** <dl>
+** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt>
+** <dd>^An SQLITE_TRACE_STMT callback is invoked when a prepared statement
+** first begins running and possibly at other times during the
+** execution of the prepared statement, such as at the start of each
+** trigger subprogram. ^The P argument is a pointer to the
+** [prepared statement]. ^The X argument is a pointer to a string which
** is the unexpanded SQL text of the prepared statement or an SQL comment
-** that indicates the invocation of a trigger. ^The callback can compute
-** the same text that would have been returned by the legacy [sqlite3_trace()]
-** interface by using the X argument when X begins with "--" and invoking
-** [sqlite3_expanded_sql(P)] otherwise.
-**
-** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt>
-** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
-** information as is provided by the [sqlite3_profile()] callback.
-** ^The P argument is a pointer to the [prepared statement] and the
-** X argument points to a 64-bit integer which is the estimated of
-** the number of nanosecond that the prepared statement took to run.
-** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
-**
-** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
-** <dd>^An SQLITE_TRACE_ROW callback is invoked whenever a prepared
+** that indicates the invocation of a trigger. ^The callback can compute
+** the same text that would have been returned by the legacy [sqlite3_trace()]
+** interface by using the X argument when X begins with "--" and invoking
+** [sqlite3_expanded_sql(P)] otherwise.
+**
+** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt>
+** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
+** information as is provided by the [sqlite3_profile()] callback.
+** ^The P argument is a pointer to the [prepared statement] and the
+** X argument points to a 64-bit integer which is the estimated of
+** the number of nanosecond that the prepared statement took to run.
+** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
+**
+** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
+** <dd>^An SQLITE_TRACE_ROW callback is invoked whenever a prepared
** statement generates a single row of result.
-** ^The P argument is a pointer to the [prepared statement] and the
-** X argument is unused.
-**
-** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt>
-** <dd>^An SQLITE_TRACE_CLOSE callback is invoked when a database
-** connection closes.
-** ^The P argument is a pointer to the [database connection] object
-** and the X argument is unused.
-** </dl>
-*/
-#define SQLITE_TRACE_STMT 0x01
-#define SQLITE_TRACE_PROFILE 0x02
-#define SQLITE_TRACE_ROW 0x04
-#define SQLITE_TRACE_CLOSE 0x08
-
-/*
-** CAPI3REF: SQL Trace Hook
-** METHOD: sqlite3
-**
-** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback
-** function X against [database connection] D, using property mask M
-** and context pointer P. ^If the X callback is
-** NULL or if the M mask is zero, then tracing is disabled. The
-** M argument should be the bitwise OR-ed combination of
-** zero or more [SQLITE_TRACE] constants.
-**
+** ^The P argument is a pointer to the [prepared statement] and the
+** X argument is unused.
+**
+** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt>
+** <dd>^An SQLITE_TRACE_CLOSE callback is invoked when a database
+** connection closes.
+** ^The P argument is a pointer to the [database connection] object
+** and the X argument is unused.
+** </dl>
+*/
+#define SQLITE_TRACE_STMT 0x01
+#define SQLITE_TRACE_PROFILE 0x02
+#define SQLITE_TRACE_ROW 0x04
+#define SQLITE_TRACE_CLOSE 0x08
+
+/*
+** CAPI3REF: SQL Trace Hook
+** METHOD: sqlite3
+**
+** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback
+** function X against [database connection] D, using property mask M
+** and context pointer P. ^If the X callback is
+** NULL or if the M mask is zero, then tracing is disabled. The
+** M argument should be the bitwise OR-ed combination of
+** zero or more [SQLITE_TRACE] constants.
+**
** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides
-** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().
-**
+** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().
+**
** ^The X callback is invoked whenever any of the events identified by
-** mask M occur. ^The integer return value from the callback is currently
-** ignored, though this may change in future releases. Callback
-** implementations should return zero to ensure future compatibility.
-**
-** ^A trace callback is invoked with four arguments: callback(T,C,P,X).
-** ^The T argument is one of the [SQLITE_TRACE]
-** constants to indicate why the callback was invoked.
-** ^The C argument is a copy of the context pointer.
-** The P and X arguments are pointers whose meanings depend on T.
-**
-** The sqlite3_trace_v2() interface is intended to replace the legacy
-** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
-** are deprecated.
-*/
-SQLITE_API int sqlite3_trace_v2(
- sqlite3*,
- unsigned uMask,
- int(*xCallback)(unsigned,void*,void*,void*),
- void *pCtx
-);
-
-/*
+** mask M occur. ^The integer return value from the callback is currently
+** ignored, though this may change in future releases. Callback
+** implementations should return zero to ensure future compatibility.
+**
+** ^A trace callback is invoked with four arguments: callback(T,C,P,X).
+** ^The T argument is one of the [SQLITE_TRACE]
+** constants to indicate why the callback was invoked.
+** ^The C argument is a copy of the context pointer.
+** The P and X arguments are pointers whose meanings depend on T.
+**
+** The sqlite3_trace_v2() interface is intended to replace the legacy
+** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
+** are deprecated.
+*/
+SQLITE_API int sqlite3_trace_v2(
+ sqlite3*,
+ unsigned uMask,
+ int(*xCallback)(unsigned,void*,void*,void*),
+ void *pCtx
+);
+
+/*
** CAPI3REF: Query Progress Callbacks
** METHOD: sqlite3
**
@@ -3652,7 +3652,7 @@ SQLITE_API int sqlite3_trace_v2(
** database connections for the meaning of "modify" in this paragraph.
**
*/
-SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
/*
** CAPI3REF: Opening A New Database Connection
@@ -3784,10 +3784,10 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** ^If [URI filename] interpretation is enabled, and the filename argument
** begins with "file:", then the filename is interpreted as a URI. ^URI
** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
-** set in the third argument to sqlite3_open_v2(), or if it has
+** set in the third argument to sqlite3_open_v2(), or if it has
** been enabled globally using the [SQLITE_CONFIG_URI] option with the
** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
-** URI filename interpretation is turned off
+** URI filename interpretation is turned off
** by default, but future releases of SQLite might enable URI filename
** interpretation by default. See "[URI filenames]" for additional
** information.
@@ -3924,15 +3924,15 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
**
** See also: [sqlite3_temp_directory]
*/
-SQLITE_API int sqlite3_open(
+SQLITE_API int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int sqlite3_open16(
+SQLITE_API int sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int sqlite3_open_v2(
+SQLITE_API int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
@@ -4005,9 +4005,9 @@ SQLITE_API int sqlite3_open_v2(
**
** See the [URI filename] documentation for additional information.
*/
-SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
-SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
-SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
+SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
+SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N);
/*
@@ -4166,11 +4166,11 @@ SQLITE_API void sqlite3_free_filename(char*);
** was invoked incorrectly by the application. In that case, the
** error code and message may or may not be set.
*/
-SQLITE_API int sqlite3_errcode(sqlite3 *db);
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
-SQLITE_API const char *sqlite3_errstr(int);
+SQLITE_API int sqlite3_errcode(sqlite3 *db);
+SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
+SQLITE_API const char *sqlite3_errmsg(sqlite3*);
+SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *sqlite3_errstr(int);
/*
** CAPI3REF: Prepared Statement Object
@@ -4238,7 +4238,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
**
** New run-time limit categories may be added in future releases.
*/
-SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
+SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
/*
** CAPI3REF: Run-Time Limit Categories
@@ -4269,9 +4269,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
**
** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
** <dd>The maximum number of instructions in a virtual machine program
-** used to implement an SQL statement. If [sqlite3_prepare_v2()] or
-** the equivalent tries to allocate space for more than this many opcodes
-** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
+** used to implement an SQL statement. If [sqlite3_prepare_v2()] or
+** the equivalent tries to allocate space for more than this many opcodes
+** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
**
** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
** <dd>The maximum number of arguments on a function.</dd>)^
@@ -4310,25 +4310,25 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
#define SQLITE_LIMIT_WORKER_THREADS 11
/*
-** CAPI3REF: Prepare Flags
-**
-** These constants define various flags that can be passed into
-** "prepFlags" parameter of the [sqlite3_prepare_v3()] and
-** [sqlite3_prepare16_v3()] interfaces.
-**
-** New flags may be added in future releases of SQLite.
-**
-** <dl>
-** [[SQLITE_PREPARE_PERSISTENT]] ^(<dt>SQLITE_PREPARE_PERSISTENT</dt>
-** <dd>The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner
-** that the prepared statement will be retained for a long time and
-** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()]
+** CAPI3REF: Prepare Flags
+**
+** These constants define various flags that can be passed into
+** "prepFlags" parameter of the [sqlite3_prepare_v3()] and
+** [sqlite3_prepare16_v3()] interfaces.
+**
+** New flags may be added in future releases of SQLite.
+**
+** <dl>
+** [[SQLITE_PREPARE_PERSISTENT]] ^(<dt>SQLITE_PREPARE_PERSISTENT</dt>
+** <dd>The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner
+** that the prepared statement will be retained for a long time and
+** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()]
** and [sqlite3_prepare16_v3()] assume that the prepared statement will
-** be used just once or at most a few times and then destroyed using
-** [sqlite3_finalize()] relatively soon. The current implementation acts
-** on this hint by avoiding the use of [lookaside memory] so as not to
-** deplete the limited store of lookaside memory. Future versions of
-** SQLite may act on this hint differently.
+** be used just once or at most a few times and then destroyed using
+** [sqlite3_finalize()] relatively soon. The current implementation acts
+** on this hint by avoiding the use of [lookaside memory] so as not to
+** deplete the limited store of lookaside memory. Future versions of
+** SQLite may act on this hint differently.
**
** [[SQLITE_PREPARE_NORMALIZE]] <dt>SQLITE_PREPARE_NORMALIZE</dt>
** <dd>The SQLITE_PREPARE_NORMALIZE flag is a no-op. This flag used
@@ -4342,41 +4342,41 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
** to return an error (error code SQLITE_ERROR) if the statement uses
** any virtual tables.
-** </dl>
-*/
-#define SQLITE_PREPARE_PERSISTENT 0x01
+** </dl>
+*/
+#define SQLITE_PREPARE_PERSISTENT 0x01
#define SQLITE_PREPARE_NORMALIZE 0x02
#define SQLITE_PREPARE_NO_VTAB 0x04
-
-/*
+
+/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
** METHOD: sqlite3
** CONSTRUCTOR: sqlite3_stmt
**
-** To execute an SQL statement, it must first be compiled into a byte-code
-** program using one of these routines. Or, in other words, these routines
-** are constructors for the [prepared statement] object.
-**
-** The preferred routine to use is [sqlite3_prepare_v2()]. The
-** [sqlite3_prepare()] interface is legacy and should be avoided.
-** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used
-** for special purposes.
-**
-** The use of the UTF-8 interfaces is preferred, as SQLite currently
-** does all parsing using UTF-8. The UTF-16 interfaces are provided
-** as a convenience. The UTF-16 interfaces work by converting the
-** input text into UTF-8, then invoking the corresponding UTF-8 interface.
-**
+** To execute an SQL statement, it must first be compiled into a byte-code
+** program using one of these routines. Or, in other words, these routines
+** are constructors for the [prepared statement] object.
+**
+** The preferred routine to use is [sqlite3_prepare_v2()]. The
+** [sqlite3_prepare()] interface is legacy and should be avoided.
+** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used
+** for special purposes.
+**
+** The use of the UTF-8 interfaces is preferred, as SQLite currently
+** does all parsing using UTF-8. The UTF-16 interfaces are provided
+** as a convenience. The UTF-16 interfaces work by converting the
+** input text into UTF-8, then invoking the corresponding UTF-8 interface.
+**
** The first argument, "db", is a [database connection] obtained from a
** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
** [sqlite3_open16()]. The database connection must not have been closed.
**
** The second argument, "zSql", is the statement to be compiled, encoded
-** as either UTF-8 or UTF-16. The sqlite3_prepare(), sqlite3_prepare_v2(),
-** and sqlite3_prepare_v3()
-** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(),
-** and sqlite3_prepare16_v3() use UTF-16.
+** as either UTF-8 or UTF-16. The sqlite3_prepare(), sqlite3_prepare_v2(),
+** and sqlite3_prepare_v3()
+** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(),
+** and sqlite3_prepare16_v3() use UTF-16.
**
** ^If the nByte argument is negative, then zSql is read up to the
** first zero terminator. ^If nByte is positive, then it is the
@@ -4403,11 +4403,11 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK];
** otherwise an [error code] is returned.
**
-** The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(),
-** and sqlite3_prepare16_v3() interfaces are recommended for all new programs.
-** The older interfaces (sqlite3_prepare() and sqlite3_prepare16())
-** are retained for backwards compatibility, but their use is discouraged.
-** ^In the "vX" interfaces, the prepared statement
+** The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(),
+** and sqlite3_prepare16_v3() interfaces are recommended for all new programs.
+** The older interfaces (sqlite3_prepare() and sqlite3_prepare16())
+** are retained for backwards compatibility, but their use is discouraged.
+** ^In the "vX" interfaces, the prepared statement
** that is returned (the [sqlite3_stmt] object) contains a copy of the
** original SQL text. This causes the [sqlite3_step()] interface to
** behave differently in three ways:
@@ -4441,101 +4441,101 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled.
** </li>
** </ol>
-**
-** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
-** the extra prepFlags parameter, which is a bit array consisting of zero or
-** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The
-** sqlite3_prepare_v2() interface works exactly the same as
-** sqlite3_prepare_v3() with a zero prepFlags parameter.
-*/
-SQLITE_API int sqlite3_prepare(
+**
+** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
+** the extra prepFlags parameter, which is a bit array consisting of zero or
+** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The
+** sqlite3_prepare_v2() interface works exactly the same as
+** sqlite3_prepare_v3() with a zero prepFlags parameter.
+*/
+SQLITE_API int sqlite3_prepare(
+ sqlite3 *db, /* Database handle */
+ const char *zSql, /* SQL statement, UTF-8 encoded */
+ int nByte, /* Maximum length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: Statement handle */
+ const char **pzTail /* OUT: Pointer to unused portion of zSql */
+);
+SQLITE_API int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int sqlite3_prepare_v2(
+SQLITE_API int sqlite3_prepare_v3(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
+ unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int sqlite3_prepare_v3(
+SQLITE_API int sqlite3_prepare16(
sqlite3 *db, /* Database handle */
- const char *zSql, /* SQL statement, UTF-8 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const char **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare16(
- sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const void **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int sqlite3_prepare16_v2(
+SQLITE_API int sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const void **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int sqlite3_prepare16_v3(
- sqlite3 *db, /* Database handle */
- const void *zSql, /* SQL statement, UTF-16 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const void **pzTail /* OUT: Pointer to unused portion of zSql */
-);
+SQLITE_API int sqlite3_prepare16_v3(
+ sqlite3 *db, /* Database handle */
+ const void *zSql, /* SQL statement, UTF-16 encoded */
+ int nByte, /* Maximum length of zSql in bytes. */
+ unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
+ sqlite3_stmt **ppStmt, /* OUT: Statement handle */
+ const void **pzTail /* OUT: Pointer to unused portion of zSql */
+);
/*
** CAPI3REF: Retrieving Statement SQL
** METHOD: sqlite3_stmt
**
-** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8
-** SQL text used to create [prepared statement] P if P was
-** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
-** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
-** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
-** string containing the SQL text of prepared statement P with
-** [bound parameters] expanded.
+** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8
+** SQL text used to create [prepared statement] P if P was
+** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
+** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
+** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
+** string containing the SQL text of prepared statement P with
+** [bound parameters] expanded.
** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
** string containing the normalized SQL text of prepared statement P. The
** semantics used to normalize a SQL statement are unspecified and subject
** to change. At a minimum, literal values will be replaced with suitable
** placeholders.
-**
-** ^(For example, if a prepared statement is created using the SQL
-** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
-** and parameter :xyz is unbound, then sqlite3_sql() will return
-** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
-** will return "SELECT 2345,NULL".)^
-**
-** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory
-** is available to hold the result, or if the result would exceed the
-** the maximum string length determined by the [SQLITE_LIMIT_LENGTH].
-**
-** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
-** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
-** option causes sqlite3_expanded_sql() to always return NULL.
-**
+**
+** ^(For example, if a prepared statement is created using the SQL
+** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
+** and parameter :xyz is unbound, then sqlite3_sql() will return
+** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
+** will return "SELECT 2345,NULL".)^
+**
+** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory
+** is available to hold the result, or if the result would exceed the
+** the maximum string length determined by the [SQLITE_LIMIT_LENGTH].
+**
+** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
+** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
+** option causes sqlite3_expanded_sql() to always return NULL.
+**
** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
** are managed by SQLite and are automatically freed when the prepared
** statement is finalized.
-** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
+** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
** is obtained from [sqlite3_malloc()] and must be freed by the application
-** by passing it to [sqlite3_free()].
+** by passing it to [sqlite3_free()].
**
** ^The sqlite3_normalized_sql() interface is only available if
** the [SQLITE_ENABLE_NORMALIZE] compile-time option is defined.
*/
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
-SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
+SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
+SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
#ifdef SQLITE_ENABLE_NORMALIZE
SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
#endif
@@ -4569,10 +4569,10 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
** sqlite3_stmt_readonly() to return true since, while those statements
** change the configuration of a database connection, they do not make
** changes to the content of the database files on disk.
-** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since
-** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
-** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
-** sqlite3_stmt_readonly() returns false for those commands.
+** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since
+** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
+** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
+** sqlite3_stmt_readonly() returns false for those commands.
**
** ^This routine returns false if there is any possibility that the
** statement might change the database file. ^A false return does
@@ -4583,7 +4583,7 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
** read-only no-op if the table already exists, but
** sqlite3_stmt_readonly() still returns false for such a statement.
*/
-SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4603,8 +4603,8 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
**
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
** [prepared statement] S has been stepped at least once using
-** [sqlite3_step(S)] but has neither run to completion (returned
-** [SQLITE_DONE] from [sqlite3_step(S)]) nor
+** [sqlite3_step(S)] but has neither run to completion (returned
+** [SQLITE_DONE] from [sqlite3_step(S)]) nor
** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S)
** interface returns false if S is a NULL pointer. If S is not a
** NULL pointer and is not a pointer to a valid [prepared statement]
@@ -4616,7 +4616,7 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
** for example, in diagnostic routines to search for prepared
** statements that are holding a transaction open.
*/
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
+SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
/*
** CAPI3REF: Dynamically Typed Value Object
@@ -4652,13 +4652,13 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
** 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 as arguments
-** to [sqlite3_result_value()], [sqlite3_bind_value()], and
-** [sqlite3_value_dup()].
+** Unprotected sqlite3_value objects may only be used as arguments
+** to [sqlite3_result_value()], [sqlite3_bind_value()], and
+** [sqlite3_value_dup()].
** The [sqlite3_value_blob | sqlite3_value_type()] family of
** interfaces require protected sqlite3_value objects.
*/
-typedef struct sqlite3_value sqlite3_value;
+typedef struct sqlite3_value sqlite3_value;
/*
** CAPI3REF: SQL Function Context Object
@@ -4784,15 +4784,15 @@ typedef struct sqlite3_context sqlite3_context;
** [sqlite3_blob_open | incremental BLOB I/O] routines.
** ^A negative value for the zeroblob results in a zero-length BLOB.
**
-** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
-** [prepared statement] S to have an SQL value of NULL, but to also be
-** associated with the pointer P of type T. ^D is either a NULL pointer or
-** a pointer to a destructor function for P. ^SQLite will invoke the
-** destructor D with a single argument of P when it is finished using
-** P. The T parameter should be a static string, preferably a string
-** literal. The sqlite3_bind_pointer() routine is part of the
-** [pointer passing interface] added for SQLite 3.20.0.
-**
+** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
+** [prepared statement] S to have an SQL value of NULL, but to also be
+** associated with the pointer P of type T. ^D is either a NULL pointer or
+** a pointer to a destructor function for P. ^SQLite will invoke the
+** destructor D with a single argument of P when it is finished using
+** P. The T parameter should be a static string, preferably a string
+** literal. The sqlite3_bind_pointer() routine is part of the
+** [pointer passing interface] added for SQLite 3.20.0.
+**
** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
** for the [prepared statement] or with a prepared statement for which
** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
@@ -4814,21 +4814,21 @@ typedef struct sqlite3_context sqlite3_context;
** See also: [sqlite3_bind_parameter_count()],
** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
void(*)(void*));
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
-SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
+SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
+SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
+SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
void(*)(void*), unsigned char encoding);
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
-SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
+SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
+SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
+SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
/*
** CAPI3REF: Number Of SQL Parameters
@@ -4849,7 +4849,7 @@ SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
** [sqlite3_bind_parameter_name()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
+SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
** CAPI3REF: Name Of A Host Parameter
@@ -4870,14 +4870,14 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
** ^If the value N is out of range or if the N-th parameter is
** nameless, then NULL is returned. ^The returned string is
** always in UTF-8 encoding even if the named parameter was
-** originally specified as UTF-16 in [sqlite3_prepare16()],
-** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
+** originally specified as UTF-16 in [sqlite3_prepare16()],
+** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
/*
** CAPI3REF: Index Of A Parameter With A Given Name
@@ -4888,14 +4888,14 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero
** is returned if no matching parameter is found. ^The parameter
** name must be given in UTF-8 even if the original statement
-** was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or
-** [sqlite3_prepare16_v3()].
+** was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or
+** [sqlite3_prepare16_v3()].
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_name()].
+** [sqlite3_bind_parameter_name()].
*/
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
/*
** CAPI3REF: Reset All Bindings On A Prepared Statement
@@ -4905,7 +4905,7 @@ SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
** the [sqlite3_bind_blob | bindings] on a [prepared statement].
** ^Use this routine to reset all host parameters to NULL.
*/
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
+SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
/*
** CAPI3REF: Number Of Columns In A Result Set
@@ -4913,15 +4913,15 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
**
** ^Return the number of columns in the result set returned by the
** [prepared statement]. ^If this routine returns 0, that means the
-** [prepared statement] returns no data (for example an [UPDATE]).
-** ^However, just because this routine returns a positive number does not
-** mean that one or more rows of data will be returned. ^A SELECT statement
-** will always have a positive sqlite3_column_count() but depending on the
-** WHERE clause constraints and the table content, it might return no rows.
+** [prepared statement] returns no data (for example an [UPDATE]).
+** ^However, just because this routine returns a positive number does not
+** mean that one or more rows of data will be returned. ^A SELECT statement
+** will always have a positive sqlite3_column_count() but depending on the
+** WHERE clause constraints and the table content, it might return no rows.
**
** See also: [sqlite3_data_count()]
*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Column Names In A Result Set
@@ -4950,8 +4950,8 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
** then the name of the column is unspecified and may change from
** one release of SQLite to the next.
*/
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
+SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
+SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
/*
** CAPI3REF: Source Of Data In A Query Result
@@ -4995,12 +4995,12 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
** for the same [prepared statement] and result column
** at the same time then the results are undefined.
*/
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
/*
** CAPI3REF: Declared Datatype Of A Query Result
@@ -5032,25 +5032,25 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
** is associated with individual values, not with the containers
** used to hold those values.
*/
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
/*
** CAPI3REF: Evaluate An SQL Statement
** METHOD: sqlite3_stmt
**
-** After a [prepared statement] has been prepared using any of
-** [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()],
-** or [sqlite3_prepare16_v3()] or one of the legacy
+** After a [prepared statement] has been prepared using any of
+** [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()],
+** or [sqlite3_prepare16_v3()] or one of the legacy
** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
** must be called one or more times to evaluate the statement.
**
** The details of the behavior of the sqlite3_step() interface depend
-** on whether the statement was prepared using the newer "vX" interfaces
-** [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()],
-** [sqlite3_prepare16_v2()] or the older legacy
-** interfaces [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the
-** new "vX" interface is recommended for new applications but the legacy
+** on whether the statement was prepared using the newer "vX" interfaces
+** [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()],
+** [sqlite3_prepare16_v2()] or the older legacy
+** interfaces [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the
+** new "vX" interface is recommended for new applications but the legacy
** interface will continue to be supported.
**
** ^In the legacy interface, the return value will be either [SQLITE_BUSY],
@@ -5096,8 +5096,8 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step(). Failure to reset the prepared statement using
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
-** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
-** sqlite3_step() began
+** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
+** sqlite3_step() began
** calling [sqlite3_reset()] automatically in this circumstance rather
** than returning [SQLITE_MISUSE]. This is not considered a compatibility
** break because any application that ever receives an SQLITE_MISUSE error
@@ -5111,13 +5111,13 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** specific [error codes] that better describes the error.
** We admit that this is a goofy design. The problem has been fixed
** with the "v2" interface. If you prepare all of your SQL statements
-** using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()]
-** or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead
+** using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()]
+** or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead
** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
** then the more specific [error codes] are returned directly
-** by sqlite3_step(). The use of the "vX" interfaces is recommended.
+** by sqlite3_step(). The use of the "vX" interfaces is recommended.
*/
-SQLITE_API int sqlite3_step(sqlite3_stmt*);
+SQLITE_API int sqlite3_step(sqlite3_stmt*);
/*
** CAPI3REF: Number of columns in a result set
@@ -5138,7 +5138,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt*);
**
** See also: [sqlite3_column_count()]
*/
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Fundamental Datatypes
@@ -5177,28 +5177,28 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** KEYWORDS: {column access functions}
** METHOD: sqlite3_stmt
**
-** <b>Summary:</b>
-** <blockquote><table border=0 cellpadding=0 cellspacing=0>
-** <tr><td><b>sqlite3_column_blob</b><td>&rarr;<td>BLOB result
-** <tr><td><b>sqlite3_column_double</b><td>&rarr;<td>REAL result
-** <tr><td><b>sqlite3_column_int</b><td>&rarr;<td>32-bit INTEGER result
-** <tr><td><b>sqlite3_column_int64</b><td>&rarr;<td>64-bit INTEGER result
-** <tr><td><b>sqlite3_column_text</b><td>&rarr;<td>UTF-8 TEXT result
-** <tr><td><b>sqlite3_column_text16</b><td>&rarr;<td>UTF-16 TEXT result
+** <b>Summary:</b>
+** <blockquote><table border=0 cellpadding=0 cellspacing=0>
+** <tr><td><b>sqlite3_column_blob</b><td>&rarr;<td>BLOB result
+** <tr><td><b>sqlite3_column_double</b><td>&rarr;<td>REAL result
+** <tr><td><b>sqlite3_column_int</b><td>&rarr;<td>32-bit INTEGER result
+** <tr><td><b>sqlite3_column_int64</b><td>&rarr;<td>64-bit INTEGER result
+** <tr><td><b>sqlite3_column_text</b><td>&rarr;<td>UTF-8 TEXT result
+** <tr><td><b>sqlite3_column_text16</b><td>&rarr;<td>UTF-16 TEXT result
** <tr><td><b>sqlite3_column_value</b><td>&rarr;<td>The result as an
-** [sqlite3_value|unprotected sqlite3_value] object.
-** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
-** <tr><td><b>sqlite3_column_bytes</b><td>&rarr;<td>Size of a BLOB
-** or a UTF-8 TEXT result in bytes
-** <tr><td><b>sqlite3_column_bytes16&nbsp;&nbsp;</b>
-** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
-** TEXT in bytes
-** <tr><td><b>sqlite3_column_type</b><td>&rarr;<td>Default
-** datatype of the result
-** </table></blockquote>
-**
-** <b>Details:</b>
-**
+** [sqlite3_value|unprotected sqlite3_value] object.
+** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
+** <tr><td><b>sqlite3_column_bytes</b><td>&rarr;<td>Size of a BLOB
+** or a UTF-8 TEXT result in bytes
+** <tr><td><b>sqlite3_column_bytes16&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
+** TEXT in bytes
+** <tr><td><b>sqlite3_column_type</b><td>&rarr;<td>Default
+** datatype of the result
+** </table></blockquote>
+**
+** <b>Details:</b>
+**
** ^These routines return information about a single column of the current
** result row of a query. ^In every case the first argument is a pointer
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
@@ -5220,29 +5220,29 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** are called from a different thread while any of these routines
** are pending, then the results are undefined.
**
-** The first six interfaces (_blob, _double, _int, _int64, _text, and _text16)
-** each return the value of a result column in a specific data format. If
-** the result column is not initially in the requested format (for example,
-** if the query returns an integer but the sqlite3_column_text() interface
-** is used to extract the value) then an automatic type conversion is performed.
-**
+** The first six interfaces (_blob, _double, _int, _int64, _text, and _text16)
+** each return the value of a result column in a specific data format. If
+** the result column is not initially in the requested format (for example,
+** if the query returns an integer but the sqlite3_column_text() interface
+** is used to extract the value) then an automatic type conversion is performed.
+**
** ^The sqlite3_column_type() routine returns the
** [SQLITE_INTEGER | datatype code] for the initial data type
** of the result column. ^The returned value is one of [SQLITE_INTEGER],
-** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].
-** The return value of sqlite3_column_type() can be used to decide which
-** of the first six interface should be used to extract the column value.
-** The value returned by sqlite3_column_type() is only meaningful if no
+** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].
+** The return value of sqlite3_column_type() can be used to decide which
+** of the first six interface should be used to extract the column value.
+** The value returned by sqlite3_column_type() is only meaningful if no
** automatic type conversions have occurred for the value in question.
-** After a type conversion, the result of calling sqlite3_column_type()
-** is undefined, though harmless. Future
+** After a type conversion, the result of calling sqlite3_column_type()
+** is undefined, though harmless. Future
** versions of SQLite may change the behavior of sqlite3_column_type()
** following a type conversion.
**
-** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes()
-** or sqlite3_column_bytes16() interfaces can be used to determine the size
-** of that BLOB or string.
-**
+** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes()
+** or sqlite3_column_bytes16() interfaces can be used to determine the size
+** of that BLOB or string.
+**
** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
** routine returns the number of bytes in that BLOB or string.
** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts
@@ -5279,13 +5279,13 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** [sqlite3_column_value()] is used in any other way, including calls
** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
** or [sqlite3_value_bytes()], the behavior is not threadsafe.
-** Hence, the sqlite3_column_value() interface
+** Hence, the sqlite3_column_value() interface
** is normally only useful within the implementation of
-** [application-defined SQL functions] or [virtual tables], not within
-** top-level application code.
+** [application-defined SQL functions] or [virtual tables], not within
+** top-level application code.
**
-** The these routines may attempt to convert the datatype of the result.
-** ^For example, if the internal representation is FLOAT and a text result
+** The these routines may attempt to convert the datatype of the result.
+** ^For example, if the internal representation is FLOAT and a text result
** is requested, [sqlite3_snprintf()] is used internally to perform the
** conversion automatically. ^(The following table details the conversions
** that are applied:
@@ -5357,7 +5357,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** ^The pointers returned are valid until a type conversion occurs as
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
** [sqlite3_finalize()] is called. ^The memory space used to hold strings
-** and BLOBs is freed automatically. Do not pass the pointers returned
+** and BLOBs is freed automatically. Do not pass the pointers returned
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
** [sqlite3_free()].
**
@@ -5381,16 +5381,16 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** return value is obtained and before any
** other SQLite interface is called on the same [database connection].
*/
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
+SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
/*
** CAPI3REF: Destroy A Prepared Statement Object
@@ -5418,7 +5418,7 @@ SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
** statement after it has been finalized can result in undefined and
** undesirable behavior such as segfaults and heap corruption.
*/
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Reset A Prepared Statement Object
@@ -5445,7 +5445,7 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
** ^The [sqlite3_reset(S)] interface does not change the values
** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Create Or Redefine SQL Functions
@@ -5570,7 +5570,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** close the database connection nor finalize or reset the prepared
** statement in which the function is running.
*/
-SQLITE_API int sqlite3_create_function(
+SQLITE_API int sqlite3_create_function(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -5580,7 +5580,7 @@ SQLITE_API int sqlite3_create_function(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int sqlite3_create_function16(
+SQLITE_API int sqlite3_create_function16(
sqlite3 *db,
const void *zFunctionName,
int nArg,
@@ -5590,7 +5590,7 @@ SQLITE_API int sqlite3_create_function16(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int sqlite3_create_function_v2(
+SQLITE_API int sqlite3_create_function_v2(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -5708,12 +5708,12 @@ SQLITE_API int sqlite3_create_window_function(
** these functions, we will not explain what they do.
*/
#ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
-SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
+SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
void*,sqlite3_int64);
#endif
@@ -5721,45 +5721,45 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** CAPI3REF: Obtaining SQL Values
** METHOD: sqlite3_value
**
-** <b>Summary:</b>
-** <blockquote><table border=0 cellpadding=0 cellspacing=0>
-** <tr><td><b>sqlite3_value_blob</b><td>&rarr;<td>BLOB value
-** <tr><td><b>sqlite3_value_double</b><td>&rarr;<td>REAL value
-** <tr><td><b>sqlite3_value_int</b><td>&rarr;<td>32-bit INTEGER value
-** <tr><td><b>sqlite3_value_int64</b><td>&rarr;<td>64-bit INTEGER value
-** <tr><td><b>sqlite3_value_pointer</b><td>&rarr;<td>Pointer value
-** <tr><td><b>sqlite3_value_text</b><td>&rarr;<td>UTF-8 TEXT value
-** <tr><td><b>sqlite3_value_text16</b><td>&rarr;<td>UTF-16 TEXT value in
-** the native byteorder
-** <tr><td><b>sqlite3_value_text16be</b><td>&rarr;<td>UTF-16be TEXT value
-** <tr><td><b>sqlite3_value_text16le</b><td>&rarr;<td>UTF-16le TEXT value
-** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
-** <tr><td><b>sqlite3_value_bytes</b><td>&rarr;<td>Size of a BLOB
-** or a UTF-8 TEXT in bytes
-** <tr><td><b>sqlite3_value_bytes16&nbsp;&nbsp;</b>
-** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
-** TEXT in bytes
-** <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
-** datatype of the value
-** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
-** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
-** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
-** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
-** against a virtual table.
+** <b>Summary:</b>
+** <blockquote><table border=0 cellpadding=0 cellspacing=0>
+** <tr><td><b>sqlite3_value_blob</b><td>&rarr;<td>BLOB value
+** <tr><td><b>sqlite3_value_double</b><td>&rarr;<td>REAL value
+** <tr><td><b>sqlite3_value_int</b><td>&rarr;<td>32-bit INTEGER value
+** <tr><td><b>sqlite3_value_int64</b><td>&rarr;<td>64-bit INTEGER value
+** <tr><td><b>sqlite3_value_pointer</b><td>&rarr;<td>Pointer value
+** <tr><td><b>sqlite3_value_text</b><td>&rarr;<td>UTF-8 TEXT value
+** <tr><td><b>sqlite3_value_text16</b><td>&rarr;<td>UTF-16 TEXT value in
+** the native byteorder
+** <tr><td><b>sqlite3_value_text16be</b><td>&rarr;<td>UTF-16be TEXT value
+** <tr><td><b>sqlite3_value_text16le</b><td>&rarr;<td>UTF-16le TEXT value
+** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
+** <tr><td><b>sqlite3_value_bytes</b><td>&rarr;<td>Size of a BLOB
+** or a UTF-8 TEXT in bytes
+** <tr><td><b>sqlite3_value_bytes16&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
+** TEXT in bytes
+** <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
+** datatype of the value
+** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
+** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
+** against a virtual table.
** <tr><td><b>sqlite3_value_frombind&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>True if value originated from a [bound parameter]
-** </table></blockquote>
+** </table></blockquote>
**
-** <b>Details:</b>
+** <b>Details:</b>
**
-** These routines extract type, size, and content information from
-** [protected sqlite3_value] objects. Protected sqlite3_value objects
+** These routines extract type, size, and content information from
+** [protected sqlite3_value] objects. Protected sqlite3_value objects
** are used to pass parameter information into the functions that
** implement [application-defined SQL functions] and [virtual tables].
-**
+**
** These routines work only with [protected sqlite3_value] objects.
** Any attempt to use these routines on an [unprotected sqlite3_value]
-** is not threadsafe.
+** is not threadsafe.
**
** ^These routines work just like the corresponding [column access functions]
** except that these routines take a single [protected sqlite3_value] object
@@ -5771,23 +5771,23 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** extract UTF-16 strings as big-endian and little-endian respectively.
**
** ^If [sqlite3_value] object V was initialized
-** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)]
-** and if X and Y are strings that compare equal according to strcmp(X,Y),
-** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise,
+** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)]
+** and if X and Y are strings that compare equal according to strcmp(X,Y),
+** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise,
** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer()
-** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
-**
-** ^(The sqlite3_value_type(V) interface returns the
-** [SQLITE_INTEGER | datatype code] for the initial datatype of the
-** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER],
-** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^
-** Other interfaces might change the datatype for an sqlite3_value object.
-** For example, if the datatype is initially SQLITE_INTEGER and
-** sqlite3_value_text(V) is called to extract a text value for that
-** integer, then subsequent calls to sqlite3_value_type(V) might return
-** SQLITE_TEXT. Whether or not a persistent internal datatype conversion
-** occurs is undefined and may change from one release of SQLite to the next.
-**
+** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
+**
+** ^(The sqlite3_value_type(V) interface returns the
+** [SQLITE_INTEGER | datatype code] for the initial datatype of the
+** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER],
+** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^
+** Other interfaces might change the datatype for an sqlite3_value object.
+** For example, if the datatype is initially SQLITE_INTEGER and
+** sqlite3_value_text(V) is called to extract a text value for that
+** integer, then subsequent calls to sqlite3_value_type(V) might return
+** SQLITE_TEXT. Whether or not a persistent internal datatype conversion
+** occurs is undefined and may change from one release of SQLite to the next.
+**
** ^(The sqlite3_value_numeric_type() interface attempts to apply
** numeric affinity to the value. This means that an attempt is
** made to convert the value to an integer or floating point. If
@@ -5796,19 +5796,19 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** then the conversion is performed. Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
-** ^Within the [xUpdate] method of a [virtual table], the
-** sqlite3_value_nochange(X) interface returns true if and only if
-** the column corresponding to X is unchanged by the UPDATE operation
-** that the xUpdate method call was invoked to implement and if
-** and the prior [xColumn] method call that was invoked to extracted
-** the value for that column returned without setting a result (probably
-** because it queried [sqlite3_vtab_nochange()] and found that the column
-** was unchanging). ^Within an [xUpdate] method, any value for which
-** sqlite3_value_nochange(X) is true will in all other respects appear
-** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other
-** than within an [xUpdate] method call for an UPDATE statement, then
-** the return value is arbitrary and meaningless.
-**
+** ^Within the [xUpdate] method of a [virtual table], the
+** sqlite3_value_nochange(X) interface returns true if and only if
+** the column corresponding to X is unchanged by the UPDATE operation
+** that the xUpdate method call was invoked to implement and if
+** and the prior [xColumn] method call that was invoked to extracted
+** the value for that column returned without setting a result (probably
+** because it queried [sqlite3_vtab_nochange()] and found that the column
+** was unchanging). ^Within an [xUpdate] method, any value for which
+** sqlite3_value_nochange(X) is true will in all other respects appear
+** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other
+** than within an [xUpdate] method call for an UPDATE statement, then
+** the return value is arbitrary and meaningless.
+**
** ^The sqlite3_value_frombind(X) interface returns non-zero if the
** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
** interfaces. ^If X comes from an SQL literal value, or a table column,
@@ -5845,35 +5845,35 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** return value is obtained and before any
** other SQLite interface is called on the same [database connection].
*/
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
-SQLITE_API double sqlite3_value_double(sqlite3_value*);
-SQLITE_API int sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
-SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*);
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API int sqlite3_value_type(sqlite3_value*);
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
-SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
+SQLITE_API double sqlite3_value_double(sqlite3_value*);
+SQLITE_API int sqlite3_value_int(sqlite3_value*);
+SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
+SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*);
+SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
+SQLITE_API int sqlite3_value_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
/*
-** CAPI3REF: Finding The Subtype Of SQL Values
-** METHOD: sqlite3_value
-**
-** The sqlite3_value_subtype(V) function returns the subtype for
-** an [application-defined SQL function] argument V. The subtype
-** information can be used to pass a limited amount of context from
-** one SQL function to another. Use the [sqlite3_result_subtype()]
-** routine to set the subtype for the return value of an SQL function.
-*/
-SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
-
-/*
+** CAPI3REF: Finding The Subtype Of SQL Values
+** METHOD: sqlite3_value
+**
+** The sqlite3_value_subtype(V) function returns the subtype for
+** an [application-defined SQL function] argument V. The subtype
+** information can be used to pass a limited amount of context from
+** one SQL function to another. Use the [sqlite3_result_subtype()]
+** routine to set the subtype for the return value of an SQL function.
+*/
+SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
+
+/*
** CAPI3REF: Copy And Free SQL Values
** METHOD: sqlite3_value
**
@@ -5887,8 +5887,8 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
** then sqlite3_value_free(V) is a harmless no-op.
*/
-SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
-SQLITE_API void sqlite3_value_free(sqlite3_value*);
+SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
+SQLITE_API void sqlite3_value_free(sqlite3_value*);
/*
** CAPI3REF: Obtain Aggregate Function Context
@@ -5933,7 +5933,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*);
** This routine must be called from the same thread in which
** the aggregate SQL function is running.
*/
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/*
** CAPI3REF: User Data For Functions
@@ -5948,7 +5948,7 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
** This routine must be called from the same thread in which
** the application-defined function is running.
*/
-SQLITE_API void *sqlite3_user_data(sqlite3_context*);
+SQLITE_API void *sqlite3_user_data(sqlite3_context*);
/*
** CAPI3REF: Database Connection For Functions
@@ -5960,7 +5960,7 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context*);
** and [sqlite3_create_function16()] routines that originally
** registered the application defined function.
*/
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
+SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/*
** CAPI3REF: Function Auxiliary Data
@@ -5977,11 +5977,11 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
-** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
-** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
-** value to the application-defined function. ^N is zero for the left-most
-** function argument. ^If there is no metadata
-** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
+** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
+** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
+** value to the application-defined function. ^N is zero for the left-most
+** function argument. ^If there is no metadata
+** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
@@ -5993,13 +5993,13 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** SQLite will invoke the destructor function X with parameter P exactly
** once, when the metadata is discarded.
** SQLite is free to discard the metadata at any time, including: <ul>
-** <li> ^(when the corresponding function parameter changes)^, or
-** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
-** SQL statement)^, or
-** <li> ^(when sqlite3_set_auxdata() is invoked again on the same
-** parameter)^, or
+** <li> ^(when the corresponding function parameter changes)^, or
+** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+** SQL statement)^, or
+** <li> ^(when sqlite3_set_auxdata() is invoked again on the same
+** parameter)^, or
** <li> ^(during the original sqlite3_set_auxdata() call when a memory
-** allocation error occurs.)^ </ul>
+** allocation error occurs.)^ </ul>
**
** Note the last bullet in particular. The destructor X in
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
@@ -6012,15 +6012,15 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
-** The value of the N parameter to these interfaces should be non-negative.
-** Future enhancements may make use of negative N values to define new
-** kinds of function caching behavior.
-**
+** The value of the N parameter to these interfaces should be non-negative.
+** Future enhancements may make use of negative N values to define new
+** kinds of function caching behavior.
+**
** These routines must be called from the same thread in which
** the SQL function is running.
*/
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
+SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
+SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
/*
@@ -6140,7 +6140,7 @@ typedef void (*sqlite3_destructor_type)(void*);
** when it has finished using that result.
** ^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
+** then SQLite makes a copy of the result into space obtained
** from [sqlite3_malloc()] before it returns.
**
** ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and
@@ -6172,60 +6172,60 @@ typedef void (*sqlite3_destructor_type)(void*);
** [unprotected sqlite3_value] object is required, so either
** kind of [sqlite3_value] object can be used with this interface.
**
-** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an
-** SQL NULL value, just like [sqlite3_result_null(C)], except that it
+** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an
+** SQL NULL value, just like [sqlite3_result_null(C)], except that it
** also associates the host-language pointer P or type T with that
-** NULL value such that the pointer can be retrieved within an
-** [application-defined SQL function] using [sqlite3_value_pointer()].
-** ^If the D parameter is not NULL, then it is a pointer to a destructor
-** for the P parameter. ^SQLite invokes D with P as its only argument
-** when SQLite is finished with P. The T parameter should be a static
-** string and preferably a string literal. The sqlite3_result_pointer()
-** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
-**
+** NULL value such that the pointer can be retrieved within an
+** [application-defined SQL function] using [sqlite3_value_pointer()].
+** ^If the D parameter is not NULL, then it is a pointer to a destructor
+** for the P parameter. ^SQLite invokes D with P as its only argument
+** when SQLite is finished with P. The T parameter should be a static
+** string and preferably a string literal. The sqlite3_result_pointer()
+** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
+**
** If these routines are called from within the different thread
** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined.
*/
-SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
+SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
sqlite3_uint64,void(*)(void*));
-SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void sqlite3_result_null(sqlite3_context*);
-SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
+SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
+SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
+SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+SQLITE_API void sqlite3_result_null(sqlite3_context*);
+SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
void(*)(void*), unsigned char encoding);
-SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*));
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
-SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
-
-
-/*
-** CAPI3REF: Setting The Subtype Of An SQL Function
-** METHOD: sqlite3_context
-**
-** The sqlite3_result_subtype(C,T) function causes the subtype of
+SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*));
+SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
+SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
+
+
+/*
+** CAPI3REF: Setting The Subtype Of An SQL Function
+** METHOD: sqlite3_context
+**
+** The sqlite3_result_subtype(C,T) function causes the subtype of
** the result from the [application-defined SQL function] with
** [sqlite3_context] C to be the value T. Only the lower 8 bits
-** of the subtype T are preserved in current versions of SQLite;
-** higher order bits are discarded.
-** The number of subtype bytes preserved by SQLite might increase
-** in future releases of SQLite.
-*/
-SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
-
-/*
+** of the subtype T are preserved in current versions of SQLite;
+** higher order bits are discarded.
+** The number of subtype bytes preserved by SQLite might increase
+** in future releases of SQLite.
+*/
+SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
+
+/*
** CAPI3REF: Define New Collating Sequences
** METHOD: sqlite3
**
@@ -6306,14 +6306,14 @@ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
**
** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
*/
-SQLITE_API int sqlite3_create_collation(
+SQLITE_API int sqlite3_create_collation(
sqlite3*,
const char *zName,
int eTextRep,
void *pArg,
int(*xCompare)(void*,int,const void*,int,const void*)
);
-SQLITE_API int sqlite3_create_collation_v2(
+SQLITE_API int sqlite3_create_collation_v2(
sqlite3*,
const char *zName,
int eTextRep,
@@ -6321,7 +6321,7 @@ SQLITE_API int sqlite3_create_collation_v2(
int(*xCompare)(void*,int,const void*,int,const void*),
void(*xDestroy)(void*)
);
-SQLITE_API int sqlite3_create_collation16(
+SQLITE_API int sqlite3_create_collation16(
sqlite3*,
const void *zName,
int eTextRep,
@@ -6356,12 +6356,12 @@ SQLITE_API int sqlite3_create_collation16(
** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
** [sqlite3_create_collation_v2()].
*/
-SQLITE_API int sqlite3_collation_needed(
+SQLITE_API int sqlite3_collation_needed(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const char*)
);
-SQLITE_API int sqlite3_collation_needed16(
+SQLITE_API int sqlite3_collation_needed16(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const void*)
@@ -6372,7 +6372,7 @@ SQLITE_API int sqlite3_collation_needed16(
** Specify the activation key for a CEROD database. Unless
** activated, none of the CEROD routines will work.
*/
-SQLITE_API void sqlite3_activate_cerod(
+SQLITE_API void sqlite3_activate_cerod(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -6394,7 +6394,7 @@ SQLITE_API void sqlite3_activate_cerod(
** all, then the behavior of sqlite3_sleep() may deviate from the description
** in the previous paragraphs.
*/
-SQLITE_API int sqlite3_sleep(int);
+SQLITE_API int sqlite3_sleep(int);
/*
** CAPI3REF: Name Of The Folder Holding Temporary Files
@@ -6548,7 +6548,7 @@ SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zVa
** connection while this routine is running, then the return value
** is undefined.
*/
-SQLITE_API int sqlite3_get_autocommit(sqlite3*);
+SQLITE_API int sqlite3_get_autocommit(sqlite3*);
/*
** CAPI3REF: Find The Database Handle Of A Prepared Statement
@@ -6561,7 +6561,7 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*);
** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
** create the statement in the first place.
*/
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
+SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
/*
** CAPI3REF: Return The Filename For A Database Connection
@@ -6593,7 +6593,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
** <li> [sqlite3_filename_wal()]
** </ul>
*/
-SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
+SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine if a database is read-only
@@ -6603,7 +6603,7 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
** of connection D is read-only, 0 if it is read/write, or -1 if N is not
** the name of a database on connection D.
*/
-SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
+SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine the transaction state of a database
@@ -6670,7 +6670,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema);
** [sqlite3_next_stmt(D,S)] must refer to an open database
** connection and in particular must not be a NULL pointer.
*/
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
+SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
** CAPI3REF: Commit And Rollback Notification Callbacks
@@ -6719,8 +6719,8 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
**
** See also the [sqlite3_update_hook()] interface.
*/
-SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
** CAPI3REF: Autovacuum Compaction Amount Callback
@@ -6795,7 +6795,7 @@ SQLITE_API int sqlite3_autovacuum_pages(
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
** to be invoked whenever a row is updated, inserted or deleted in
-** a [rowid table].
+** a [rowid table].
** ^Any callback set by a previous call to this function
** for the same database connection is overridden.
**
@@ -6816,7 +6816,7 @@ SQLITE_API int sqlite3_autovacuum_pages(
** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
-** is not invoked when conflicting rows are deleted because of an
+** is not invoked when conflicting rows are deleted because of an
** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
** invoked when rows are deleted using the [truncate optimization].
** The exceptions defined in this paragraph might change in a future
@@ -6834,10 +6834,10 @@ SQLITE_API int sqlite3_autovacuum_pages(
** on the same [database connection] D, or NULL for
** the first call on D.
**
-** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
-** and [sqlite3_preupdate_hook()] interfaces.
+** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
+** and [sqlite3_preupdate_hook()] interfaces.
*/
-SQLITE_API void *sqlite3_update_hook(
+SQLITE_API void *sqlite3_update_hook(
sqlite3*,
void(*)(void *,int ,char const *,char const *,sqlite3_int64),
void*
@@ -6853,7 +6853,7 @@ SQLITE_API void *sqlite3_update_hook(
**
** ^Cache sharing is enabled and disabled for an entire process.
** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]).
-** In prior versions of SQLite,
+** In prior versions of SQLite,
** sharing was enabled or disabled for each thread separately.
**
** ^(The cache sharing mode set by this interface effects all subsequent
@@ -6882,7 +6882,7 @@ SQLITE_API void *sqlite3_update_hook(
**
** See Also: [SQLite Shared-Cache Mode]
*/
-SQLITE_API int sqlite3_enable_shared_cache(int);
+SQLITE_API int sqlite3_enable_shared_cache(int);
/*
** CAPI3REF: Attempt To Free Heap Memory
@@ -6898,7 +6898,7 @@ SQLITE_API int sqlite3_enable_shared_cache(int);
**
** See also: [sqlite3_db_release_memory()]
*/
-SQLITE_API int sqlite3_release_memory(int);
+SQLITE_API int sqlite3_release_memory(int);
/*
** CAPI3REF: Free Memory Used By A Database Connection
@@ -6912,7 +6912,7 @@ SQLITE_API int sqlite3_release_memory(int);
**
** See also: [sqlite3_release_memory()]
*/
-SQLITE_API int sqlite3_db_release_memory(sqlite3*);
+SQLITE_API int sqlite3_db_release_memory(sqlite3*);
/*
** CAPI3REF: Impose A Limit On Heap Size
@@ -6978,7 +6978,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
** The circumstances under which SQLite will enforce the heap limits may
** changes in future releases of SQLite.
*/
-SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
+SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N);
/*
@@ -6990,7 +6990,7 @@ SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N);
** only. All new applications should use the
** [sqlite3_soft_heap_limit64()] interface rather than this one.
*/
-SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
+SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
/*
@@ -7005,11 +7005,11 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
** column exists. ^The sqlite3_table_column_metadata() interface returns
** SQLITE_ERROR if the specified column does not exist.
** ^If the column-name parameter to sqlite3_table_column_metadata() is a
-** NULL pointer, then this routine simply checks for the existence of the
+** NULL pointer, then this routine simply checks for the existence of the
** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
-** does not. If the table name parameter T in a call to
-** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is
-** undefined behavior.
+** does not. If the table name parameter T in a call to
+** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is
+** undefined behavior.
**
** ^The column is identified by the second, third and fourth parameters to
** this function. ^(The second parameter is either the name of the database
@@ -7062,7 +7062,7 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
** parsed, if that has not already been done, and returns an error if
** any errors are encountered while loading the schema.
*/
-SQLITE_API int sqlite3_table_column_metadata(
+SQLITE_API int sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
@@ -7104,21 +7104,21 @@ SQLITE_API int sqlite3_table_column_metadata(
** should free this memory by calling [sqlite3_free()].
**
** ^Extension loading must be enabled using
-** [sqlite3_enable_load_extension()] or
-** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
-** prior to calling this API,
+** [sqlite3_enable_load_extension()] or
+** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
+** prior to calling this API,
** otherwise an error will be returned.
**
** <b>Security warning:</b> It is recommended that the
-** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
-** interface. The use of the [sqlite3_enable_load_extension()] interface
-** should be avoided. This will keep the SQL function [load_extension()]
-** disabled and prevent SQL injections from giving attackers
-** access to extension loading capabilities.
-**
+** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
+** interface. The use of the [sqlite3_enable_load_extension()] interface
+** should be avoided. This will keep the SQL function [load_extension()]
+** disabled and prevent SQL injections from giving attackers
+** access to extension loading capabilities.
+**
** See also the [load_extension() SQL function].
*/
-SQLITE_API int sqlite3_load_extension(
+SQLITE_API int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Derived from zFile if 0 */
@@ -7138,19 +7138,19 @@ SQLITE_API int sqlite3_load_extension(
** ^Call the sqlite3_enable_load_extension() routine with onoff==1
** to turn extension loading on and call it with onoff==0 to turn
** it back off again.
-**
-** ^This interface enables or disables both the C-API
-** [sqlite3_load_extension()] and the SQL function [load_extension()].
-** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
-** to enable or disable only the C-API.)^
-**
-** <b>Security warning:</b> It is recommended that extension loading
+**
+** ^This interface enables or disables both the C-API
+** [sqlite3_load_extension()] and the SQL function [load_extension()].
+** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
+** to enable or disable only the C-API.)^
+**
+** <b>Security warning:</b> It is recommended that extension loading
** be enabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
-** rather than this interface, so the [load_extension()] SQL function
-** remains disabled. This will prevent SQL injections from giving attackers
-** access to extension loading capabilities.
+** rather than this interface, so the [load_extension()] SQL function
+** remains disabled. This will prevent SQL injections from giving attackers
+** access to extension loading capabilities.
*/
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
+SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
/*
** CAPI3REF: Automatically Load Statically Linked Extensions
@@ -7162,7 +7162,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
**
** ^(Even though the function prototype shows that xEntryPoint() takes
** no arguments and returns void, SQLite invokes xEntryPoint() with three
-** arguments and expects an integer result as if the signature of the
+** arguments and expects an integer result as if the signature of the
** entry point where as follows:
**
** <blockquote><pre>
@@ -7188,7 +7188,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** See also: [sqlite3_reset_auto_extension()]
** and [sqlite3_cancel_auto_extension()]
*/
-SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void));
+SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void));
/*
** CAPI3REF: Cancel Automatic Extension Loading
@@ -7200,7 +7200,7 @@ SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void));
** unregistered and it returns 0 if X was not on the list of initialization
** routines.
*/
-SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
+SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
/*
** CAPI3REF: Reset Automatic Extension Loading
@@ -7208,7 +7208,7 @@ SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
** ^This interface disables all automatic extensions previously
** registered using [sqlite3_auto_extension()].
*/
-SQLITE_API void sqlite3_reset_auto_extension(void);
+SQLITE_API void sqlite3_reset_auto_extension(void);
/*
** The interface to the virtual-table mechanism is currently considered
@@ -7313,17 +7313,17 @@ struct sqlite3_module {
** ^Information about the ORDER BY clause is stored in aOrderBy[].
** ^Each term of aOrderBy records a column of the ORDER BY clause.
**
-** The colUsed field indicates which columns of the virtual table may be
-** required by the current scan. Virtual table columns are numbered from
-** zero in the order in which they appear within the CREATE TABLE statement
-** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
-** the corresponding bit is set within the colUsed mask if the column may be
-** required by SQLite. If the table has at least 64 columns and any column
-** to the right of the first 63 is required, then bit 63 of colUsed is also
-** set. In other words, column iCol may be required if the expression
+** The colUsed field indicates which columns of the virtual table may be
+** required by the current scan. Virtual table columns are numbered from
+** zero in the order in which they appear within the CREATE TABLE statement
+** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
+** the corresponding bit is set within the colUsed mask if the column may be
+** required by SQLite. If the table has at least 64 columns and any column
+** to the right of the first 63 is required, then bit 63 of colUsed is also
+** set. In other words, column iCol may be required if the expression
** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to
-** non-zero.
-**
+** non-zero.
+**
** The [xBestIndex] method must fill aConstraintUsage[] with information
** about what parameters to pass to xFilter. ^If argvIndex>0 then
** the right-hand side of the corresponding aConstraint[] is evaluated
@@ -7356,38 +7356,38 @@ struct sqlite3_module {
** will be returned by the strategy.
**
** The xBestIndex method may optionally populate the idxFlags field with a
-** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
-** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
+** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
+** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
** assumes that the strategy may visit at most one row.
-**
-** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
-** SQLite also assumes that if a call to the xUpdate() method is made as
-** part of the same statement to delete or update a virtual table row and the
-** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
-** any database changes. In other words, if the xUpdate() returns
-** SQLITE_CONSTRAINT, the database contents must be exactly as they were
-** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
-** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
-** the xUpdate method are automatically rolled back by SQLite.
-**
+**
+** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
+** SQLite also assumes that if a call to the xUpdate() method is made as
+** part of the same statement to delete or update a virtual table row and the
+** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
+** any database changes. In other words, if the xUpdate() returns
+** SQLITE_CONSTRAINT, the database contents must be exactly as they were
+** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
+** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
+** the xUpdate method are automatically rolled back by SQLite.
+**
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
** structure for SQLite [version 3.8.2] ([dateof:3.8.2]).
-** If a virtual table extension is
+** If a virtual table extension is
** used with an SQLite version earlier than 3.8.2, the results of attempting
** to read or write the estimatedRows field are undefined (but are likely
** to include crashing the application). The estimatedRows field should
** therefore only be used if [sqlite3_libversion_number()] returns a
-** value greater than or equal to 3008002. Similarly, the idxFlags field
+** value greater than or equal to 3008002. Similarly, the idxFlags field
** was added for [version 3.9.0] ([dateof:3.9.0]).
-** It may therefore only be used if
-** sqlite3_libversion_number() returns a value greater than or equal to
-** 3009000.
+** It may therefore only be used if
+** sqlite3_libversion_number() returns a value greater than or equal to
+** 3009000.
*/
struct sqlite3_index_info {
/* Inputs */
int nConstraint; /* Number of entries in aConstraint */
struct sqlite3_index_constraint {
- int iColumn; /* Column constrained. -1 for ROWID */
+ int iColumn; /* Column constrained. -1 for ROWID */
unsigned char op; /* Constraint operator */
unsigned char usable; /* True if this constraint is usable */
int iTermOffset; /* Used internally - xBestIndex should ignore */
@@ -7409,22 +7409,22 @@ struct sqlite3_index_info {
double estimatedCost; /* Estimated cost of using this index */
/* Fields below are only available in SQLite 3.8.2 and later */
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
- /* Fields below are only available in SQLite 3.9.0 and later */
- int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
- /* Fields below are only available in SQLite 3.10.0 and later */
- sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */
+ /* Fields below are only available in SQLite 3.9.0 and later */
+ int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
+ /* Fields below are only available in SQLite 3.10.0 and later */
+ sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */
};
/*
-** CAPI3REF: Virtual Table Scan Flags
+** CAPI3REF: Virtual Table Scan Flags
**
** Virtual table implementations are allowed to set the
** [sqlite3_index_info].idxFlags field to some combination of
** these bits.
-*/
-#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
-
-/*
+*/
+#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
+
+/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
** These macros define the allowed values for the
@@ -7432,20 +7432,20 @@ struct sqlite3_index_info {
** an operator that is part of a constraint term in the wHERE clause of
** a query that uses a [virtual table].
*/
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
-#define SQLITE_INDEX_CONSTRAINT_GT 4
-#define SQLITE_INDEX_CONSTRAINT_LE 8
-#define SQLITE_INDEX_CONSTRAINT_LT 16
-#define SQLITE_INDEX_CONSTRAINT_GE 32
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
-#define SQLITE_INDEX_CONSTRAINT_LIKE 65
-#define SQLITE_INDEX_CONSTRAINT_GLOB 66
-#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
-#define SQLITE_INDEX_CONSTRAINT_NE 68
-#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
-#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
-#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
-#define SQLITE_INDEX_CONSTRAINT_IS 72
+#define SQLITE_INDEX_CONSTRAINT_EQ 2
+#define SQLITE_INDEX_CONSTRAINT_GT 4
+#define SQLITE_INDEX_CONSTRAINT_LE 8
+#define SQLITE_INDEX_CONSTRAINT_LT 16
+#define SQLITE_INDEX_CONSTRAINT_GE 32
+#define SQLITE_INDEX_CONSTRAINT_MATCH 64
+#define SQLITE_INDEX_CONSTRAINT_LIKE 65
+#define SQLITE_INDEX_CONSTRAINT_GLOB 66
+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
+#define SQLITE_INDEX_CONSTRAINT_NE 68
+#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
+#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
+#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
+#define SQLITE_INDEX_CONSTRAINT_IS 72
#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
/*
@@ -7480,13 +7480,13 @@ struct sqlite3_index_info {
**
** See also: [sqlite3_drop_modules()]
*/
-SQLITE_API int sqlite3_create_module(
+SQLITE_API int sqlite3_create_module(
sqlite3 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite3_module *p, /* Methods for the module */
void *pClientData /* Client data for xCreate/xConnect */
);
-SQLITE_API int sqlite3_create_module_v2(
+SQLITE_API int sqlite3_create_module_v2(
sqlite3 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite3_module *p, /* Methods for the module */
@@ -7566,7 +7566,7 @@ struct sqlite3_vtab_cursor {
** to declare the format (the names and datatypes of the columns) of
** the virtual tables they implement.
*/
-SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
/*
** CAPI3REF: Overload A Function For A Virtual Table
@@ -7585,7 +7585,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
** purpose is to be a placeholder function that can be overloaded
** by a [virtual table].
*/
-SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
/*
** The interface to the virtual-table mechanism defined above (back up
@@ -7660,12 +7660,12 @@ typedef struct sqlite3_blob sqlite3_blob;
** [database connection] error code and message accessible via
** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
**
-** A BLOB referenced by sqlite3_blob_open() may be read using the
-** [sqlite3_blob_read()] interface and modified by using
-** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a
-** different row of the same table using the [sqlite3_blob_reopen()]
-** interface. However, the column, table, or database of a [BLOB handle]
-** cannot be changed after the [BLOB handle] is opened.
+** A BLOB referenced by sqlite3_blob_open() may be read using the
+** [sqlite3_blob_read()] interface and modified by using
+** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a
+** different row of the same table using the [sqlite3_blob_reopen()]
+** interface. However, the column, table, or database of a [BLOB handle]
+** cannot be changed after the [BLOB handle] is opened.
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
@@ -7689,12 +7689,12 @@ typedef struct sqlite3_blob sqlite3_blob;
**
** To avoid a resource leak, every open [BLOB handle] should eventually
** be released by a call to [sqlite3_blob_close()].
-**
-** See also: [sqlite3_blob_close()],
-** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
-** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
+**
+** See also: [sqlite3_blob_close()],
+** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
+** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
*/
-SQLITE_API int sqlite3_blob_open(
+SQLITE_API int sqlite3_blob_open(
sqlite3*,
const char *zDb,
const char *zTable,
@@ -7708,11 +7708,11 @@ SQLITE_API int sqlite3_blob_open(
** CAPI3REF: Move a BLOB Handle to a New Row
** METHOD: sqlite3_blob
**
-** ^This function is used to move an existing [BLOB handle] so that it points
+** ^This function is used to move an existing [BLOB handle] so that it points
** to a different row of the same database table. ^The new row is identified
** by the rowid value passed as the second argument. Only the row can be
** changed. ^The database, table and column on which the blob handle is open
-** remain the same. Moving an existing [BLOB handle] to a new row is
+** remain the same. Moving an existing [BLOB handle] to a new row is
** faster than closing the existing handle and opening a new one.
**
** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
@@ -7727,7 +7727,7 @@ SQLITE_API int sqlite3_blob_open(
**
** ^This function sets the database handle error code and message.
*/
-SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
/*
** CAPI3REF: Close A BLOB Handle
@@ -7750,7 +7750,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
** is passed a valid open blob handle, the values returned by the
** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
+SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
/*
** CAPI3REF: Return The Size Of An Open BLOB
@@ -7766,7 +7766,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
*/
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
+SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
/*
** CAPI3REF: Read Data From A BLOB Incrementally
@@ -7795,7 +7795,7 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
**
** See also: [sqlite3_blob_write()].
*/
-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
@@ -7837,7 +7837,7 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
**
** See also: [sqlite3_blob_read()].
*/
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
/*
** CAPI3REF: Virtual File System Objects
@@ -7868,9 +7868,9 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOff
** ^(If the default VFS is unregistered, another VFS is chosen as
** the default. The choice for the new VFS is arbitrary.)^
*/
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
+SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
+SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
/*
** CAPI3REF: Mutexes
@@ -7923,9 +7923,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** <li> SQLITE_MUTEX_STATIC_APP1
** <li> SQLITE_MUTEX_STATIC_APP2
** <li> SQLITE_MUTEX_STATIC_APP3
-** <li> SQLITE_MUTEX_STATIC_VFS1
-** <li> SQLITE_MUTEX_STATIC_VFS2
-** <li> SQLITE_MUTEX_STATIC_VFS3
+** <li> SQLITE_MUTEX_STATIC_VFS1
+** <li> SQLITE_MUTEX_STATIC_VFS2
+** <li> SQLITE_MUTEX_STATIC_VFS3
** </ul>
**
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
@@ -7986,11 +7986,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
+SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
+SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
/*
** CAPI3REF: Mutex Methods Object
@@ -8100,8 +8100,8 @@ struct sqlite3_mutex_methods {
** interface should also return 1 when given a NULL pointer.
*/
#ifndef NDEBUG
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#endif
/*
@@ -8120,7 +8120,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
-#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */
+#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */
#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
@@ -8145,7 +8145,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
** ^If the [threading mode] is Single-thread or Multi-thread then this
** routine returns a NULL pointer.
*/
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
+SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
/*
** CAPI3REF: Low-Level Control Of Database Files
@@ -8168,7 +8168,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** A few opcodes for [sqlite3_file_control()] are handled directly
** by the SQLite core and never invoke the
** sqlite3_io_methods.xFileControl method.
-** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
+** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
** a pointer to the underlying [sqlite3_file] object to be written into
** the space pointed to by the 4th parameter. The
** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
@@ -8186,9 +8186,9 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** an incorrect zDbName and an SQLITE_ERROR return from the underlying
** xFileControl method.
**
-** See also: [file control opcodes]
+** See also: [file control opcodes]
*/
-SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
/*
** CAPI3REF: Testing Interface
@@ -8207,7 +8207,7 @@ SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*
** Unlike most of the SQLite API, this function is not guaranteed to
** operate consistently from one release to the next.
*/
-SQLITE_API int sqlite3_test_control(int op, ...);
+SQLITE_API int sqlite3_test_control(int op, ...);
/*
** CAPI3REF: Testing Interface Operation Codes
@@ -8233,18 +8233,18 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
-#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
+#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
-#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
+#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
#define SQLITE_TESTCTRL_BYTEORDER 22
#define SQLITE_TESTCTRL_ISINIT 23
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
-#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
+#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
#define SQLITE_TESTCTRL_RESULT_INTREAL 27
#define SQLITE_TESTCTRL_PRNG_SEED 28
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
@@ -8462,8 +8462,8 @@ SQLITE_API char *sqlite3_str_value(sqlite3_str*);
**
** See also: [sqlite3_db_status()]
*/
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
-SQLITE_API int sqlite3_status64(
+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int sqlite3_status64(
int op,
sqlite3_int64 *pCurrent,
sqlite3_int64 *pHighwater,
@@ -8483,7 +8483,7 @@ SQLITE_API int sqlite3_status64(
** <dd>This parameter is the current amount of memory checked out
** using [sqlite3_malloc()], either directly or indirectly. The
** figure includes calls made to [sqlite3_malloc()] by the application
-** and internal memory usage by the SQLite library. Auxiliary page-cache
+** and internal memory usage by the SQLite library. Auxiliary page-cache
** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
** this parameter. The amount returned is the sum of the allocation
** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
@@ -8521,18 +8521,18 @@ SQLITE_API int sqlite3_status64(
** *pHighwater parameter to [sqlite3_status()] is of interest.
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
-** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt>
-** <dd>No longer used.</dd>
+** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt>
+** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
-** <dd>No longer used.</dd>
+** <dd>No longer used.</dd>
**
-** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
-** <dd>No longer used.</dd>
+** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
+** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
** <dd>The *pHighwater parameter records the deepest parser stack.
-** The *pCurrent value is undefined. The *pHighwater value is only
+** The *pCurrent value is undefined. The *pHighwater value is only
** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
** </dl>
**
@@ -8541,12 +8541,12 @@ SQLITE_API int sqlite3_status64(
#define SQLITE_STATUS_MEMORY_USED 0
#define SQLITE_STATUS_PAGECACHE_USED 1
#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2
-#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */
-#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */
+#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */
+#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */
#define SQLITE_STATUS_MALLOC_SIZE 5
#define SQLITE_STATUS_PARSER_STACK 6
#define SQLITE_STATUS_PAGECACHE_SIZE 7
-#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */
+#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */
#define SQLITE_STATUS_MALLOC_COUNT 9
/*
@@ -8572,7 +8572,7 @@ SQLITE_API int sqlite3_status64(
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
-SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
@@ -8619,17 +8619,17 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
**
** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]]
-** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt>
-** <dd>This parameter is similar to DBSTATUS_CACHE_USED, except that if a
-** pager cache is shared between two or more connections the bytes of heap
-** memory used by that pager cache is divided evenly between the attached
-** connections.)^ In other words, if none of the pager caches associated
-** with the database connection are shared, this request returns the same
-** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are
-** shared, the value returned by this call will be smaller than that returned
-** by DBSTATUS_CACHE_USED. ^The highwater mark associated with
-** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.
-**
+** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt>
+** <dd>This parameter is similar to DBSTATUS_CACHE_USED, except that if a
+** pager cache is shared between two or more connections the bytes of heap
+** memory used by that pager cache is divided evenly between the attached
+** connections.)^ In other words, if none of the pager caches associated
+** with the database connection are shared, this request returns the same
+** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are
+** shared, the value returned by this call will be smaller than that returned
+** by DBSTATUS_CACHE_USED. ^The highwater mark associated with
+** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.
+**
** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
** <dd>This parameter returns the approximate number of bytes of heap
** memory used to store the schema for all databases associated
@@ -8696,7 +8696,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
#define SQLITE_DBSTATUS_CACHE_MISS 8
#define SQLITE_DBSTATUS_CACHE_WRITE 9
#define SQLITE_DBSTATUS_DEFERRED_FKS 10
-#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11
+#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11
#define SQLITE_DBSTATUS_CACHE_SPILL 12
#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */
@@ -8725,7 +8725,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
**
** See also: [sqlite3_status()] and [sqlite3_db_status()].
*/
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
/*
** CAPI3REF: Status Parameters for prepared statements
@@ -8761,24 +8761,24 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
** used as a proxy for the total work done by the prepared statement.
** If the number of virtual machine operations exceeds 2147483647
** then the value returned by this statement status code is undefined.
-**
-** [[SQLITE_STMTSTATUS_REPREPARE]] <dt>SQLITE_STMTSTATUS_REPREPARE</dt>
-** <dd>^This is the number of times that the prepare statement has been
+**
+** [[SQLITE_STMTSTATUS_REPREPARE]] <dt>SQLITE_STMTSTATUS_REPREPARE</dt>
+** <dd>^This is the number of times that the prepare statement has been
** automatically regenerated due to schema changes or changes to
-** [bound parameters] that might affect the query plan.
-**
-** [[SQLITE_STMTSTATUS_RUN]] <dt>SQLITE_STMTSTATUS_RUN</dt>
-** <dd>^This is the number of times that the prepared statement has
-** been run. A single "run" for the purposes of this counter is one
-** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
-** The counter is incremented on the first [sqlite3_step()] call of each
-** cycle.
-**
-** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
-** <dd>^This is the approximate number of bytes of heap memory
-** used to store the prepared statement. ^This value is not actually
-** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
-** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
+** [bound parameters] that might affect the query plan.
+**
+** [[SQLITE_STMTSTATUS_RUN]] <dt>SQLITE_STMTSTATUS_RUN</dt>
+** <dd>^This is the number of times that the prepared statement has
+** been run. A single "run" for the purposes of this counter is one
+** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
+** The counter is incremented on the first [sqlite3_step()] call of each
+** cycle.
+**
+** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
+** <dd>^This is the approximate number of bytes of heap memory
+** used to store the prepared statement. ^This value is not actually
+** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
+** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
** </dd>
** </dl>
*/
@@ -8786,9 +8786,9 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
#define SQLITE_STMTSTATUS_VM_STEP 4
-#define SQLITE_STMTSTATUS_REPREPARE 5
-#define SQLITE_STMTSTATUS_RUN 6
-#define SQLITE_STMTSTATUS_MEMUSED 99
+#define SQLITE_STMTSTATUS_REPREPARE 5
+#define SQLITE_STMTSTATUS_RUN 6
+#define SQLITE_STMTSTATUS_MEMUSED 99
/*
** CAPI3REF: Custom Page Cache Object
@@ -9215,16 +9215,16 @@ typedef struct sqlite3_backup sqlite3_backup;
** same time as another thread is invoking sqlite3_backup_step() it is
** possible that they return invalid values.
*/
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
+SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3 *pDest, /* Destination database handle */
const char *zDestName, /* Destination database name */
sqlite3 *pSource, /* Source database handle */
const char *zSourceName /* Source database name */
);
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
+SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
/*
** CAPI3REF: Unlock Notification
@@ -9341,7 +9341,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
** the special "DROP TABLE/INDEX" case, the extended error code is just
** SQLITE_LOCKED.)^
*/
-SQLITE_API int sqlite3_unlock_notify(
+SQLITE_API int sqlite3_unlock_notify(
sqlite3 *pBlocked, /* Waiting connection */
void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
void *pNotifyArg /* Argument to pass to xNotify */
@@ -9356,50 +9356,50 @@ SQLITE_API int sqlite3_unlock_notify(
** strings in a case-independent fashion, using the same definition of "case
** independence" that SQLite uses internally when comparing identifiers.
*/
-SQLITE_API int sqlite3_stricmp(const char *, const char *);
-SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
+SQLITE_API int sqlite3_stricmp(const char *, const char *);
+SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
/*
** CAPI3REF: String Globbing
*
-** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
-** string X matches the [GLOB] pattern P.
-** ^The definition of [GLOB] pattern matching used in
+** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
+** string X matches the [GLOB] pattern P.
+** ^The definition of [GLOB] pattern matching used in
** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
-** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function
-** is case sensitive.
+** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function
+** is case sensitive.
+**
+** Note that this routine returns zero on a match and non-zero if the strings
+** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
+**
+** See also: [sqlite3_strlike()].
+*/
+SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
+
+/*
+** CAPI3REF: String LIKE Matching
+*
+** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
+** string X matches the [LIKE] pattern P with escape character E.
+** ^The definition of [LIKE] pattern matching used in
+** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
+** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without
+** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
+** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
+** insensitive - equivalent upper and lower case ASCII characters match
+** one another.
+**
+** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
+** only ASCII characters are case folded.
**
** Note that this routine returns zero on a match and non-zero if the strings
** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
-**
-** See also: [sqlite3_strlike()].
-*/
-SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
-
-/*
-** CAPI3REF: String LIKE Matching
-*
-** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
-** string X matches the [LIKE] pattern P with escape character E.
-** ^The definition of [LIKE] pattern matching used in
-** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
-** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without
-** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
-** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
-** insensitive - equivalent upper and lower case ASCII characters match
-** one another.
-**
-** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
-** only ASCII characters are case folded.
-**
-** Note that this routine returns zero on a match and non-zero if the strings
-** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
-**
-** See also: [sqlite3_strglob()].
-*/
-SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
-
-/*
+**
+** See also: [sqlite3_strglob()].
+*/
+SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
+
+/*
** CAPI3REF: Error Logging Interface
**
** ^The [sqlite3_log()] interface writes a message into the [error log]
@@ -9420,7 +9420,7 @@ SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int
** a few hundred characters, it will be truncated to the length of the
** buffer.
*/
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
+SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
/*
** CAPI3REF: Write-Ahead Log Commit Hook
@@ -9455,9 +9455,9 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
** a copy of the third parameter from the previous call, if any, or 0.
** ^Note that the [sqlite3_wal_autocheckpoint()] interface and the
** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
-** overwrite any prior [sqlite3_wal_hook()] settings.
+** overwrite any prior [sqlite3_wal_hook()] settings.
*/
-SQLITE_API void *sqlite3_wal_hook(
+SQLITE_API void *sqlite3_wal_hook(
sqlite3*,
int(*)(void *,sqlite3*,const char*,int),
void*
@@ -9492,7 +9492,7 @@ SQLITE_API void *sqlite3_wal_hook(
** is only necessary if the default setting is found to be suboptimal
** for a particular application.
*/
-SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
+SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
/*
** CAPI3REF: Checkpoint a database
@@ -9514,7 +9514,7 @@ SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
** start a callback but which do not need the full power (and corresponding
** complication) of [sqlite3_wal_checkpoint_v2()].
*/
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
/*
** CAPI3REF: Checkpoint a database
@@ -9608,7 +9608,7 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
** from SQL.
*/
-SQLITE_API int sqlite3_wal_checkpoint_v2(
+SQLITE_API int sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -9648,7 +9648,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
** of parameters after C depend on which [virtual table configuration option]
** is used.
*/
-SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Virtual Table Configuration Options
@@ -9726,50 +9726,50 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
-SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
+SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/*
-** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
-**
-** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
+** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
+**
+** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
** method of a [virtual table], then it might return true if the
-** column is being fetched as part of an UPDATE operation during which the
+** column is being fetched as part of an UPDATE operation during which the
** column value will not change. The virtual table implementation can use
** this hint as permission to substitute a return value that is less
** expensive to compute and that the corresponding
** [xUpdate] method understands as a "no-change" value.
-**
-** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
+**
+** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
** the column is not changed by the UPDATE statement, then the xColumn
-** method can optionally return without setting a result, without calling
-** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
-** In that case, [sqlite3_value_nochange(X)] will return true for the
-** same column in the [xUpdate] method.
+** method can optionally return without setting a result, without calling
+** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
+** In that case, [sqlite3_value_nochange(X)] will return true for the
+** same column in the [xUpdate] method.
**
** The sqlite3_vtab_nochange() routine is an optimization. Virtual table
** implementations should continue to give a correct answer even if the
** sqlite3_vtab_nochange() interface were to always return false. In the
** current implementation, the sqlite3_vtab_nochange() interface does always
** returns false for the enhanced [UPDATE FROM] statement.
-*/
-SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
-
-/*
-** CAPI3REF: Determine The Collation For a Virtual Table Constraint
-**
-** This function may only be called from within a call to the [xBestIndex]
+*/
+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
+
+/*
+** CAPI3REF: Determine The Collation For a Virtual Table Constraint
+**
+** This function may only be called from within a call to the [xBestIndex]
** method of a [virtual table].
-**
-** The first argument must be the sqlite3_index_info object that is the
-** first parameter to the xBestIndex() method. The second argument must be
-** an index into the aConstraint[] array belonging to the sqlite3_index_info
+**
+** The first argument must be the sqlite3_index_info object that is the
+** first parameter to the xBestIndex() method. The second argument must be
+** an index into the aConstraint[] array belonging to the sqlite3_index_info
** structure passed to xBestIndex. This function returns a pointer to a buffer
-** containing the name of the collation sequence for the corresponding
-** constraint.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
-
-/*
+** containing the name of the collation sequence for the corresponding
+** constraint.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
+
+/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
@@ -9872,7 +9872,7 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_
**
** See also: [sqlite3_stmt_scanstatus_reset()]
*/
-SQLITE_API int sqlite3_stmt_scanstatus(
+SQLITE_API int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
@@ -9888,122 +9888,122 @@ SQLITE_API int sqlite3_stmt_scanstatus(
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
-SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
+SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
-/*
-** CAPI3REF: Flush caches to disk mid-transaction
+/*
+** CAPI3REF: Flush caches to disk mid-transaction
** METHOD: sqlite3
-**
-** ^If a write-transaction is open on [database connection] D when the
-** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
+**
+** ^If a write-transaction is open on [database connection] D when the
+** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
** pages in the pager-cache that are not currently in use are written out
-** to disk. A dirty page may be in use if a database cursor created by an
-** active SQL statement is reading from it, or if it is page 1 of a database
-** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)]
-** interface flushes caches for all schemas - "main", "temp", and
-** any [attached] databases.
-**
+** to disk. A dirty page may be in use if a database cursor created by an
+** active SQL statement is reading from it, or if it is page 1 of a database
+** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)]
+** interface flushes caches for all schemas - "main", "temp", and
+** any [attached] databases.
+**
** ^If this function needs to obtain extra database locks before dirty pages
** can be flushed to disk, it does so. ^If those locks cannot be obtained
-** immediately and there is a busy-handler callback configured, it is invoked
-** in the usual manner. ^If the required lock still cannot be obtained, then
-** the database is skipped and an attempt made to flush any dirty pages
-** belonging to the next (if any) database. ^If any databases are skipped
-** because locks cannot be obtained, but no other error occurs, this
-** function returns SQLITE_BUSY.
-**
-** ^If any other error occurs while flushing dirty pages to disk (for
-** example an IO error or out-of-memory condition), then processing is
-** abandoned and an SQLite [error code] is returned to the caller immediately.
-**
-** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
-**
-** ^This function does not set the database handle error code or message
-** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
-*/
-SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
-
-/*
-** CAPI3REF: The pre-update hook.
+** immediately and there is a busy-handler callback configured, it is invoked
+** in the usual manner. ^If the required lock still cannot be obtained, then
+** the database is skipped and an attempt made to flush any dirty pages
+** belonging to the next (if any) database. ^If any databases are skipped
+** because locks cannot be obtained, but no other error occurs, this
+** function returns SQLITE_BUSY.
+**
+** ^If any other error occurs while flushing dirty pages to disk (for
+** example an IO error or out-of-memory condition), then processing is
+** abandoned and an SQLite [error code] is returned to the caller immediately.
+**
+** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
+**
+** ^This function does not set the database handle error code or message
+** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
+*/
+SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
+
+/*
+** CAPI3REF: The pre-update hook.
** METHOD: sqlite3
-**
-** ^These interfaces are only available if SQLite is compiled using the
-** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
-**
-** ^The [sqlite3_preupdate_hook()] interface registers a callback function
-** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
-** on a database table.
-** ^At most one preupdate hook may be registered at a time on a single
-** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
-** the previous setting.
-** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()]
-** with a NULL pointer as the second parameter.
-** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
-** the first parameter to callbacks.
-**
-** ^The preupdate hook only fires for changes to real database tables; the
-** preupdate hook is not invoked for changes to [virtual tables] or to
+**
+** ^These interfaces are only available if SQLite is compiled using the
+** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
+**
+** ^The [sqlite3_preupdate_hook()] interface registers a callback function
+** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
+** on a database table.
+** ^At most one preupdate hook may be registered at a time on a single
+** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
+** the previous setting.
+** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()]
+** with a NULL pointer as the second parameter.
+** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
+** the first parameter to callbacks.
+**
+** ^The preupdate hook only fires for changes to real database tables; the
+** preupdate hook is not invoked for changes to [virtual tables] or to
** system tables like sqlite_sequence or sqlite_stat1.
-**
-** ^The second parameter to the preupdate callback is a pointer to
-** the [database connection] that registered the preupdate hook.
-** ^The third parameter to the preupdate callback is one of the constants
-** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the
-** kind of update operation that is about to occur.
-** ^(The fourth parameter to the preupdate callback is the name of the
-** database within the database connection that is being modified. This
+**
+** ^The second parameter to the preupdate callback is a pointer to
+** the [database connection] that registered the preupdate hook.
+** ^The third parameter to the preupdate callback is one of the constants
+** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the
+** kind of update operation that is about to occur.
+** ^(The fourth parameter to the preupdate callback is the name of the
+** database within the database connection that is being modified. This
** will be "main" for the main database or "temp" for TEMP tables or
-** the name given after the AS keyword in the [ATTACH] statement for attached
-** databases.)^
-** ^The fifth parameter to the preupdate callback is the name of the
-** table that is being modified.
-**
-** For an UPDATE or DELETE operation on a [rowid table], the sixth
+** the name given after the AS keyword in the [ATTACH] statement for attached
+** databases.)^
+** ^The fifth parameter to the preupdate callback is the name of the
+** table that is being modified.
+**
+** For an UPDATE or DELETE operation on a [rowid table], the sixth
** parameter passed to the preupdate callback is the initial [rowid] of the
-** row being modified or deleted. For an INSERT operation on a rowid table,
+** row being modified or deleted. For an INSERT operation on a rowid table,
** or any operation on a WITHOUT ROWID table, the value of the sixth
-** parameter is undefined. For an INSERT or UPDATE on a rowid table the
-** seventh parameter is the final rowid value of the row being inserted
-** or updated. The value of the seventh parameter passed to the callback
-** function is not defined for operations on WITHOUT ROWID tables, or for
+** parameter is undefined. For an INSERT or UPDATE on a rowid table the
+** seventh parameter is the final rowid value of the row being inserted
+** or updated. The value of the seventh parameter passed to the callback
+** function is not defined for operations on WITHOUT ROWID tables, or for
** DELETE operations on rowid tables.
-**
-** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
-** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
-** provide additional information about a preupdate event. These routines
-** may only be called from within a preupdate callback. Invoking any of
-** these routines from outside of a preupdate callback or with a
-** [database connection] pointer that is different from the one supplied
-** to the preupdate callback results in undefined and probably undesirable
-** behavior.
-**
-** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns
-** in the row that is being inserted, updated, or deleted.
-**
-** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to
-** a [protected sqlite3_value] that contains the value of the Nth column of
-** the table row before it is updated. The N parameter must be between 0
-** and one less than the number of columns or the behavior will be
-** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE
-** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the
-** behavior is undefined. The [sqlite3_value] that P points to
-** will be destroyed when the preupdate callback returns.
-**
-** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to
-** a [protected sqlite3_value] that contains the value of the Nth column of
-** the table row after it is updated. The N parameter must be between 0
-** and one less than the number of columns or the behavior will be
-** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE
-** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the
-** behavior is undefined. The [sqlite3_value] that P points to
-** will be destroyed when the preupdate callback returns.
-**
-** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate
-** callback was invoked as a result of a direct insert, update, or delete
+**
+** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
+** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
+** provide additional information about a preupdate event. These routines
+** may only be called from within a preupdate callback. Invoking any of
+** these routines from outside of a preupdate callback or with a
+** [database connection] pointer that is different from the one supplied
+** to the preupdate callback results in undefined and probably undesirable
+** behavior.
+**
+** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns
+** in the row that is being inserted, updated, or deleted.
+**
+** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to
+** a [protected sqlite3_value] that contains the value of the Nth column of
+** the table row before it is updated. The N parameter must be between 0
+** and one less than the number of columns or the behavior will be
+** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE
+** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the
+** behavior is undefined. The [sqlite3_value] that P points to
+** will be destroyed when the preupdate callback returns.
+**
+** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to
+** a [protected sqlite3_value] that contains the value of the Nth column of
+** the table row after it is updated. The N parameter must be between 0
+** and one less than the number of columns or the behavior will be
+** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE
+** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the
+** behavior is undefined. The [sqlite3_value] that P points to
+** will be destroyed when the preupdate callback returns.
+**
+** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate
+** callback was invoked as a result of a direct insert, update, or delete
** operation; or 1 for inserts, updates, or deletes invoked by top-level
-** triggers; or 2 for changes resulting from triggers called by top-level
-** triggers; and so forth.
-**
+** triggers; or 2 for changes resulting from triggers called by top-level
+** triggers; and so forth.
+**
** When the [sqlite3_blob_write()] API is used to update a blob column,
** the pre-update hook is invoked with SQLITE_DELETE. This is because the
** in this case the new values are not available. In this case, when a
@@ -10013,126 +10013,126 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
** pre-update hook is being invoked for some other reason, including a
** regular DELETE, sqlite3_preupdate_blobwrite() returns -1.
**
-** See also: [sqlite3_update_hook()]
-*/
-#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
-SQLITE_API void *sqlite3_preupdate_hook(
- sqlite3 *db,
- void(*xPreUpdate)(
- void *pCtx, /* Copy of third arg to preupdate_hook() */
- sqlite3 *db, /* Database handle */
- int op, /* SQLITE_UPDATE, DELETE or INSERT */
- char const *zDb, /* Database name */
- char const *zName, /* Table name */
- sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */
- sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */
- ),
- void*
-);
-SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
-SQLITE_API int sqlite3_preupdate_count(sqlite3 *);
-SQLITE_API int sqlite3_preupdate_depth(sqlite3 *);
-SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
+** See also: [sqlite3_update_hook()]
+*/
+#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+SQLITE_API void *sqlite3_preupdate_hook(
+ sqlite3 *db,
+ void(*xPreUpdate)(
+ void *pCtx, /* Copy of third arg to preupdate_hook() */
+ sqlite3 *db, /* Database handle */
+ int op, /* SQLITE_UPDATE, DELETE or INSERT */
+ char const *zDb, /* Database name */
+ char const *zName, /* Table name */
+ sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */
+ sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */
+ ),
+ void*
+);
+SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
+SQLITE_API int sqlite3_preupdate_count(sqlite3 *);
+SQLITE_API int sqlite3_preupdate_depth(sqlite3 *);
+SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *);
-#endif
-
-/*
-** CAPI3REF: Low-level system error code
+#endif
+
+/*
+** CAPI3REF: Low-level system error code
** METHOD: sqlite3
-**
-** ^Attempt to return the underlying operating system error code or error
-** number that caused the most recent I/O error or failure to open a file.
-** The return value is OS-dependent. For example, on unix systems, after
-** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
-** called to get back the underlying "errno" that caused the problem, such
+**
+** ^Attempt to return the underlying operating system error code or error
+** number that caused the most recent I/O error or failure to open a file.
+** The return value is OS-dependent. For example, on unix systems, after
+** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
+** called to get back the underlying "errno" that caused the problem, such
** as ENOSPC, EAUTH, EISDIR, and so forth.
-*/
-SQLITE_API int sqlite3_system_errno(sqlite3*);
-
-/*
-** CAPI3REF: Database Snapshot
-** KEYWORDS: {snapshot} {sqlite3_snapshot}
-**
-** An instance of the snapshot object records the state of a [WAL mode]
-** database for some specific point in history.
-**
-** In [WAL mode], multiple [database connections] that are open on the
-** same database file can each be reading a different historical version
-** of the database file. When a [database connection] begins a read
-** transaction, that connection sees an unchanging copy of the database
-** as it existed for the point in time when the transaction first started.
-** Subsequent changes to the database from other connections are not seen
-** by the reader until a new read transaction is started.
-**
-** The sqlite3_snapshot object records state information about an historical
-** version of the database file so that it is possible to later open a new read
-** transaction that sees that historical version of the database rather than
-** the most recent version.
-*/
-typedef struct sqlite3_snapshot {
- unsigned char hidden[48];
-} sqlite3_snapshot;
-
-/*
-** CAPI3REF: Record A Database Snapshot
+*/
+SQLITE_API int sqlite3_system_errno(sqlite3*);
+
+/*
+** CAPI3REF: Database Snapshot
+** KEYWORDS: {snapshot} {sqlite3_snapshot}
+**
+** An instance of the snapshot object records the state of a [WAL mode]
+** database for some specific point in history.
+**
+** In [WAL mode], multiple [database connections] that are open on the
+** same database file can each be reading a different historical version
+** of the database file. When a [database connection] begins a read
+** transaction, that connection sees an unchanging copy of the database
+** as it existed for the point in time when the transaction first started.
+** Subsequent changes to the database from other connections are not seen
+** by the reader until a new read transaction is started.
+**
+** The sqlite3_snapshot object records state information about an historical
+** version of the database file so that it is possible to later open a new read
+** transaction that sees that historical version of the database rather than
+** the most recent version.
+*/
+typedef struct sqlite3_snapshot {
+ unsigned char hidden[48];
+} sqlite3_snapshot;
+
+/*
+** CAPI3REF: Record A Database Snapshot
** CONSTRUCTOR: sqlite3_snapshot
-**
-** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
-** new [sqlite3_snapshot] object that records the current state of
-** schema S in database connection D. ^On success, the
-** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
-** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
-** If there is not already a read-transaction open on schema S when
+**
+** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
+** new [sqlite3_snapshot] object that records the current state of
+** schema S in database connection D. ^On success, the
+** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
+** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
+** If there is not already a read-transaction open on schema S when
** this function is called, one is opened automatically.
-**
-** The following must be true for this function to succeed. If any of
-** the following statements are false when sqlite3_snapshot_get() is
-** called, SQLITE_ERROR is returned. The final value of *P is undefined
+**
+** The following must be true for this function to succeed. If any of
+** the following statements are false when sqlite3_snapshot_get() is
+** called, SQLITE_ERROR is returned. The final value of *P is undefined
** in this case.
-**
-** <ul>
+**
+** <ul>
** <li> The database handle must not be in [autocommit mode].
-**
-** <li> Schema S of [database connection] D must be a [WAL mode] database.
-**
-** <li> There must not be a write transaction open on schema S of database
-** connection D.
-**
-** <li> One or more transactions must have been written to the current wal
-** file since it was created on disk (by any connection). This means
+**
+** <li> Schema S of [database connection] D must be a [WAL mode] database.
+**
+** <li> There must not be a write transaction open on schema S of database
+** connection D.
+**
+** <li> One or more transactions must have been written to the current wal
+** file since it was created on disk (by any connection). This means
** that a snapshot cannot be taken on a wal mode database with no wal
-** file immediately after it is first opened. At least one transaction
-** must be written to it first.
-** </ul>
-**
-** This function may also return SQLITE_NOMEM. If it is called with the
+** file immediately after it is first opened. At least one transaction
+** must be written to it first.
+** </ul>
+**
+** This function may also return SQLITE_NOMEM. If it is called with the
** database handle in autocommit mode but fails for some other reason,
-** whether or not a read transaction is opened on schema S is undefined.
-**
-** The [sqlite3_snapshot] object returned from a successful call to
-** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
-** to avoid a memory leak.
-**
-** The [sqlite3_snapshot_get()] interface is only available when the
+** whether or not a read transaction is opened on schema S is undefined.
+**
+** The [sqlite3_snapshot] object returned from a successful call to
+** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
+** to avoid a memory leak.
+**
+** The [sqlite3_snapshot_get()] interface is only available when the
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
- sqlite3 *db,
- const char *zSchema,
- sqlite3_snapshot **ppSnapshot
-);
-
-/*
-** CAPI3REF: Start a read transaction on an historical snapshot
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
+ sqlite3 *db,
+ const char *zSchema,
+ sqlite3_snapshot **ppSnapshot
+);
+
+/*
+** CAPI3REF: Start a read transaction on an historical snapshot
** METHOD: sqlite3_snapshot
-**
+**
** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read
** transaction or upgrades an existing one for schema S of
** [database connection] D such that the read transaction refers to
** historical [snapshot] P, rather than the most recent change to the
** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK
** on success or an appropriate [error code] if it fails.
-**
+**
** ^In order to succeed, the database connection must not be in
** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
** is already a read transaction open on schema S, then the database handle
@@ -10153,71 +10153,71 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
** read transaction is undefined. If SQLITE_OK is returned, then the
** read transaction is now open on database snapshot P.
**
-** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
-** database connection D does not know that the database file for
-** schema S is in [WAL mode]. A database connection might not know
-** that the database file is in [WAL mode] if there has been no prior
+** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
+** database connection D does not know that the database file for
+** schema S is in [WAL mode]. A database connection might not know
+** that the database file is in [WAL mode] if there has been no prior
** I/O on that database connection, or if the database entered [WAL mode]
-** after the most recent I/O on the database connection.)^
-** (Hint: Run "[PRAGMA application_id]" against a newly opened
-** database connection in order to make it ready to use snapshots.)
-**
-** The [sqlite3_snapshot_open()] interface is only available when the
+** after the most recent I/O on the database connection.)^
+** (Hint: Run "[PRAGMA application_id]" against a newly opened
+** database connection in order to make it ready to use snapshots.)
+**
+** The [sqlite3_snapshot_open()] interface is only available when the
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
- sqlite3 *db,
- const char *zSchema,
- sqlite3_snapshot *pSnapshot
-);
-
-/*
-** CAPI3REF: Destroy a snapshot
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
+ sqlite3 *db,
+ const char *zSchema,
+ sqlite3_snapshot *pSnapshot
+);
+
+/*
+** CAPI3REF: Destroy a snapshot
** DESTRUCTOR: sqlite3_snapshot
-**
-** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
-** The application must eventually free every [sqlite3_snapshot] object
-** using this routine to avoid a memory leak.
-**
-** The [sqlite3_snapshot_free()] interface is only available when the
+**
+** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
+** The application must eventually free every [sqlite3_snapshot] object
+** using this routine to avoid a memory leak.
+**
+** The [sqlite3_snapshot_free()] interface is only available when the
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
-
-/*
-** CAPI3REF: Compare the ages of two snapshot handles.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
+
+/*
+** CAPI3REF: Compare the ages of two snapshot handles.
** METHOD: sqlite3_snapshot
-**
-** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
+**
+** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
** of two valid snapshot handles.
-**
+**
** If the two snapshot handles are not associated with the same database
** file, the result of the comparison is undefined.
-**
-** Additionally, the result of the comparison is only valid if both of the
-** snapshot handles were obtained by calling sqlite3_snapshot_get() since the
-** last time the wal file was deleted. The wal file is deleted when the
-** database is changed back to rollback mode or when the number of database
+**
+** Additionally, the result of the comparison is only valid if both of the
+** snapshot handles were obtained by calling sqlite3_snapshot_get() since the
+** last time the wal file was deleted. The wal file is deleted when the
+** database is changed back to rollback mode or when the number of database
** clients drops to zero. If either snapshot handle was obtained before the
** wal file was last deleted, the value returned by this function
-** is undefined.
-**
-** Otherwise, this API returns a negative value if P1 refers to an older
-** snapshot than P2, zero if the two handles refer to the same database
-** snapshot, and a positive value if P1 is a newer snapshot than P2.
+** is undefined.
+**
+** Otherwise, this API returns a negative value if P1 refers to an older
+** snapshot than P2, zero if the two handles refer to the same database
+** snapshot, and a positive value if P1 is a newer snapshot than P2.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_SNAPSHOT] option.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
- sqlite3_snapshot *p1,
- sqlite3_snapshot *p2
-);
-
-/*
-** CAPI3REF: Recover snapshots from a wal file
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
+ sqlite3_snapshot *p1,
+ sqlite3_snapshot *p2
+);
+
+/*
+** CAPI3REF: Recover snapshots from a wal file
** METHOD: sqlite3_snapshot
-**
+**
** If a [WAL file] remains on disk after all database connections close
** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
** or because the last process to have the database opened exited without
@@ -10225,21 +10225,21 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
** on that database and [WAL file], the [sqlite3_snapshot_open()] interface
** will only be able to open the last transaction added to the WAL file
** even though the WAL file contains other valid transactions.
-**
+**
** This function attempts to scan the WAL file associated with database zDb
-** of database handle db and make all valid snapshots available to
-** sqlite3_snapshot_open(). It is an error if there is already a read
+** of database handle db and make all valid snapshots available to
+** sqlite3_snapshot_open(). It is an error if there is already a read
** transaction open on the database, or if the database is not a WAL mode
-** database.
-**
-** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+** database.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_SNAPSHOT] option.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
-
-/*
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
+
+/*
** CAPI3REF: Serialize a database
**
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
@@ -10376,9 +10376,9 @@ SQLITE_API int sqlite3_deserialize(
#if 0
} /* End of the 'extern "C"' block */
#endif
-#endif /* SQLITE3_H */
+#endif /* SQLITE3_H */
-/******** Begin file sqlite3rtree.h *********/
+/******** Begin file sqlite3rtree.h *********/
/*
** 2010 August 30
**
@@ -10418,7 +10418,7 @@ typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
*/
-SQLITE_API int sqlite3_rtree_geometry_callback(
+SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db,
const char *zGeom,
int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
@@ -10444,7 +10444,7 @@ struct sqlite3_rtree_geometry {
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
*/
-SQLITE_API int sqlite3_rtree_query_callback(
+SQLITE_API int sqlite3_rtree_query_callback(
sqlite3 *db,
const char *zQueryFunc,
int (*xQueryFunc)(sqlite3_rtree_query_info*),
@@ -10496,88 +10496,88 @@ struct sqlite3_rtree_query_info {
#endif /* ifndef _SQLITE3RTREE_H_ */
-/******** End of sqlite3rtree.h *********/
-/******** Begin file sqlite3session.h *********/
-
-#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION)
-#define __SQLITESESSION_H_ 1
-
-/*
-** Make sure we can call this stuff from C++.
-*/
-#if 0
-extern "C" {
-#endif
-
-
-/*
-** CAPI3REF: Session Object Handle
+/******** End of sqlite3rtree.h *********/
+/******** Begin file sqlite3session.h *********/
+
+#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION)
+#define __SQLITESESSION_H_ 1
+
+/*
+** Make sure we can call this stuff from C++.
+*/
+#if 0
+extern "C" {
+#endif
+
+
+/*
+** CAPI3REF: Session Object Handle
**
** An instance of this object is a [session] that can be used to
** record changes to a database.
-*/
-typedef struct sqlite3_session sqlite3_session;
-
-/*
-** CAPI3REF: Changeset Iterator Handle
+*/
+typedef struct sqlite3_session sqlite3_session;
+
+/*
+** CAPI3REF: Changeset Iterator Handle
**
** An instance of this object acts as a cursor for iterating
** over the elements of a [changeset] or [patchset].
-*/
-typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
-
-/*
-** CAPI3REF: Create A New Session Object
+*/
+typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
+
+/*
+** CAPI3REF: Create A New Session Object
** CONSTRUCTOR: sqlite3_session
-**
-** Create a new session object attached to database handle db. If successful,
-** a pointer to the new object is written to *ppSession and SQLITE_OK is
-** returned. If an error occurs, *ppSession is set to NULL and an SQLite
-** error code (e.g. SQLITE_NOMEM) is returned.
-**
-** It is possible to create multiple session objects attached to a single
-** database handle.
-**
-** Session objects created using this function should be deleted using the
-** [sqlite3session_delete()] function before the database handle that they
-** are attached to is itself closed. If the database handle is closed before
-** the session object is deleted, then the results of calling any session
-** module function, including [sqlite3session_delete()] on the session object
-** are undefined.
-**
-** Because the session module uses the [sqlite3_preupdate_hook()] API, it
-** is not possible for an application to register a pre-update hook on a
-** database handle that has one or more session objects attached. Nor is
-** it possible to create a session object attached to a database handle for
+**
+** Create a new session object attached to database handle db. If successful,
+** a pointer to the new object is written to *ppSession and SQLITE_OK is
+** returned. If an error occurs, *ppSession is set to NULL and an SQLite
+** error code (e.g. SQLITE_NOMEM) is returned.
+**
+** It is possible to create multiple session objects attached to a single
+** database handle.
+**
+** Session objects created using this function should be deleted using the
+** [sqlite3session_delete()] function before the database handle that they
+** are attached to is itself closed. If the database handle is closed before
+** the session object is deleted, then the results of calling any session
+** module function, including [sqlite3session_delete()] on the session object
+** are undefined.
+**
+** Because the session module uses the [sqlite3_preupdate_hook()] API, it
+** is not possible for an application to register a pre-update hook on a
+** database handle that has one or more session objects attached. Nor is
+** it possible to create a session object attached to a database handle for
** which a pre-update hook is already defined. The results of attempting
-** either of these things are undefined.
-**
-** The session object will be used to create changesets for tables in
-** database zDb, where zDb is either "main", or "temp", or the name of an
-** attached database. It is not an error if database zDb is not attached
-** to the database when the session object is created.
-*/
-SQLITE_API int sqlite3session_create(
- sqlite3 *db, /* Database handle */
- const char *zDb, /* Name of db (e.g. "main") */
- sqlite3_session **ppSession /* OUT: New session object */
-);
-
-/*
-** CAPI3REF: Delete A Session Object
+** either of these things are undefined.
+**
+** The session object will be used to create changesets for tables in
+** database zDb, where zDb is either "main", or "temp", or the name of an
+** attached database. It is not an error if database zDb is not attached
+** to the database when the session object is created.
+*/
+SQLITE_API int sqlite3session_create(
+ sqlite3 *db, /* Database handle */
+ const char *zDb, /* Name of db (e.g. "main") */
+ sqlite3_session **ppSession /* OUT: New session object */
+);
+
+/*
+** CAPI3REF: Delete A Session Object
** DESTRUCTOR: sqlite3_session
-**
+**
** Delete a session object previously allocated using
-** [sqlite3session_create()]. Once a session object has been deleted, the
-** results of attempting to use pSession with any other session module
-** function are undefined.
-**
-** Session objects must be deleted before the database handle to which they
+** [sqlite3session_create()]. Once a session object has been deleted, the
+** results of attempting to use pSession with any other session module
+** function are undefined.
+**
+** Session objects must be deleted before the database handle to which they
** are attached is closed. Refer to the documentation for
-** [sqlite3session_create()] for details.
-*/
-SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
-
+** [sqlite3session_create()] for details.
+*/
+SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
+
/*
** CAPIREF: Conigure a Session Object
** METHOD: sqlite3_session
@@ -10606,255 +10606,255 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
** the first table has been attached to the session object.
*/
SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
-
-/*
+
+/*
*/
#define SQLITE_SESSION_OBJCONFIG_SIZE 1
/*
-** CAPI3REF: Enable Or Disable A Session Object
+** CAPI3REF: Enable Or Disable A Session Object
** METHOD: sqlite3_session
-**
-** Enable or disable the recording of changes by a session object. When
-** enabled, a session object records changes made to the database. When
-** disabled - it does not. A newly created session object is enabled.
-** Refer to the documentation for [sqlite3session_changeset()] for further
-** details regarding how enabling and disabling a session object affects
-** the eventual changesets.
-**
-** Passing zero to this function disables the session. Passing a value
+**
+** Enable or disable the recording of changes by a session object. When
+** enabled, a session object records changes made to the database. When
+** disabled - it does not. A newly created session object is enabled.
+** Refer to the documentation for [sqlite3session_changeset()] for further
+** details regarding how enabling and disabling a session object affects
+** the eventual changesets.
+**
+** Passing zero to this function disables the session. Passing a value
** greater than zero enables it. Passing a value less than zero is a
-** no-op, and may be used to query the current state of the session.
-**
+** no-op, and may be used to query the current state of the session.
+**
** The return value indicates the final state of the session object: 0 if
-** the session is disabled, or 1 if it is enabled.
-*/
-SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
-
-/*
-** CAPI3REF: Set Or Clear the Indirect Change Flag
+** the session is disabled, or 1 if it is enabled.
+*/
+SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
+
+/*
+** CAPI3REF: Set Or Clear the Indirect Change Flag
** METHOD: sqlite3_session
-**
-** Each change recorded by a session object is marked as either direct or
-** indirect. A change is marked as indirect if either:
-**
-** <ul>
-** <li> The session object "indirect" flag is set when the change is
-** made, or
+**
+** Each change recorded by a session object is marked as either direct or
+** indirect. A change is marked as indirect if either:
+**
+** <ul>
+** <li> The session object "indirect" flag is set when the change is
+** made, or
** <li> The change is made by an SQL trigger or foreign key action
-** instead of directly as a result of a users SQL statement.
-** </ul>
-**
-** If a single row is affected by more than one operation within a session,
-** then the change is considered indirect if all operations meet the criteria
-** for an indirect change above, or direct otherwise.
-**
-** This function is used to set, clear or query the session object indirect
-** flag. If the second argument passed to this function is zero, then the
-** indirect flag is cleared. If it is greater than zero, the indirect flag
-** is set. Passing a value less than zero does not modify the current value
+** instead of directly as a result of a users SQL statement.
+** </ul>
+**
+** If a single row is affected by more than one operation within a session,
+** then the change is considered indirect if all operations meet the criteria
+** for an indirect change above, or direct otherwise.
+**
+** This function is used to set, clear or query the session object indirect
+** flag. If the second argument passed to this function is zero, then the
+** indirect flag is cleared. If it is greater than zero, the indirect flag
+** is set. Passing a value less than zero does not modify the current value
** of the indirect flag, and may be used to query the current state of the
-** indirect flag for the specified session object.
-**
+** indirect flag for the specified session object.
+**
** The return value indicates the final state of the indirect flag: 0 if
-** it is clear, or 1 if it is set.
-*/
-SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
-
-/*
-** CAPI3REF: Attach A Table To A Session Object
+** it is clear, or 1 if it is set.
+*/
+SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
+
+/*
+** CAPI3REF: Attach A Table To A Session Object
** METHOD: sqlite3_session
-**
-** If argument zTab is not NULL, then it is the name of a table to attach
+**
+** If argument zTab is not NULL, then it is the name of a table to attach
** to the session object passed as the first argument. All subsequent changes
** made to the table while the session object is enabled will be recorded. See
-** documentation for [sqlite3session_changeset()] for further details.
-**
-** Or, if argument zTab is NULL, then changes are recorded for all tables
+** documentation for [sqlite3session_changeset()] for further details.
+**
+** Or, if argument zTab is NULL, then changes are recorded for all tables
** in the database. If additional tables are added to the database (by
** executing "CREATE TABLE" statements) after this call is made, changes for
-** the new tables are also recorded.
-**
-** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
+** the new tables are also recorded.
+**
+** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
** defined as part of their CREATE TABLE statement. It does not matter if the
-** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY
-** KEY may consist of a single column, or may be a composite key.
-**
-** It is not an error if the named table does not exist in the database. Nor
-** is it an error if the named table does not have a PRIMARY KEY. However,
-** no changes will be recorded in either of these scenarios.
-**
-** Changes are not recorded for individual rows that have NULL values stored
-** in one or more of their PRIMARY KEY columns.
-**
+** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY
+** KEY may consist of a single column, or may be a composite key.
+**
+** It is not an error if the named table does not exist in the database. Nor
+** is it an error if the named table does not have a PRIMARY KEY. However,
+** no changes will be recorded in either of these scenarios.
+**
+** Changes are not recorded for individual rows that have NULL values stored
+** in one or more of their PRIMARY KEY columns.
+**
** SQLITE_OK is returned if the call completes without error. Or, if an error
-** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
-**
-** <h3>Special sqlite_stat1 Handling</h3>
-**
+** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
+**
+** <h3>Special sqlite_stat1 Handling</h3>
+**
** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to
-** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
-** <pre>
+** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
+** <pre>
** &nbsp; CREATE TABLE sqlite_stat1(tbl,idx,stat)
-** </pre>
-**
+** </pre>
+**
** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are
** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes
-** are recorded for rows for which (idx IS NULL) is true. However, for such
-** rows a zero-length blob (SQL value X'') is stored in the changeset or
-** patchset instead of a NULL value. This allows such changesets to be
-** manipulated by legacy implementations of sqlite3changeset_invert(),
-** concat() and similar.
-**
+** are recorded for rows for which (idx IS NULL) is true. However, for such
+** rows a zero-length blob (SQL value X'') is stored in the changeset or
+** patchset instead of a NULL value. This allows such changesets to be
+** manipulated by legacy implementations of sqlite3changeset_invert(),
+** concat() and similar.
+**
** The sqlite3changeset_apply() function automatically converts the
-** zero-length blob back to a NULL value when updating the sqlite_stat1
-** table. However, if the application calls sqlite3changeset_new(),
+** zero-length blob back to a NULL value when updating the sqlite_stat1
+** table. However, if the application calls sqlite3changeset_new(),
** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset
-** iterator directly (including on a changeset iterator passed to a
-** conflict-handler callback) then the X'' value is returned. The application
-** must translate X'' to NULL itself if required.
-**
-** Legacy (older than 3.22.0) versions of the sessions module cannot capture
-** changes made to the sqlite_stat1 table. Legacy versions of the
-** sqlite3changeset_apply() function silently ignore any modifications to the
-** sqlite_stat1 table that are part of a changeset or patchset.
-*/
-SQLITE_API int sqlite3session_attach(
- sqlite3_session *pSession, /* Session object */
- const char *zTab /* Table name */
-);
-
-/*
-** CAPI3REF: Set a table filter on a Session Object.
+** iterator directly (including on a changeset iterator passed to a
+** conflict-handler callback) then the X'' value is returned. The application
+** must translate X'' to NULL itself if required.
+**
+** Legacy (older than 3.22.0) versions of the sessions module cannot capture
+** changes made to the sqlite_stat1 table. Legacy versions of the
+** sqlite3changeset_apply() function silently ignore any modifications to the
+** sqlite_stat1 table that are part of a changeset or patchset.
+*/
+SQLITE_API int sqlite3session_attach(
+ sqlite3_session *pSession, /* Session object */
+ const char *zTab /* Table name */
+);
+
+/*
+** CAPI3REF: Set a table filter on a Session Object.
** METHOD: sqlite3_session
-**
+**
** The second argument (xFilter) is the "filter callback". For changes to rows
-** in tables that are not attached to the Session object, the filter is called
+** in tables that are not attached to the Session object, the filter is called
** to determine whether changes to the table's rows should be tracked or not.
** If xFilter returns 0, changes are not tracked. Note that once a table is
-** attached, xFilter will not be called again.
-*/
-SQLITE_API void sqlite3session_table_filter(
- sqlite3_session *pSession, /* Session object */
- int(*xFilter)(
- void *pCtx, /* Copy of third arg to _filter_table() */
- const char *zTab /* Table name */
- ),
- void *pCtx /* First argument passed to xFilter */
-);
-
-/*
-** CAPI3REF: Generate A Changeset From A Session Object
+** attached, xFilter will not be called again.
+*/
+SQLITE_API void sqlite3session_table_filter(
+ sqlite3_session *pSession, /* Session object */
+ int(*xFilter)(
+ void *pCtx, /* Copy of third arg to _filter_table() */
+ const char *zTab /* Table name */
+ ),
+ void *pCtx /* First argument passed to xFilter */
+);
+
+/*
+** CAPI3REF: Generate A Changeset From A Session Object
** METHOD: sqlite3_session
-**
+**
** Obtain a changeset containing changes to the tables attached to the
** session object passed as the first argument. If successful,
** set *ppChangeset to point to a buffer containing the changeset
-** and *pnChangeset to the size of the changeset in bytes before returning
-** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to
-** zero and return an SQLite error code.
-**
-** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes,
-** each representing a change to a single row of an attached table. An INSERT
-** change contains the values of each field of a new database row. A DELETE
-** contains the original values of each field of a deleted database row. An
-** UPDATE change contains the original values of each field of an updated
-** database row along with the updated values for each updated non-primary-key
-** column. It is not possible for an UPDATE change to represent a change that
-** modifies the values of primary key columns. If such a change is made, it
-** is represented in a changeset as a DELETE followed by an INSERT.
-**
+** and *pnChangeset to the size of the changeset in bytes before returning
+** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to
+** zero and return an SQLite error code.
+**
+** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes,
+** each representing a change to a single row of an attached table. An INSERT
+** change contains the values of each field of a new database row. A DELETE
+** contains the original values of each field of a deleted database row. An
+** UPDATE change contains the original values of each field of an updated
+** database row along with the updated values for each updated non-primary-key
+** column. It is not possible for an UPDATE change to represent a change that
+** modifies the values of primary key columns. If such a change is made, it
+** is represented in a changeset as a DELETE followed by an INSERT.
+**
** Changes are not recorded for rows that have NULL values stored in one or
-** more of their PRIMARY KEY columns. If such a row is inserted or deleted,
-** no corresponding change is present in the changesets returned by this
-** function. If an existing row with one or more NULL values stored in
-** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL,
-** only an INSERT is appears in the changeset. Similarly, if an existing row
-** with non-NULL PRIMARY KEY values is updated so that one or more of its
-** PRIMARY KEY columns are set to NULL, the resulting changeset contains a
-** DELETE change only.
-**
-** The contents of a changeset may be traversed using an iterator created
-** using the [sqlite3changeset_start()] API. A changeset may be applied to
-** a database with a compatible schema using the [sqlite3changeset_apply()]
-** API.
-**
-** Within a changeset generated by this function, all changes related to a
-** single table are grouped together. In other words, when iterating through
-** a changeset or when applying a changeset to a database, all changes related
-** to a single table are processed before moving on to the next table. Tables
-** are sorted in the same order in which they were attached (or auto-attached)
-** to the sqlite3_session object. The order in which the changes related to
-** a single table are stored is undefined.
-**
-** Following a successful call to this function, it is the responsibility of
-** the caller to eventually free the buffer that *ppChangeset points to using
-** [sqlite3_free()].
-**
-** <h3>Changeset Generation</h3>
-**
-** Once a table has been attached to a session object, the session object
-** records the primary key values of all new rows inserted into the table.
-** It also records the original primary key and other column values of any
-** deleted or updated rows. For each unique primary key value, data is only
-** recorded once - the first time a row with said primary key is inserted,
-** updated or deleted in the lifetime of the session.
-**
-** There is one exception to the previous paragraph: when a row is inserted,
-** updated or deleted, if one or more of its primary key columns contain a
-** NULL value, no record of the change is made.
-**
-** The session object therefore accumulates two types of records - those
-** that consist of primary key values only (created when the user inserts
-** a new record) and those that consist of the primary key values and the
-** original values of other table columns (created when the users deletes
-** or updates a record).
-**
-** When this function is called, the requested changeset is created using
-** both the accumulated records and the current contents of the database
-** file. Specifically:
-**
-** <ul>
-** <li> For each record generated by an insert, the database is queried
-** for a row with a matching primary key. If one is found, an INSERT
+** more of their PRIMARY KEY columns. If such a row is inserted or deleted,
+** no corresponding change is present in the changesets returned by this
+** function. If an existing row with one or more NULL values stored in
+** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL,
+** only an INSERT is appears in the changeset. Similarly, if an existing row
+** with non-NULL PRIMARY KEY values is updated so that one or more of its
+** PRIMARY KEY columns are set to NULL, the resulting changeset contains a
+** DELETE change only.
+**
+** The contents of a changeset may be traversed using an iterator created
+** using the [sqlite3changeset_start()] API. A changeset may be applied to
+** a database with a compatible schema using the [sqlite3changeset_apply()]
+** API.
+**
+** Within a changeset generated by this function, all changes related to a
+** single table are grouped together. In other words, when iterating through
+** a changeset or when applying a changeset to a database, all changes related
+** to a single table are processed before moving on to the next table. Tables
+** are sorted in the same order in which they were attached (or auto-attached)
+** to the sqlite3_session object. The order in which the changes related to
+** a single table are stored is undefined.
+**
+** Following a successful call to this function, it is the responsibility of
+** the caller to eventually free the buffer that *ppChangeset points to using
+** [sqlite3_free()].
+**
+** <h3>Changeset Generation</h3>
+**
+** Once a table has been attached to a session object, the session object
+** records the primary key values of all new rows inserted into the table.
+** It also records the original primary key and other column values of any
+** deleted or updated rows. For each unique primary key value, data is only
+** recorded once - the first time a row with said primary key is inserted,
+** updated or deleted in the lifetime of the session.
+**
+** There is one exception to the previous paragraph: when a row is inserted,
+** updated or deleted, if one or more of its primary key columns contain a
+** NULL value, no record of the change is made.
+**
+** The session object therefore accumulates two types of records - those
+** that consist of primary key values only (created when the user inserts
+** a new record) and those that consist of the primary key values and the
+** original values of other table columns (created when the users deletes
+** or updates a record).
+**
+** When this function is called, the requested changeset is created using
+** both the accumulated records and the current contents of the database
+** file. Specifically:
+**
+** <ul>
+** <li> For each record generated by an insert, the database is queried
+** for a row with a matching primary key. If one is found, an INSERT
** change is added to the changeset. If no such row is found, no change
-** is added to the changeset.
-**
+** is added to the changeset.
+**
** <li> For each record generated by an update or delete, the database is
-** queried for a row with a matching primary key. If such a row is
-** found and one or more of the non-primary key fields have been
+** queried for a row with a matching primary key. If such a row is
+** found and one or more of the non-primary key fields have been
** modified from their original values, an UPDATE change is added to
** the changeset. Or, if no such row is found in the table, a DELETE
-** change is added to the changeset. If there is a row with a matching
-** primary key in the database, but all fields contain their original
-** values, no change is added to the changeset.
-** </ul>
-**
-** This means, amongst other things, that if a row is inserted and then later
-** deleted while a session object is active, neither the insert nor the delete
+** change is added to the changeset. If there is a row with a matching
+** primary key in the database, but all fields contain their original
+** values, no change is added to the changeset.
+** </ul>
+**
+** This means, amongst other things, that if a row is inserted and then later
+** deleted while a session object is active, neither the insert nor the delete
** will be present in the changeset. Or if a row is deleted and then later a
-** row with the same primary key values inserted while a session object is
-** active, the resulting changeset will contain an UPDATE change instead of
-** a DELETE and an INSERT.
-**
-** When a session object is disabled (see the [sqlite3session_enable()] API),
-** it does not accumulate records when rows are inserted, updated or deleted.
-** This may appear to have some counter-intuitive effects if a single row
-** is written to more than once during a session. For example, if a row
+** row with the same primary key values inserted while a session object is
+** active, the resulting changeset will contain an UPDATE change instead of
+** a DELETE and an INSERT.
+**
+** When a session object is disabled (see the [sqlite3session_enable()] API),
+** it does not accumulate records when rows are inserted, updated or deleted.
+** This may appear to have some counter-intuitive effects if a single row
+** is written to more than once during a session. For example, if a row
** is inserted while a session object is enabled, then later deleted while
-** the same session object is disabled, no INSERT record will appear in the
-** changeset, even though the delete took place while the session was disabled.
+** the same session object is disabled, no INSERT record will appear in the
+** changeset, even though the delete took place while the session was disabled.
** Or, if one field of a row is updated while a session is disabled, and
-** another field of the same row is updated while the session is enabled, the
-** resulting changeset will contain an UPDATE change that updates both fields.
-*/
-SQLITE_API int sqlite3session_changeset(
- sqlite3_session *pSession, /* Session object */
- int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
- void **ppChangeset /* OUT: Buffer containing changeset */
-);
-
-/*
+** another field of the same row is updated while the session is enabled, the
+** resulting changeset will contain an UPDATE change that updates both fields.
+*/
+SQLITE_API int sqlite3session_changeset(
+ sqlite3_session *pSession, /* Session object */
+ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
+ void **ppChangeset /* OUT: Buffer containing changeset */
+);
+
+/*
** CAPI3REF: Return An Upper-limit For The Size Of The Changeset
** METHOD: sqlite3_session
**
@@ -10873,121 +10873,121 @@ SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession
/*
** CAPI3REF: Load The Difference Between Tables Into A Session
** METHOD: sqlite3_session
-**
-** If it is not already attached to the session object passed as the first
-** argument, this function attaches table zTbl in the same manner as the
-** [sqlite3session_attach()] function. If zTbl does not exist, or if it
-** does not have a primary key, this function is a no-op (but does not return
-** an error).
-**
-** Argument zFromDb must be the name of a database ("main", "temp" etc.)
+**
+** If it is not already attached to the session object passed as the first
+** argument, this function attaches table zTbl in the same manner as the
+** [sqlite3session_attach()] function. If zTbl does not exist, or if it
+** does not have a primary key, this function is a no-op (but does not return
+** an error).
+**
+** Argument zFromDb must be the name of a database ("main", "temp" etc.)
** attached to the same database handle as the session object that contains
-** a table compatible with the table attached to the session by this function.
-** A table is considered compatible if it:
-**
-** <ul>
-** <li> Has the same name,
-** <li> Has the same set of columns declared in the same order, and
-** <li> Has the same PRIMARY KEY definition.
-** </ul>
-**
-** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables
-** are compatible but do not have any PRIMARY KEY columns, it is not an error
-** but no changes are added to the session object. As with other session
-** APIs, tables without PRIMARY KEYs are simply ignored.
-**
-** This function adds a set of changes to the session object that could be
+** a table compatible with the table attached to the session by this function.
+** A table is considered compatible if it:
+**
+** <ul>
+** <li> Has the same name,
+** <li> Has the same set of columns declared in the same order, and
+** <li> Has the same PRIMARY KEY definition.
+** </ul>
+**
+** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables
+** are compatible but do not have any PRIMARY KEY columns, it is not an error
+** but no changes are added to the session object. As with other session
+** APIs, tables without PRIMARY KEYs are simply ignored.
+**
+** This function adds a set of changes to the session object that could be
** used to update the table in database zFrom (call this the "from-table")
** so that its content is the same as the table attached to the session
-** object (call this the "to-table"). Specifically:
-**
-** <ul>
+** object (call this the "to-table"). Specifically:
+**
+** <ul>
** <li> For each row (primary key) that exists in the to-table but not in
-** the from-table, an INSERT record is added to the session object.
-**
+** the from-table, an INSERT record is added to the session object.
+**
** <li> For each row (primary key) that exists in the to-table but not in
-** the from-table, a DELETE record is added to the session object.
-**
+** the from-table, a DELETE record is added to the session object.
+**
** <li> For each row (primary key) that exists in both tables, but features
-** different non-PK values in each, an UPDATE record is added to the
+** different non-PK values in each, an UPDATE record is added to the
** session.
-** </ul>
-**
-** To clarify, if this function is called and then a changeset constructed
+** </ul>
+**
+** To clarify, if this function is called and then a changeset constructed
** using [sqlite3session_changeset()], then after applying that changeset to
** database zFrom the contents of the two compatible tables would be
-** identical.
-**
-** It an error if database zFrom does not exist or does not contain the
-** required compatible table.
-**
+** identical.
+**
+** It an error if database zFrom does not exist or does not contain the
+** required compatible table.
+**
** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite
-** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
+** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
** may be set to point to a buffer containing an English language error
-** message. It is the responsibility of the caller to free this buffer using
-** sqlite3_free().
-*/
-SQLITE_API int sqlite3session_diff(
- sqlite3_session *pSession,
- const char *zFromDb,
- const char *zTbl,
- char **pzErrMsg
-);
-
-
-/*
-** CAPI3REF: Generate A Patchset From A Session Object
+** message. It is the responsibility of the caller to free this buffer using
+** sqlite3_free().
+*/
+SQLITE_API int sqlite3session_diff(
+ sqlite3_session *pSession,
+ const char *zFromDb,
+ const char *zTbl,
+ char **pzErrMsg
+);
+
+
+/*
+** CAPI3REF: Generate A Patchset From A Session Object
** METHOD: sqlite3_session
-**
-** The differences between a patchset and a changeset are that:
-**
-** <ul>
+**
+** The differences between a patchset and a changeset are that:
+**
+** <ul>
** <li> DELETE records consist of the primary key fields only. The
-** original values of other fields are omitted.
+** original values of other fields are omitted.
** <li> The original values of any modified fields are omitted from
-** UPDATE records.
-** </ul>
-**
+** UPDATE records.
+** </ul>
+**
** A patchset blob may be used with up to date versions of all
** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(),
-** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly,
-** attempting to use a patchset blob with old versions of the
+** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly,
+** attempting to use a patchset blob with old versions of the
** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error.
-**
+**
** Because the non-primary key "old.*" fields are omitted, no
-** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset
-** is passed to the sqlite3changeset_apply() API. Other conflict types work
-** in the same way as for changesets.
-**
-** Changes within a patchset are ordered in the same way as for changesets
-** generated by the sqlite3session_changeset() function (i.e. all changes for
-** a single table are grouped together, tables appear in the order in which
-** they were attached to the session object).
-*/
-SQLITE_API int sqlite3session_patchset(
- sqlite3_session *pSession, /* Session object */
- int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */
- void **ppPatchset /* OUT: Buffer containing patchset */
-);
-
-/*
-** CAPI3REF: Test if a changeset has recorded any changes.
-**
+** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset
+** is passed to the sqlite3changeset_apply() API. Other conflict types work
+** in the same way as for changesets.
+**
+** Changes within a patchset are ordered in the same way as for changesets
+** generated by the sqlite3session_changeset() function (i.e. all changes for
+** a single table are grouped together, tables appear in the order in which
+** they were attached to the session object).
+*/
+SQLITE_API int sqlite3session_patchset(
+ sqlite3_session *pSession, /* Session object */
+ int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */
+ void **ppPatchset /* OUT: Buffer containing patchset */
+);
+
+/*
+** CAPI3REF: Test if a changeset has recorded any changes.
+**
** Return non-zero if no changes to attached tables have been recorded by
** the session object passed as the first argument. Otherwise, if one or
-** more changes have been recorded, return zero.
-**
-** Even if this function returns zero, it is possible that calling
-** [sqlite3session_changeset()] on the session handle may still return a
+** more changes have been recorded, return zero.
+**
+** Even if this function returns zero, it is possible that calling
+** [sqlite3session_changeset()] on the session handle may still return a
** changeset that contains no changes. This can happen when a row in
** an attached table is modified and then later on the original values
-** are restored. However, if this function returns non-zero, then it is
+** are restored. However, if this function returns non-zero, then it is
** guaranteed that a call to sqlite3session_changeset() will return a
-** changeset containing zero changes.
-*/
-SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
-
-/*
+** changeset containing zero changes.
+*/
+SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
+
+/*
** CAPI3REF: Query for the amount of heap memory used by a session object.
**
** This API returns the total amount of heap memory in bytes currently
@@ -10998,36 +10998,36 @@ SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession);
/*
** CAPI3REF: Create An Iterator To Traverse A Changeset
** CONSTRUCTOR: sqlite3_changeset_iter
-**
-** Create an iterator used to iterate through the contents of a changeset.
-** If successful, *pp is set to point to the iterator handle and SQLITE_OK
-** is returned. Otherwise, if an error occurs, *pp is set to zero and an
-** SQLite error code is returned.
-**
+**
+** Create an iterator used to iterate through the contents of a changeset.
+** If successful, *pp is set to point to the iterator handle and SQLITE_OK
+** is returned. Otherwise, if an error occurs, *pp is set to zero and an
+** SQLite error code is returned.
+**
** The following functions can be used to advance and query a changeset
-** iterator created by this function:
-**
-** <ul>
-** <li> [sqlite3changeset_next()]
-** <li> [sqlite3changeset_op()]
-** <li> [sqlite3changeset_new()]
-** <li> [sqlite3changeset_old()]
-** </ul>
-**
-** It is the responsibility of the caller to eventually destroy the iterator
-** by passing it to [sqlite3changeset_finalize()]. The buffer containing the
-** changeset (pChangeset) must remain valid until after the iterator is
-** destroyed.
-**
-** Assuming the changeset blob was created by one of the
-** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
+** iterator created by this function:
+**
+** <ul>
+** <li> [sqlite3changeset_next()]
+** <li> [sqlite3changeset_op()]
+** <li> [sqlite3changeset_new()]
+** <li> [sqlite3changeset_old()]
+** </ul>
+**
+** It is the responsibility of the caller to eventually destroy the iterator
+** by passing it to [sqlite3changeset_finalize()]. The buffer containing the
+** changeset (pChangeset) must remain valid until after the iterator is
+** destroyed.
+**
+** Assuming the changeset blob was created by one of the
+** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
** [sqlite3changeset_invert()] functions, all changes within the changeset
** that apply to a single table are grouped together. This means that when
** an application iterates through a changeset using an iterator created by
** this function, all changes that relate to a single table are visited
** consecutively. There is no chance that the iterator will visit a change
** the applies to table X, then one for table Y, and then later on visit
-** another change for table X.
+** another change for table X.
**
** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
** may be modified by passing a combination of
@@ -11035,19 +11035,19 @@ SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession);
**
** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
** and therefore subject to change.
-*/
-SQLITE_API int sqlite3changeset_start(
- sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
- int nChangeset, /* Size of changeset blob in bytes */
- void *pChangeset /* Pointer to blob containing changeset */
-);
+*/
+SQLITE_API int sqlite3changeset_start(
+ sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
+ int nChangeset, /* Size of changeset blob in bytes */
+ void *pChangeset /* Pointer to blob containing changeset */
+);
SQLITE_API int sqlite3changeset_start_v2(
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
int nChangeset, /* Size of changeset blob in bytes */
void *pChangeset, /* Pointer to blob containing changeset */
int flags /* SESSION_CHANGESETSTART_* flags */
);
-
+
/*
** CAPI3REF: Flags for sqlite3changeset_start_v2
**
@@ -11060,43 +11060,43 @@ SQLITE_API int sqlite3changeset_start_v2(
** It is an error to specify this flag with a patchset.
*/
#define SQLITE_CHANGESETSTART_INVERT 0x0002
-
-/*
-** CAPI3REF: Advance A Changeset Iterator
+
+/*
+** CAPI3REF: Advance A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
+**
** This function may only be used with iterators created by the function
-** [sqlite3changeset_start()]. If it is called on an iterator passed to
-** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
-** is returned and the call has no effect.
-**
-** Immediately after an iterator is created by sqlite3changeset_start(), it
-** does not point to any change in the changeset. Assuming the changeset
-** is not empty, the first call to this function advances the iterator to
-** point to the first change in the changeset. Each subsequent call advances
-** the iterator to point to the next change in the changeset (if any). If
-** no error occurs and the iterator points to a valid change after a call
+** [sqlite3changeset_start()]. If it is called on an iterator passed to
+** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
+** is returned and the call has no effect.
+**
+** Immediately after an iterator is created by sqlite3changeset_start(), it
+** does not point to any change in the changeset. Assuming the changeset
+** is not empty, the first call to this function advances the iterator to
+** point to the first change in the changeset. Each subsequent call advances
+** the iterator to point to the next change in the changeset (if any). If
+** no error occurs and the iterator points to a valid change after a call
** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned.
-** Otherwise, if all changes in the changeset have already been visited,
-** SQLITE_DONE is returned.
-**
+** Otherwise, if all changes in the changeset have already been visited,
+** SQLITE_DONE is returned.
+**
** If an error occurs, an SQLite error code is returned. Possible error
** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or
-** SQLITE_NOMEM.
-*/
-SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
-
-/*
-** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
+** SQLITE_NOMEM.
+*/
+SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
+
+/*
+** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
-** The pIter argument passed to this function may either be an iterator
-** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
-** created by [sqlite3changeset_start()]. In the latter case, the most recent
-** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this
-** is not the case, this function returns [SQLITE_MISUSE].
-**
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this
+** is not the case, this function returns [SQLITE_MISUSE].
+**
** Arguments pOp, pnCol and pzTab may not be NULL. Upon return, three
** outputs are set through these pointers:
**
@@ -11111,566 +11111,566 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
** or until the conflict-handler function returns.
**
** If pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
-** is an indirect change, or false (0) otherwise. See the documentation for
-** [sqlite3session_indirect()] for a description of direct and indirect
+** is an indirect change, or false (0) otherwise. See the documentation for
+** [sqlite3session_indirect()] for a description of direct and indirect
** changes.
-**
-** If no error occurs, SQLITE_OK is returned. If an error does occur, an
-** SQLite error code is returned. The values of the output variables may not
-** be trusted in this case.
-*/
-SQLITE_API int sqlite3changeset_op(
- sqlite3_changeset_iter *pIter, /* Iterator object */
- const char **pzTab, /* OUT: Pointer to table name */
- int *pnCol, /* OUT: Number of columns in table */
- int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */
- int *pbIndirect /* OUT: True for an 'indirect' change */
-);
-
-/*
-** CAPI3REF: Obtain The Primary Key Definition Of A Table
+**
+** If no error occurs, SQLITE_OK is returned. If an error does occur, an
+** SQLite error code is returned. The values of the output variables may not
+** be trusted in this case.
+*/
+SQLITE_API int sqlite3changeset_op(
+ sqlite3_changeset_iter *pIter, /* Iterator object */
+ const char **pzTab, /* OUT: Pointer to table name */
+ int *pnCol, /* OUT: Number of columns in table */
+ int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */
+ int *pbIndirect /* OUT: True for an 'indirect' change */
+);
+
+/*
+** CAPI3REF: Obtain The Primary Key Definition Of A Table
** METHOD: sqlite3_changeset_iter
-**
-** For each modified table, a changeset includes the following:
-**
-** <ul>
-** <li> The number of columns in the table, and
-** <li> Which of those columns make up the tables PRIMARY KEY.
-** </ul>
-**
-** This function is used to find which columns comprise the PRIMARY KEY of
-** the table modified by the change that iterator pIter currently points to.
-** If successful, *pabPK is set to point to an array of nCol entries, where
-** nCol is the number of columns in the table. Elements of *pabPK are set to
-** 0x01 if the corresponding column is part of the tables primary key, or
-** 0x00 if it is not.
-**
-** If argument pnCol is not NULL, then *pnCol is set to the number of columns
-** in the table.
-**
-** If this function is called when the iterator does not point to a valid
-** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
-** SQLITE_OK is returned and the output variables populated as described
-** above.
-*/
-SQLITE_API int sqlite3changeset_pk(
- sqlite3_changeset_iter *pIter, /* Iterator object */
- unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
- int *pnCol /* OUT: Number of entries in output array */
-);
-
-/*
-** CAPI3REF: Obtain old.* Values From A Changeset Iterator
+**
+** For each modified table, a changeset includes the following:
+**
+** <ul>
+** <li> The number of columns in the table, and
+** <li> Which of those columns make up the tables PRIMARY KEY.
+** </ul>
+**
+** This function is used to find which columns comprise the PRIMARY KEY of
+** the table modified by the change that iterator pIter currently points to.
+** If successful, *pabPK is set to point to an array of nCol entries, where
+** nCol is the number of columns in the table. Elements of *pabPK are set to
+** 0x01 if the corresponding column is part of the tables primary key, or
+** 0x00 if it is not.
+**
+** If argument pnCol is not NULL, then *pnCol is set to the number of columns
+** in the table.
+**
+** If this function is called when the iterator does not point to a valid
+** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
+** SQLITE_OK is returned and the output variables populated as described
+** above.
+*/
+SQLITE_API int sqlite3changeset_pk(
+ sqlite3_changeset_iter *pIter, /* Iterator object */
+ unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
+ int *pnCol /* OUT: Number of entries in output array */
+);
+
+/*
+** CAPI3REF: Obtain old.* Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
-** The pIter argument passed to this function may either be an iterator
-** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
-** created by [sqlite3changeset_start()]. In the latter case, the most recent
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
** call to [sqlite3changeset_next()] must have returned SQLITE_ROW.
-** Furthermore, it may only be called if the type of change that the iterator
-** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise,
-** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
-**
-** Argument iVal must be greater than or equal to 0, and less than the number
-** of columns in the table affected by the current change. Otherwise,
-** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
-**
-** If successful, this function sets *ppValue to point to a protected
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise,
+** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
** sqlite3_value object containing the iVal'th value from the vector of
-** original row values stored as part of the UPDATE or DELETE change and
+** original row values stored as part of the UPDATE or DELETE change and
** returns SQLITE_OK. The name of the function comes from the fact that this
-** is similar to the "old.*" columns available to update or delete triggers.
-**
-** If some other error occurs (e.g. an OOM condition), an SQLite error code
-** is returned and *ppValue is set to NULL.
-*/
-SQLITE_API int sqlite3changeset_old(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int iVal, /* Column number */
- sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
-);
-
-/*
-** CAPI3REF: Obtain new.* Values From A Changeset Iterator
+** is similar to the "old.*" columns available to update or delete triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+SQLITE_API int sqlite3changeset_old(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int iVal, /* Column number */
+ sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
+);
+
+/*
+** CAPI3REF: Obtain new.* Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
-** The pIter argument passed to this function may either be an iterator
-** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
-** created by [sqlite3changeset_start()]. In the latter case, the most recent
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
** call to [sqlite3changeset_next()] must have returned SQLITE_ROW.
-** Furthermore, it may only be called if the type of change that the iterator
-** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise,
-** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
-**
-** Argument iVal must be greater than or equal to 0, and less than the number
-** of columns in the table affected by the current change. Otherwise,
-** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
-**
-** If successful, this function sets *ppValue to point to a protected
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise,
+** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
** sqlite3_value object containing the iVal'th value from the vector of
-** new row values stored as part of the UPDATE or INSERT change and
-** returns SQLITE_OK. If the change is an UPDATE and does not include
+** new row values stored as part of the UPDATE or INSERT change and
+** returns SQLITE_OK. If the change is an UPDATE and does not include
** a new value for the requested column, *ppValue is set to NULL and
** SQLITE_OK returned. The name of the function comes from the fact that
** this is similar to the "new.*" columns available to update or delete
-** triggers.
-**
-** If some other error occurs (e.g. an OOM condition), an SQLite error code
-** is returned and *ppValue is set to NULL.
-*/
-SQLITE_API int sqlite3changeset_new(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int iVal, /* Column number */
- sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
-);
-
-/*
-** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
+** triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+SQLITE_API int sqlite3changeset_new(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int iVal, /* Column number */
+ sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
+);
+
+/*
+** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
-** This function should only be used with iterator objects passed to a
-** conflict-handler callback by [sqlite3changeset_apply()] with either
-** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function
-** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue
-** is set to NULL.
-**
-** Argument iVal must be greater than or equal to 0, and less than the number
-** of columns in the table affected by the current change. Otherwise,
-** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
-**
-** If successful, this function sets *ppValue to point to a protected
+**
+** This function should only be used with iterator objects passed to a
+** conflict-handler callback by [sqlite3changeset_apply()] with either
+** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function
+** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue
+** is set to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
** sqlite3_value object containing the iVal'th value from the
-** "conflicting row" associated with the current conflict-handler callback
-** and returns SQLITE_OK.
-**
-** If some other error occurs (e.g. an OOM condition), an SQLite error code
-** is returned and *ppValue is set to NULL.
-*/
-SQLITE_API int sqlite3changeset_conflict(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int iVal, /* Column number */
- sqlite3_value **ppValue /* OUT: Value from conflicting row */
-);
-
-/*
-** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
+** "conflicting row" associated with the current conflict-handler callback
+** and returns SQLITE_OK.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+SQLITE_API int sqlite3changeset_conflict(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int iVal, /* Column number */
+ sqlite3_value **ppValue /* OUT: Value from conflicting row */
+);
+
+/*
+** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
** METHOD: sqlite3_changeset_iter
-**
-** This function may only be called with an iterator passed to an
-** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
-** it sets the output variable to the total number of known foreign key
-** violations in the destination database and returns SQLITE_OK.
-**
-** In all other cases this function returns SQLITE_MISUSE.
-*/
-SQLITE_API int sqlite3changeset_fk_conflicts(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int *pnOut /* OUT: Number of FK violations */
-);
-
-
-/*
-** CAPI3REF: Finalize A Changeset Iterator
+**
+** This function may only be called with an iterator passed to an
+** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
+** it sets the output variable to the total number of known foreign key
+** violations in the destination database and returns SQLITE_OK.
+**
+** In all other cases this function returns SQLITE_MISUSE.
+*/
+SQLITE_API int sqlite3changeset_fk_conflicts(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int *pnOut /* OUT: Number of FK violations */
+);
+
+
+/*
+** CAPI3REF: Finalize A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
-** This function is used to finalize an iterator allocated with
-** [sqlite3changeset_start()].
-**
-** This function should only be called on iterators created using the
-** [sqlite3changeset_start()] function. If an application calls this
-** function with an iterator passed to a conflict-handler by
-** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the
-** call has no effect.
-**
-** If an error was encountered within a call to an sqlite3changeset_xxx()
+**
+** This function is used to finalize an iterator allocated with
+** [sqlite3changeset_start()].
+**
+** This function should only be called on iterators created using the
+** [sqlite3changeset_start()] function. If an application calls this
+** function with an iterator passed to a conflict-handler by
+** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the
+** call has no effect.
+**
+** If an error was encountered within a call to an sqlite3changeset_xxx()
** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an
-** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding
-** to that error is returned by this function. Otherwise, SQLITE_OK is
-** returned. This is to allow the following pattern (pseudo-code):
-**
+** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding
+** to that error is returned by this function. Otherwise, SQLITE_OK is
+** returned. This is to allow the following pattern (pseudo-code):
+**
** <pre>
-** sqlite3changeset_start();
-** while( SQLITE_ROW==sqlite3changeset_next() ){
-** // Do something with change.
-** }
-** rc = sqlite3changeset_finalize();
-** if( rc!=SQLITE_OK ){
+** sqlite3changeset_start();
+** while( SQLITE_ROW==sqlite3changeset_next() ){
+** // Do something with change.
+** }
+** rc = sqlite3changeset_finalize();
+** if( rc!=SQLITE_OK ){
** // An error has occurred
-** }
+** }
** </pre>
-*/
-SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
-
-/*
-** CAPI3REF: Invert A Changeset
-**
-** This function is used to "invert" a changeset object. Applying an inverted
-** changeset to a database reverses the effects of applying the uninverted
-** changeset. Specifically:
-**
-** <ul>
-** <li> Each DELETE change is changed to an INSERT, and
-** <li> Each INSERT change is changed to a DELETE, and
-** <li> For each UPDATE change, the old.* and new.* values are exchanged.
-** </ul>
-**
-** This function does not change the order in which changes appear within
-** the changeset. It merely reverses the sense of each individual change.
-**
-** If successful, a pointer to a buffer containing the inverted changeset
-** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and
-** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are
-** zeroed and an SQLite error code returned.
-**
-** It is the responsibility of the caller to eventually call sqlite3_free()
+*/
+SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
+
+/*
+** CAPI3REF: Invert A Changeset
+**
+** This function is used to "invert" a changeset object. Applying an inverted
+** changeset to a database reverses the effects of applying the uninverted
+** changeset. Specifically:
+**
+** <ul>
+** <li> Each DELETE change is changed to an INSERT, and
+** <li> Each INSERT change is changed to a DELETE, and
+** <li> For each UPDATE change, the old.* and new.* values are exchanged.
+** </ul>
+**
+** This function does not change the order in which changes appear within
+** the changeset. It merely reverses the sense of each individual change.
+**
+** If successful, a pointer to a buffer containing the inverted changeset
+** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and
+** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are
+** zeroed and an SQLite error code returned.
+**
+** It is the responsibility of the caller to eventually call sqlite3_free()
** on the *ppOut pointer to free the buffer allocation following a successful
-** call to this function.
-**
-** WARNING/TODO: This function currently assumes that the input is a valid
-** changeset. If it is not, the results are undefined.
-*/
-SQLITE_API int sqlite3changeset_invert(
- int nIn, const void *pIn, /* Input changeset */
- int *pnOut, void **ppOut /* OUT: Inverse of input */
-);
-
-/*
-** CAPI3REF: Concatenate Two Changeset Objects
-**
+** call to this function.
+**
+** WARNING/TODO: This function currently assumes that the input is a valid
+** changeset. If it is not, the results are undefined.
+*/
+SQLITE_API int sqlite3changeset_invert(
+ int nIn, const void *pIn, /* Input changeset */
+ int *pnOut, void **ppOut /* OUT: Inverse of input */
+);
+
+/*
+** CAPI3REF: Concatenate Two Changeset Objects
+**
** This function is used to concatenate two changesets, A and B, into a
-** single changeset. The result is a changeset equivalent to applying
+** single changeset. The result is a changeset equivalent to applying
** changeset A followed by changeset B.
-**
+**
** This function combines the two input changesets using an
-** sqlite3_changegroup object. Calling it produces similar results as the
-** following code fragment:
-**
+** sqlite3_changegroup object. Calling it produces similar results as the
+** following code fragment:
+**
** <pre>
-** sqlite3_changegroup *pGrp;
-** rc = sqlite3_changegroup_new(&pGrp);
-** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
-** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
-** if( rc==SQLITE_OK ){
-** rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
-** }else{
-** *ppOut = 0;
-** *pnOut = 0;
-** }
+** sqlite3_changegroup *pGrp;
+** rc = sqlite3_changegroup_new(&pGrp);
+** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
+** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
+** if( rc==SQLITE_OK ){
+** rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
+** }else{
+** *ppOut = 0;
+** *pnOut = 0;
+** }
** </pre>
-**
-** Refer to the sqlite3_changegroup documentation below for details.
-*/
-SQLITE_API int sqlite3changeset_concat(
- int nA, /* Number of bytes in buffer pA */
- void *pA, /* Pointer to buffer containing changeset A */
- int nB, /* Number of bytes in buffer pB */
- void *pB, /* Pointer to buffer containing changeset B */
- int *pnOut, /* OUT: Number of bytes in output changeset */
- void **ppOut /* OUT: Buffer containing output changeset */
-);
-
-
-/*
-** CAPI3REF: Changegroup Handle
+**
+** Refer to the sqlite3_changegroup documentation below for details.
+*/
+SQLITE_API int sqlite3changeset_concat(
+ int nA, /* Number of bytes in buffer pA */
+ void *pA, /* Pointer to buffer containing changeset A */
+ int nB, /* Number of bytes in buffer pB */
+ void *pB, /* Pointer to buffer containing changeset B */
+ int *pnOut, /* OUT: Number of bytes in output changeset */
+ void **ppOut /* OUT: Buffer containing output changeset */
+);
+
+
+/*
+** CAPI3REF: Changegroup Handle
**
** A changegroup is an object used to combine two or more
** [changesets] or [patchsets]
-*/
-typedef struct sqlite3_changegroup sqlite3_changegroup;
-
-/*
-** CAPI3REF: Create A New Changegroup Object
+*/
+typedef struct sqlite3_changegroup sqlite3_changegroup;
+
+/*
+** CAPI3REF: Create A New Changegroup Object
** CONSTRUCTOR: sqlite3_changegroup
-**
-** An sqlite3_changegroup object is used to combine two or more changesets
-** (or patchsets) into a single changeset (or patchset). A single changegroup
-** object may combine changesets or patchsets, but not both. The output is
-** always in the same format as the input.
-**
-** If successful, this function returns SQLITE_OK and populates (*pp) with
-** a pointer to a new sqlite3_changegroup object before returning. The caller
+**
+** An sqlite3_changegroup object is used to combine two or more changesets
+** (or patchsets) into a single changeset (or patchset). A single changegroup
+** object may combine changesets or patchsets, but not both. The output is
+** always in the same format as the input.
+**
+** If successful, this function returns SQLITE_OK and populates (*pp) with
+** a pointer to a new sqlite3_changegroup object before returning. The caller
** should eventually free the returned object using a call to
-** sqlite3changegroup_delete(). If an error occurs, an SQLite error code
-** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL.
-**
-** The usual usage pattern for an sqlite3_changegroup object is as follows:
-**
-** <ul>
-** <li> It is created using a call to sqlite3changegroup_new().
-**
-** <li> Zero or more changesets (or patchsets) are added to the object
-** by calling sqlite3changegroup_add().
-**
+** sqlite3changegroup_delete(). If an error occurs, an SQLite error code
+** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL.
+**
+** The usual usage pattern for an sqlite3_changegroup object is as follows:
+**
+** <ul>
+** <li> It is created using a call to sqlite3changegroup_new().
+**
+** <li> Zero or more changesets (or patchsets) are added to the object
+** by calling sqlite3changegroup_add().
+**
** <li> The result of combining all input changesets together is obtained
-** by the application via a call to sqlite3changegroup_output().
-**
-** <li> The object is deleted using a call to sqlite3changegroup_delete().
-** </ul>
-**
-** Any number of calls to add() and output() may be made between the calls to
-** new() and delete(), and in any order.
-**
+** by the application via a call to sqlite3changegroup_output().
+**
+** <li> The object is deleted using a call to sqlite3changegroup_delete().
+** </ul>
+**
+** Any number of calls to add() and output() may be made between the calls to
+** new() and delete(), and in any order.
+**
** As well as the regular sqlite3changegroup_add() and
-** sqlite3changegroup_output() functions, also available are the streaming
-** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
-*/
-SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
-
-/*
-** CAPI3REF: Add A Changeset To A Changegroup
+** sqlite3changegroup_output() functions, also available are the streaming
+** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
+*/
+SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
+
+/*
+** CAPI3REF: Add A Changeset To A Changegroup
** METHOD: sqlite3_changegroup
-**
-** Add all changes within the changeset (or patchset) in buffer pData (size
+**
+** Add all changes within the changeset (or patchset) in buffer pData (size
** nData bytes) to the changegroup.
-**
-** If the buffer contains a patchset, then all prior calls to this function
-** on the same changegroup object must also have specified patchsets. Or, if
-** the buffer contains a changeset, so must have the earlier calls to this
-** function. Otherwise, SQLITE_ERROR is returned and no changes are added
-** to the changegroup.
-**
-** Rows within the changeset and changegroup are identified by the values in
-** their PRIMARY KEY columns. A change in the changeset is considered to
-** apply to the same row as a change already present in the changegroup if
-** the two rows have the same primary key.
-**
-** Changes to rows that do not already appear in the changegroup are
-** simply copied into it. Or, if both the new changeset and the changegroup
-** contain changes that apply to a single row, the final contents of the
-** changegroup depends on the type of each change, as follows:
-**
-** <table border=1 style="margin-left:8ex;margin-right:8ex">
-** <tr><th style="white-space:pre">Existing Change </th>
-** <th style="white-space:pre">New Change </th>
-** <th>Output Change
-** <tr><td>INSERT <td>INSERT <td>
-** The new change is ignored. This case does not occur if the new
-** changeset was recorded immediately after the changesets already
-** added to the changegroup.
-** <tr><td>INSERT <td>UPDATE <td>
+**
+** If the buffer contains a patchset, then all prior calls to this function
+** on the same changegroup object must also have specified patchsets. Or, if
+** the buffer contains a changeset, so must have the earlier calls to this
+** function. Otherwise, SQLITE_ERROR is returned and no changes are added
+** to the changegroup.
+**
+** Rows within the changeset and changegroup are identified by the values in
+** their PRIMARY KEY columns. A change in the changeset is considered to
+** apply to the same row as a change already present in the changegroup if
+** the two rows have the same primary key.
+**
+** Changes to rows that do not already appear in the changegroup are
+** simply copied into it. Or, if both the new changeset and the changegroup
+** contain changes that apply to a single row, the final contents of the
+** changegroup depends on the type of each change, as follows:
+**
+** <table border=1 style="margin-left:8ex;margin-right:8ex">
+** <tr><th style="white-space:pre">Existing Change </th>
+** <th style="white-space:pre">New Change </th>
+** <th>Output Change
+** <tr><td>INSERT <td>INSERT <td>
+** The new change is ignored. This case does not occur if the new
+** changeset was recorded immediately after the changesets already
+** added to the changegroup.
+** <tr><td>INSERT <td>UPDATE <td>
** The INSERT change remains in the changegroup. The values in the
-** INSERT change are modified as if the row was inserted by the
-** existing change and then updated according to the new change.
-** <tr><td>INSERT <td>DELETE <td>
-** The existing INSERT is removed from the changegroup. The DELETE is
-** not added.
-** <tr><td>UPDATE <td>INSERT <td>
-** The new change is ignored. This case does not occur if the new
-** changeset was recorded immediately after the changesets already
-** added to the changegroup.
-** <tr><td>UPDATE <td>UPDATE <td>
+** INSERT change are modified as if the row was inserted by the
+** existing change and then updated according to the new change.
+** <tr><td>INSERT <td>DELETE <td>
+** The existing INSERT is removed from the changegroup. The DELETE is
+** not added.
+** <tr><td>UPDATE <td>INSERT <td>
+** The new change is ignored. This case does not occur if the new
+** changeset was recorded immediately after the changesets already
+** added to the changegroup.
+** <tr><td>UPDATE <td>UPDATE <td>
** The existing UPDATE remains within the changegroup. It is amended
** so that the accompanying values are as if the row was updated once
-** by the existing change and then again by the new change.
-** <tr><td>UPDATE <td>DELETE <td>
-** The existing UPDATE is replaced by the new DELETE within the
-** changegroup.
-** <tr><td>DELETE <td>INSERT <td>
-** If one or more of the column values in the row inserted by the
+** by the existing change and then again by the new change.
+** <tr><td>UPDATE <td>DELETE <td>
+** The existing UPDATE is replaced by the new DELETE within the
+** changegroup.
+** <tr><td>DELETE <td>INSERT <td>
+** If one or more of the column values in the row inserted by the
** new change differ from those in the row deleted by the existing
-** change, the existing DELETE is replaced by an UPDATE within the
+** change, the existing DELETE is replaced by an UPDATE within the
** changegroup. Otherwise, if the inserted row is exactly the same
-** as the deleted row, the existing DELETE is simply discarded.
-** <tr><td>DELETE <td>UPDATE <td>
-** The new change is ignored. This case does not occur if the new
-** changeset was recorded immediately after the changesets already
-** added to the changegroup.
-** <tr><td>DELETE <td>DELETE <td>
-** The new change is ignored. This case does not occur if the new
-** changeset was recorded immediately after the changesets already
-** added to the changegroup.
-** </table>
-**
-** If the new changeset contains changes to a table that is already present
-** in the changegroup, then the number of columns and the position of the
-** primary key columns for the table must be consistent. If this is not the
-** case, this function fails with SQLITE_SCHEMA. If the input changeset
-** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
-** returned. Or, if an out-of-memory condition occurs during processing, this
+** as the deleted row, the existing DELETE is simply discarded.
+** <tr><td>DELETE <td>UPDATE <td>
+** The new change is ignored. This case does not occur if the new
+** changeset was recorded immediately after the changesets already
+** added to the changegroup.
+** <tr><td>DELETE <td>DELETE <td>
+** The new change is ignored. This case does not occur if the new
+** changeset was recorded immediately after the changesets already
+** added to the changegroup.
+** </table>
+**
+** If the new changeset contains changes to a table that is already present
+** in the changegroup, then the number of columns and the position of the
+** primary key columns for the table must be consistent. If this is not the
+** case, this function fails with SQLITE_SCHEMA. If the input changeset
+** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
+** returned. Or, if an out-of-memory condition occurs during processing, this
** function returns SQLITE_NOMEM. In all cases, if an error occurs the state
** of the final contents of the changegroup is undefined.
-**
-** If no error occurs, SQLITE_OK is returned.
-*/
-SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
-
-/*
-** CAPI3REF: Obtain A Composite Changeset From A Changegroup
+**
+** If no error occurs, SQLITE_OK is returned.
+*/
+SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+
+/*
+** CAPI3REF: Obtain A Composite Changeset From A Changegroup
** METHOD: sqlite3_changegroup
-**
-** Obtain a buffer containing a changeset (or patchset) representing the
-** current contents of the changegroup. If the inputs to the changegroup
-** were themselves changesets, the output is a changeset. Or, if the
-** inputs were patchsets, the output is also a patchset.
-**
-** As with the output of the sqlite3session_changeset() and
-** sqlite3session_patchset() functions, all changes related to a single
-** table are grouped together in the output of this function. Tables appear
-** in the same order as for the very first changeset added to the changegroup.
-** If the second or subsequent changesets added to the changegroup contain
-** changes for tables that do not appear in the first changeset, they are
-** appended onto the end of the output changeset, again in the order in
-** which they are first encountered.
-**
-** If an error occurs, an SQLite error code is returned and the output
-** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK
+**
+** Obtain a buffer containing a changeset (or patchset) representing the
+** current contents of the changegroup. If the inputs to the changegroup
+** were themselves changesets, the output is a changeset. Or, if the
+** inputs were patchsets, the output is also a patchset.
+**
+** As with the output of the sqlite3session_changeset() and
+** sqlite3session_patchset() functions, all changes related to a single
+** table are grouped together in the output of this function. Tables appear
+** in the same order as for the very first changeset added to the changegroup.
+** If the second or subsequent changesets added to the changegroup contain
+** changes for tables that do not appear in the first changeset, they are
+** appended onto the end of the output changeset, again in the order in
+** which they are first encountered.
+**
+** If an error occurs, an SQLite error code is returned and the output
+** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK
** is returned and the output variables are set to the size of and a
-** pointer to the output buffer, respectively. In this case it is the
-** responsibility of the caller to eventually free the buffer using a
-** call to sqlite3_free().
-*/
-SQLITE_API int sqlite3changegroup_output(
- sqlite3_changegroup*,
- int *pnData, /* OUT: Size of output buffer in bytes */
- void **ppData /* OUT: Pointer to output buffer */
-);
-
-/*
-** CAPI3REF: Delete A Changegroup Object
+** pointer to the output buffer, respectively. In this case it is the
+** responsibility of the caller to eventually free the buffer using a
+** call to sqlite3_free().
+*/
+SQLITE_API int sqlite3changegroup_output(
+ sqlite3_changegroup*,
+ int *pnData, /* OUT: Size of output buffer in bytes */
+ void **ppData /* OUT: Pointer to output buffer */
+);
+
+/*
+** CAPI3REF: Delete A Changegroup Object
** DESTRUCTOR: sqlite3_changegroup
-*/
-SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
-
-/*
-** CAPI3REF: Apply A Changeset To A Database
-**
+*/
+SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
+
+/*
+** CAPI3REF: Apply A Changeset To A Database
+**
** Apply a changeset or patchset to a database. These functions attempt to
** update the "main" database attached to handle db with the changes found in
** the changeset passed via the second and third arguments.
-**
+**
** The fourth argument (xFilter) passed to these functions is the "filter
-** callback". If it is not NULL, then for each table affected by at least one
-** change in the changeset, the filter callback is invoked with
-** the table name as the second argument, and a copy of the context pointer
+** callback". If it is not NULL, then for each table affected by at least one
+** change in the changeset, the filter callback is invoked with
+** the table name as the second argument, and a copy of the context pointer
** passed as the sixth argument as the first. If the "filter callback"
** returns zero, then no attempt is made to apply any changes to the table.
** Otherwise, if the return value is non-zero or the xFilter argument to
** is NULL, all changes related to the table are attempted.
-**
+**
** For each table that is not excluded by the filter callback, this function
** tests that the target database contains a compatible table. A table is
-** considered compatible if all of the following are true:
-**
-** <ul>
+** considered compatible if all of the following are true:
+**
+** <ul>
** <li> The table has the same name as the name recorded in the
-** changeset, and
+** changeset, and
** <li> The table has at least as many columns as recorded in the
-** changeset, and
+** changeset, and
** <li> The table has primary key columns in the same position as
-** recorded in the changeset.
-** </ul>
-**
-** If there is no compatible table, it is not an error, but none of the
-** changes associated with the table are applied. A warning message is issued
-** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most
-** one such warning is issued for each table in the changeset.
-**
+** recorded in the changeset.
+** </ul>
+**
+** If there is no compatible table, it is not an error, but none of the
+** changes associated with the table are applied. A warning message is issued
+** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most
+** one such warning is issued for each table in the changeset.
+**
** For each change for which there is a compatible table, an attempt is made
** to modify the table contents according to the UPDATE, INSERT or DELETE
** change. If a change cannot be applied cleanly, the conflict handler
** function passed as the fifth argument to sqlite3changeset_apply() may be
** invoked. A description of exactly when the conflict handler is invoked for
-** each type of change is below.
-**
-** Unlike the xFilter argument, xConflict may not be passed NULL. The results
-** of passing anything other than a valid function pointer as the xConflict
-** argument are undefined.
-**
-** Each time the conflict handler function is invoked, it must return one
+** each type of change is below.
+**
+** Unlike the xFilter argument, xConflict may not be passed NULL. The results
+** of passing anything other than a valid function pointer as the xConflict
+** argument are undefined.
+**
+** Each time the conflict handler function is invoked, it must return one
** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or
-** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned
-** if the second argument passed to the conflict handler is either
-** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler
-** returns an illegal value, any changes already made are rolled back and
+** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned
+** if the second argument passed to the conflict handler is either
+** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler
+** returns an illegal value, any changes already made are rolled back and
** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different
-** actions are taken by sqlite3changeset_apply() depending on the value
-** returned by each invocation of the conflict-handler function. Refer to
+** actions are taken by sqlite3changeset_apply() depending on the value
+** returned by each invocation of the conflict-handler function. Refer to
** the documentation for the three
-** [SQLITE_CHANGESET_OMIT|available return values] for details.
-**
-** <dl>
-** <dt>DELETE Changes<dd>
+** [SQLITE_CHANGESET_OMIT|available return values] for details.
+**
+** <dl>
+** <dt>DELETE Changes<dd>
** For each DELETE change, the function checks if the target database
** contains a row with the same primary key value (or values) as the
** original row values stored in the changeset. If it does, and the values
** stored in all non-primary key columns also match the values stored in
-** the changeset the row is deleted from the target database.
-**
-** If a row with matching primary key values is found, but one or more of
-** the non-primary key fields contains a value different from the original
-** row value stored in the changeset, the conflict-handler function is
-** invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the
-** database table has more columns than are recorded in the changeset,
-** only the values of those non-primary key fields are compared against
-** the current database contents - any trailing database table columns
-** are ignored.
-**
-** If no row with matching primary key values is found in the database,
-** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
-** passed as the second argument.
-**
-** If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT
-** (which can only happen if a foreign key constraint is violated), the
-** conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT]
-** passed as the second argument. This includes the case where the DELETE
-** operation is attempted because an earlier call to the conflict handler
-** function returned [SQLITE_CHANGESET_REPLACE].
-**
-** <dt>INSERT Changes<dd>
-** For each INSERT change, an attempt is made to insert the new row into
-** the database. If the changeset row contains fewer fields than the
-** database table, the trailing fields are populated with their default
-** values.
-**
+** the changeset the row is deleted from the target database.
+**
+** If a row with matching primary key values is found, but one or more of
+** the non-primary key fields contains a value different from the original
+** row value stored in the changeset, the conflict-handler function is
+** invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the
+** database table has more columns than are recorded in the changeset,
+** only the values of those non-primary key fields are compared against
+** the current database contents - any trailing database table columns
+** are ignored.
+**
+** If no row with matching primary key values is found in the database,
+** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
+** passed as the second argument.
+**
+** If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT
+** (which can only happen if a foreign key constraint is violated), the
+** conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT]
+** passed as the second argument. This includes the case where the DELETE
+** operation is attempted because an earlier call to the conflict handler
+** function returned [SQLITE_CHANGESET_REPLACE].
+**
+** <dt>INSERT Changes<dd>
+** For each INSERT change, an attempt is made to insert the new row into
+** the database. If the changeset row contains fewer fields than the
+** database table, the trailing fields are populated with their default
+** values.
+**
** If the attempt to insert the row fails because the database already
-** contains a row with the same primary key values, the conflict handler
+** contains a row with the same primary key values, the conflict handler
** function is invoked with the second argument set to
-** [SQLITE_CHANGESET_CONFLICT].
-**
-** If the attempt to insert the row fails because of some other constraint
+** [SQLITE_CHANGESET_CONFLICT].
+**
+** If the attempt to insert the row fails because of some other constraint
** violation (e.g. NOT NULL or UNIQUE), the conflict handler function is
-** invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT].
+** invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT].
** This includes the case where the INSERT operation is re-attempted because
** an earlier call to the conflict handler function returned
-** [SQLITE_CHANGESET_REPLACE].
-**
-** <dt>UPDATE Changes<dd>
+** [SQLITE_CHANGESET_REPLACE].
+**
+** <dt>UPDATE Changes<dd>
** For each UPDATE change, the function checks if the target database
** contains a row with the same primary key value (or values) as the
** original row values stored in the changeset. If it does, and the values
-** stored in all modified non-primary key columns also match the values
-** stored in the changeset the row is updated within the target database.
-**
-** If a row with matching primary key values is found, but one or more of
-** the modified non-primary key fields contains a value different from an
-** original row value stored in the changeset, the conflict-handler function
-** is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
-** UPDATE changes only contain values for non-primary key fields that are
-** to be modified, only those fields need to match the original values to
-** avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
-**
-** If no row with matching primary key values is found in the database,
-** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
-** passed as the second argument.
-**
+** stored in all modified non-primary key columns also match the values
+** stored in the changeset the row is updated within the target database.
+**
+** If a row with matching primary key values is found, but one or more of
+** the modified non-primary key fields contains a value different from an
+** original row value stored in the changeset, the conflict-handler function
+** is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
+** UPDATE changes only contain values for non-primary key fields that are
+** to be modified, only those fields need to match the original values to
+** avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
+**
+** If no row with matching primary key values is found in the database,
+** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
+** passed as the second argument.
+**
** If the UPDATE operation is attempted, but SQLite returns
** SQLITE_CONSTRAINT, the conflict-handler function is invoked with
-** [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument.
+** [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument.
** This includes the case where the UPDATE operation is attempted after
-** an earlier call to the conflict handler function returned
+** an earlier call to the conflict handler function returned
** [SQLITE_CHANGESET_REPLACE].
-** </dl>
-**
-** It is safe to execute SQL statements, including those that write to the
-** table that the callback related to, from within the xConflict callback.
+** </dl>
+**
+** It is safe to execute SQL statements, including those that write to the
+** table that the callback related to, from within the xConflict callback.
** This can be used to further customize the application's conflict
-** resolution strategy.
-**
+** resolution strategy.
+**
** All changes made by these functions are enclosed in a savepoint transaction.
-** If any other error (aside from a constraint failure when attempting to
-** write to the target database) occurs, then the savepoint transaction is
+** If any other error (aside from a constraint failure when attempting to
+** write to the target database) occurs, then the savepoint transaction is
** rolled back, restoring the target database to its original state, and an
-** SQLite error code returned.
+** SQLite error code returned.
**
** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
@@ -11688,22 +11688,22 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
**
** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b>
** and therefore subject to change.
-*/
-SQLITE_API int sqlite3changeset_apply(
- sqlite3 *db, /* Apply change to "main" db of this handle */
- int nChangeset, /* Size of changeset in bytes */
- void *pChangeset, /* Changeset blob */
- int(*xFilter)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- const char *zTab /* Table name */
- ),
- int(*xConflict)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
- sqlite3_changeset_iter *p /* Handle describing change and conflict */
- ),
- void *pCtx /* First argument passed to xConflict */
-);
+*/
+SQLITE_API int sqlite3changeset_apply(
+ sqlite3 *db, /* Apply change to "main" db of this handle */
+ int nChangeset, /* Size of changeset in bytes */
+ void *pChangeset, /* Changeset blob */
+ int(*xFilter)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ const char *zTab /* Table name */
+ ),
+ int(*xConflict)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
+ sqlite3_changeset_iter *p /* Handle describing change and conflict */
+ ),
+ void *pCtx /* First argument passed to xConflict */
+);
SQLITE_API int sqlite3changeset_apply_v2(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
@@ -11721,7 +11721,7 @@ SQLITE_API int sqlite3changeset_apply_v2(
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
int flags /* SESSION_CHANGESETAPPLY_* flags */
);
-
+
/*
** CAPI3REF: Flags for sqlite3changeset_apply_v2
**
@@ -11747,101 +11747,101 @@ SQLITE_API int sqlite3changeset_apply_v2(
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
/*
-** CAPI3REF: Constants Passed To The Conflict Handler
-**
-** Values that may be passed as the second argument to a conflict-handler.
-**
-** <dl>
-** <dt>SQLITE_CHANGESET_DATA<dd>
-** The conflict handler is invoked with CHANGESET_DATA as the second argument
-** when processing a DELETE or UPDATE change if a row with the required
+** CAPI3REF: Constants Passed To The Conflict Handler
+**
+** Values that may be passed as the second argument to a conflict-handler.
+**
+** <dl>
+** <dt>SQLITE_CHANGESET_DATA<dd>
+** The conflict handler is invoked with CHANGESET_DATA as the second argument
+** when processing a DELETE or UPDATE change if a row with the required
** PRIMARY KEY fields is present in the database, but one or more other
** (non primary-key) fields modified by the update do not contain the
-** expected "before" values.
+** expected "before" values.
**
-** The conflicting row, in this case, is the database row with the matching
-** primary key.
+** The conflicting row, in this case, is the database row with the matching
+** primary key.
**
-** <dt>SQLITE_CHANGESET_NOTFOUND<dd>
-** The conflict handler is invoked with CHANGESET_NOTFOUND as the second
-** argument when processing a DELETE or UPDATE change if a row with the
-** required PRIMARY KEY fields is not present in the database.
+** <dt>SQLITE_CHANGESET_NOTFOUND<dd>
+** The conflict handler is invoked with CHANGESET_NOTFOUND as the second
+** argument when processing a DELETE or UPDATE change if a row with the
+** required PRIMARY KEY fields is not present in the database.
**
-** There is no conflicting row in this case. The results of invoking the
-** sqlite3changeset_conflict() API are undefined.
+** There is no conflicting row in this case. The results of invoking the
+** sqlite3changeset_conflict() API are undefined.
**
-** <dt>SQLITE_CHANGESET_CONFLICT<dd>
-** CHANGESET_CONFLICT is passed as the second argument to the conflict
+** <dt>SQLITE_CHANGESET_CONFLICT<dd>
+** CHANGESET_CONFLICT is passed as the second argument to the conflict
** handler while processing an INSERT change if the operation would result
-** in duplicate primary key values.
+** in duplicate primary key values.
**
-** The conflicting row in this case is the database row with the matching
-** primary key.
-**
-** <dt>SQLITE_CHANGESET_FOREIGN_KEY<dd>
-** If foreign key handling is enabled, and applying a changeset leaves the
+** The conflicting row in this case is the database row with the matching
+** primary key.
+**
+** <dt>SQLITE_CHANGESET_FOREIGN_KEY<dd>
+** If foreign key handling is enabled, and applying a changeset leaves the
** database in a state containing foreign key violations, the conflict
-** handler is invoked with CHANGESET_FOREIGN_KEY as the second argument
-** exactly once before the changeset is committed. If the conflict handler
-** returns CHANGESET_OMIT, the changes, including those that caused the
-** foreign key constraint violation, are committed. Or, if it returns
-** CHANGESET_ABORT, the changeset is rolled back.
-**
-** No current or conflicting row information is provided. The only function
-** it is possible to call on the supplied sqlite3_changeset_iter handle
-** is sqlite3changeset_fk_conflicts().
-**
-** <dt>SQLITE_CHANGESET_CONSTRAINT<dd>
+** handler is invoked with CHANGESET_FOREIGN_KEY as the second argument
+** exactly once before the changeset is committed. If the conflict handler
+** returns CHANGESET_OMIT, the changes, including those that caused the
+** foreign key constraint violation, are committed. Or, if it returns
+** CHANGESET_ABORT, the changeset is rolled back.
+**
+** No current or conflicting row information is provided. The only function
+** it is possible to call on the supplied sqlite3_changeset_iter handle
+** is sqlite3changeset_fk_conflicts().
+**
+** <dt>SQLITE_CHANGESET_CONSTRAINT<dd>
** If any other constraint violation occurs while applying a change (i.e.
** a UNIQUE, CHECK or NOT NULL constraint), the conflict handler is
-** invoked with CHANGESET_CONSTRAINT as the second argument.
-**
-** There is no conflicting row in this case. The results of invoking the
-** sqlite3changeset_conflict() API are undefined.
-**
-** </dl>
-*/
-#define SQLITE_CHANGESET_DATA 1
-#define SQLITE_CHANGESET_NOTFOUND 2
-#define SQLITE_CHANGESET_CONFLICT 3
-#define SQLITE_CHANGESET_CONSTRAINT 4
-#define SQLITE_CHANGESET_FOREIGN_KEY 5
-
-/*
-** CAPI3REF: Constants Returned By The Conflict Handler
-**
-** A conflict handler callback must return one of the following three values.
-**
-** <dl>
-** <dt>SQLITE_CHANGESET_OMIT<dd>
-** If a conflict handler returns this value no special action is taken. The
+** invoked with CHANGESET_CONSTRAINT as the second argument.
+**
+** There is no conflicting row in this case. The results of invoking the
+** sqlite3changeset_conflict() API are undefined.
+**
+** </dl>
+*/
+#define SQLITE_CHANGESET_DATA 1
+#define SQLITE_CHANGESET_NOTFOUND 2
+#define SQLITE_CHANGESET_CONFLICT 3
+#define SQLITE_CHANGESET_CONSTRAINT 4
+#define SQLITE_CHANGESET_FOREIGN_KEY 5
+
+/*
+** CAPI3REF: Constants Returned By The Conflict Handler
+**
+** A conflict handler callback must return one of the following three values.
+**
+** <dl>
+** <dt>SQLITE_CHANGESET_OMIT<dd>
+** If a conflict handler returns this value no special action is taken. The
** change that caused the conflict is not applied. The session module
-** continues to the next change in the changeset.
-**
-** <dt>SQLITE_CHANGESET_REPLACE<dd>
-** This value may only be returned if the second argument to the conflict
-** handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this
+** continues to the next change in the changeset.
+**
+** <dt>SQLITE_CHANGESET_REPLACE<dd>
+** This value may only be returned if the second argument to the conflict
+** handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this
** is not the case, any changes applied so far are rolled back and the
-** call to sqlite3changeset_apply() returns SQLITE_MISUSE.
-**
-** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict
-** handler, then the conflicting row is either updated or deleted, depending
-** on the type of change.
-**
-** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict
-** handler, then the conflicting row is removed from the database and a
-** second attempt to apply the change is made. If this second attempt fails,
-** the original row is restored to the database before continuing.
-**
-** <dt>SQLITE_CHANGESET_ABORT<dd>
+** call to sqlite3changeset_apply() returns SQLITE_MISUSE.
+**
+** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict
+** handler, then the conflicting row is either updated or deleted, depending
+** on the type of change.
+**
+** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict
+** handler, then the conflicting row is removed from the database and a
+** second attempt to apply the change is made. If this second attempt fails,
+** the original row is restored to the database before continuing.
+**
+** <dt>SQLITE_CHANGESET_ABORT<dd>
** If this value is returned, any changes applied so far are rolled back
-** and the call to sqlite3changeset_apply() returns SQLITE_ABORT.
-** </dl>
-*/
-#define SQLITE_CHANGESET_OMIT 0
-#define SQLITE_CHANGESET_REPLACE 1
-#define SQLITE_CHANGESET_ABORT 2
-
+** and the call to sqlite3changeset_apply() returns SQLITE_ABORT.
+** </dl>
+*/
+#define SQLITE_CHANGESET_OMIT 0
+#define SQLITE_CHANGESET_REPLACE 1
+#define SQLITE_CHANGESET_ABORT 2
+
/*
** CAPI3REF: Rebasing changesets
** EXPERIMENTAL
@@ -11942,7 +11942,7 @@ SQLITE_API int sqlite3changeset_apply_v2(
*/
typedef struct sqlite3_rebaser sqlite3_rebaser;
-/*
+/*
** CAPI3REF: Create a changeset rebaser object.
** EXPERIMENTAL
**
@@ -11998,13 +11998,13 @@ SQLITE_API int sqlite3rebaser_rebase(
SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p);
/*
-** CAPI3REF: Streaming Versions of API functions.
-**
+** CAPI3REF: Streaming Versions of API functions.
+**
** The six streaming API xxx_strm() functions serve similar purposes to the
-** corresponding non-streaming API functions:
-**
-** <table border=1 style="margin-left:8ex;margin-right:8ex">
-** <tr><th>Streaming function<th>Non-streaming equivalent</th>
+** corresponding non-streaming API functions:
+**
+** <table border=1 style="margin-left:8ex;margin-right:8ex">
+** <tr><th>Streaming function<th>Non-streaming equivalent</th>
** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply]
** <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2]
** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat]
@@ -12012,96 +12012,96 @@ SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p);
** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start]
** <tr><td>sqlite3session_changeset_strm<td>[sqlite3session_changeset]
** <tr><td>sqlite3session_patchset_strm<td>[sqlite3session_patchset]
-** </table>
-**
-** Non-streaming functions that accept changesets (or patchsets) as input
+** </table>
+**
+** Non-streaming functions that accept changesets (or patchsets) as input
** require that the entire changeset be stored in a single buffer in memory.
** Similarly, those that return a changeset or patchset do so by returning
** a pointer to a single large buffer allocated using sqlite3_malloc().
** Normally this is convenient. However, if an application running in a
-** low-memory environment is required to handle very large changesets, the
-** large contiguous memory allocations required can become onerous.
-**
-** In order to avoid this problem, instead of a single large buffer, input
-** is passed to a streaming API functions by way of a callback function that
-** the sessions module invokes to incrementally request input data as it is
-** required. In all cases, a pair of API function parameters such as
-**
-** <pre>
-** &nbsp; int nChangeset,
-** &nbsp; void *pChangeset,
-** </pre>
-**
-** Is replaced by:
-**
-** <pre>
-** &nbsp; int (*xInput)(void *pIn, void *pData, int *pnData),
-** &nbsp; void *pIn,
-** </pre>
-**
-** Each time the xInput callback is invoked by the sessions module, the first
+** low-memory environment is required to handle very large changesets, the
+** large contiguous memory allocations required can become onerous.
+**
+** In order to avoid this problem, instead of a single large buffer, input
+** is passed to a streaming API functions by way of a callback function that
+** the sessions module invokes to incrementally request input data as it is
+** required. In all cases, a pair of API function parameters such as
+**
+** <pre>
+** &nbsp; int nChangeset,
+** &nbsp; void *pChangeset,
+** </pre>
+**
+** Is replaced by:
+**
+** <pre>
+** &nbsp; int (*xInput)(void *pIn, void *pData, int *pnData),
+** &nbsp; void *pIn,
+** </pre>
+**
+** Each time the xInput callback is invoked by the sessions module, the first
** argument passed is a copy of the supplied pIn context pointer. The second
** argument, pData, points to a buffer (*pnData) bytes in size. Assuming no
** error occurs the xInput method should copy up to (*pnData) bytes of data
** into the buffer and set (*pnData) to the actual number of bytes copied
** before returning SQLITE_OK. If the input is completely exhausted, (*pnData)
** should be set to zero to indicate this. Or, if an error occurs, an SQLite
-** error code should be returned. In all cases, if an xInput callback returns
-** an error, all processing is abandoned and the streaming API function
-** returns a copy of the error code to the caller.
-**
-** In the case of sqlite3changeset_start_strm(), the xInput callback may be
-** invoked by the sessions module at any point during the lifetime of the
-** iterator. If such an xInput callback returns an error, the iterator enters
+** error code should be returned. In all cases, if an xInput callback returns
+** an error, all processing is abandoned and the streaming API function
+** returns a copy of the error code to the caller.
+**
+** In the case of sqlite3changeset_start_strm(), the xInput callback may be
+** invoked by the sessions module at any point during the lifetime of the
+** iterator. If such an xInput callback returns an error, the iterator enters
** an error state, whereby all subsequent calls to iterator functions
-** immediately fail with the same error code as returned by xInput.
-**
-** Similarly, streaming API functions that return changesets (or patchsets)
-** return them in chunks by way of a callback function instead of via a
-** pointer to a single large buffer. In this case, a pair of parameters such
-** as:
-**
-** <pre>
-** &nbsp; int *pnChangeset,
-** &nbsp; void **ppChangeset,
-** </pre>
-**
-** Is replaced by:
-**
-** <pre>
-** &nbsp; int (*xOutput)(void *pOut, const void *pData, int nData),
-** &nbsp; void *pOut
-** </pre>
-**
-** The xOutput callback is invoked zero or more times to return data to
-** the application. The first parameter passed to each call is a copy of the
-** pOut pointer supplied by the application. The second parameter, pData,
-** points to a buffer nData bytes in size containing the chunk of output
-** data being returned. If the xOutput callback successfully processes the
-** supplied data, it should return SQLITE_OK to indicate success. Otherwise,
-** it should return some other SQLite error code. In this case processing
-** is immediately abandoned and the streaming API function returns a copy
-** of the xOutput error code to the application.
-**
+** immediately fail with the same error code as returned by xInput.
+**
+** Similarly, streaming API functions that return changesets (or patchsets)
+** return them in chunks by way of a callback function instead of via a
+** pointer to a single large buffer. In this case, a pair of parameters such
+** as:
+**
+** <pre>
+** &nbsp; int *pnChangeset,
+** &nbsp; void **ppChangeset,
+** </pre>
+**
+** Is replaced by:
+**
+** <pre>
+** &nbsp; int (*xOutput)(void *pOut, const void *pData, int nData),
+** &nbsp; void *pOut
+** </pre>
+**
+** The xOutput callback is invoked zero or more times to return data to
+** the application. The first parameter passed to each call is a copy of the
+** pOut pointer supplied by the application. The second parameter, pData,
+** points to a buffer nData bytes in size containing the chunk of output
+** data being returned. If the xOutput callback successfully processes the
+** supplied data, it should return SQLITE_OK to indicate success. Otherwise,
+** it should return some other SQLite error code. In this case processing
+** is immediately abandoned and the streaming API function returns a copy
+** of the xOutput error code to the application.
+**
** The sessions module never invokes an xOutput callback with the third
-** parameter set to a value less than or equal to zero. Other than this,
-** no guarantees are made as to the size of the chunks of data returned.
-*/
-SQLITE_API int sqlite3changeset_apply_strm(
- sqlite3 *db, /* Apply change to "main" db of this handle */
- int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
- void *pIn, /* First arg for xInput */
- int(*xFilter)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- const char *zTab /* Table name */
- ),
- int(*xConflict)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
- sqlite3_changeset_iter *p /* Handle describing change and conflict */
- ),
- void *pCtx /* First argument passed to xConflict */
-);
+** parameter set to a value less than or equal to zero. Other than this,
+** no guarantees are made as to the size of the chunks of data returned.
+*/
+SQLITE_API int sqlite3changeset_apply_strm(
+ sqlite3 *db, /* Apply change to "main" db of this handle */
+ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
+ void *pIn, /* First arg for xInput */
+ int(*xFilter)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ const char *zTab /* Table name */
+ ),
+ int(*xConflict)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
+ sqlite3_changeset_iter *p /* Handle describing change and conflict */
+ ),
+ void *pCtx /* First argument passed to xConflict */
+);
SQLITE_API int sqlite3changeset_apply_v2_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
@@ -12119,49 +12119,49 @@ SQLITE_API int sqlite3changeset_apply_v2_strm(
void **ppRebase, int *pnRebase,
int flags
);
-SQLITE_API int sqlite3changeset_concat_strm(
- int (*xInputA)(void *pIn, void *pData, int *pnData),
- void *pInA,
- int (*xInputB)(void *pIn, void *pData, int *pnData),
- void *pInB,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-);
-SQLITE_API int sqlite3changeset_invert_strm(
- int (*xInput)(void *pIn, void *pData, int *pnData),
- void *pIn,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-);
-SQLITE_API int sqlite3changeset_start_strm(
- sqlite3_changeset_iter **pp,
- int (*xInput)(void *pIn, void *pData, int *pnData),
- void *pIn
-);
+SQLITE_API int sqlite3changeset_concat_strm(
+ int (*xInputA)(void *pIn, void *pData, int *pnData),
+ void *pInA,
+ int (*xInputB)(void *pIn, void *pData, int *pnData),
+ void *pInB,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+);
+SQLITE_API int sqlite3changeset_invert_strm(
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+);
+SQLITE_API int sqlite3changeset_start_strm(
+ sqlite3_changeset_iter **pp,
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn
+);
SQLITE_API int sqlite3changeset_start_v2_strm(
sqlite3_changeset_iter **pp,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn,
int flags
);
-SQLITE_API int sqlite3session_changeset_strm(
- sqlite3_session *pSession,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-);
-SQLITE_API int sqlite3session_patchset_strm(
- sqlite3_session *pSession,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-);
+SQLITE_API int sqlite3session_changeset_strm(
+ sqlite3_session *pSession,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+);
+SQLITE_API int sqlite3session_patchset_strm(
+ sqlite3_session *pSession,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+);
SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*,
- int (*xInput)(void *pIn, void *pData, int *pnData),
- void *pIn
-);
-SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn
+);
+SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-);
+ void *pOut
+);
SQLITE_API int sqlite3rebaser_rebase_strm(
sqlite3_rebaser *pRebaser,
int (*xInput)(void *pIn, void *pData, int *pnData),
@@ -12169,7 +12169,7 @@ SQLITE_API int sqlite3rebaser_rebase_strm(
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-
+
/*
** CAPI3REF: Configure global parameters
**
@@ -12204,600 +12204,600 @@ SQLITE_API int sqlite3rebaser_rebase_strm(
** otherwise.
*/
SQLITE_API int sqlite3session_config(int op, void *pArg);
-
-/*
+
+/*
** CAPI3REF: Values for sqlite3session_config().
*/
#define SQLITE_SESSION_CONFIG_STRMSIZE 1
/*
-** Make sure we can call this stuff from C++.
-*/
-#if 0
-}
-#endif
-
-#endif /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */
-
-/******** End of sqlite3session.h *********/
-/******** Begin file fts5.h *********/
-/*
-** 2014 May 31
-**
-** 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.
-**
-******************************************************************************
-**
+** Make sure we can call this stuff from C++.
+*/
+#if 0
+}
+#endif
+
+#endif /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */
+
+/******** End of sqlite3session.h *********/
+/******** Begin file fts5.h *********/
+/*
+** 2014 May 31
+**
+** 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.
+**
+******************************************************************************
+**
** Interfaces to extend FTS5. Using the interfaces defined in this file,
-** FTS5 may be extended with:
-**
-** * custom tokenizers, and
-** * custom auxiliary functions.
-*/
-
-
-#ifndef _FTS5_H
-#define _FTS5_H
-
-
-#if 0
-extern "C" {
-#endif
-
-/*************************************************************************
-** CUSTOM AUXILIARY FUNCTIONS
-**
-** Virtual table implementations may overload SQL functions by implementing
-** the sqlite3_module.xFindFunction() method.
-*/
-
-typedef struct Fts5ExtensionApi Fts5ExtensionApi;
-typedef struct Fts5Context Fts5Context;
-typedef struct Fts5PhraseIter Fts5PhraseIter;
-
-typedef void (*fts5_extension_function)(
- const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
- Fts5Context *pFts, /* First arg to pass to pApi functions */
- sqlite3_context *pCtx, /* Context for returning result/error */
- int nVal, /* Number of values in apVal[] array */
- sqlite3_value **apVal /* Array of trailing arguments */
-);
-
-struct Fts5PhraseIter {
- const unsigned char *a;
- const unsigned char *b;
-};
-
-/*
-** EXTENSION API FUNCTIONS
-**
-** xUserData(pFts):
+** FTS5 may be extended with:
+**
+** * custom tokenizers, and
+** * custom auxiliary functions.
+*/
+
+
+#ifndef _FTS5_H
+#define _FTS5_H
+
+
+#if 0
+extern "C" {
+#endif
+
+/*************************************************************************
+** CUSTOM AUXILIARY FUNCTIONS
+**
+** Virtual table implementations may overload SQL functions by implementing
+** the sqlite3_module.xFindFunction() method.
+*/
+
+typedef struct Fts5ExtensionApi Fts5ExtensionApi;
+typedef struct Fts5Context Fts5Context;
+typedef struct Fts5PhraseIter Fts5PhraseIter;
+
+typedef void (*fts5_extension_function)(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+);
+
+struct Fts5PhraseIter {
+ const unsigned char *a;
+ const unsigned char *b;
+};
+
+/*
+** EXTENSION API FUNCTIONS
+**
+** xUserData(pFts):
** Return a copy of the context pointer the extension function was
-** registered with.
-**
-** xColumnTotalSize(pFts, iCol, pnToken):
-** If parameter iCol is less than zero, set output variable *pnToken
-** to the total number of tokens in the FTS5 table. Or, if iCol is
-** non-negative but less than the number of columns in the table, return
+** registered with.
+**
+** xColumnTotalSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the FTS5 table. Or, if iCol is
+** non-negative but less than the number of columns in the table, return
** the total number of tokens in column iCol, considering all rows in
-** the FTS5 table.
-**
-** If parameter iCol is greater than or equal to the number of columns
-** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** the FTS5 table.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
** an OOM condition or IO error), an appropriate SQLite error code is
-** returned.
-**
-** xColumnCount(pFts):
-** Return the number of columns in the table.
-**
-** xColumnSize(pFts, iCol, pnToken):
-** If parameter iCol is less than zero, set output variable *pnToken
-** to the total number of tokens in the current row. Or, if iCol is
-** non-negative but less than the number of columns in the table, set
-** *pnToken to the number of tokens in column iCol of the current row.
-**
-** If parameter iCol is greater than or equal to the number of columns
-** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** returned.
+**
+** xColumnCount(pFts):
+** Return the number of columns in the table.
+**
+** xColumnSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the current row. Or, if iCol is
+** non-negative but less than the number of columns in the table, set
+** *pnToken to the number of tokens in column iCol of the current row.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
** an OOM condition or IO error), an appropriate SQLite error code is
-** returned.
-**
-** This function may be quite inefficient if used with an FTS5 table
-** created with the "columnsize=0" option.
-**
-** xColumnText:
-** This function attempts to retrieve the text of column iCol of the
-** current document. If successful, (*pz) is set to point to a buffer
-** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
-** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
-** if an error occurs, an SQLite error code is returned and the final values
-** of (*pz) and (*pn) are undefined.
-**
-** xPhraseCount:
-** Returns the number of phrases in the current query expression.
-**
-** xPhraseSize:
-** Returns the number of tokens in phrase iPhrase of the query. Phrases
-** are numbered starting from zero.
-**
-** xInstCount:
-** Set *pnInst to the total number of occurrences of all phrases within
-** the query within the current row. Return SQLITE_OK if successful, or
-** an error code (i.e. SQLITE_NOMEM) if an error occurs.
-**
-** This API can be quite slow if used with an FTS5 table created with the
+** returned.
+**
+** This function may be quite inefficient if used with an FTS5 table
+** created with the "columnsize=0" option.
+**
+** xColumnText:
+** This function attempts to retrieve the text of column iCol of the
+** current document. If successful, (*pz) is set to point to a buffer
+** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
+** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
+** if an error occurs, an SQLite error code is returned and the final values
+** of (*pz) and (*pn) are undefined.
+**
+** xPhraseCount:
+** Returns the number of phrases in the current query expression.
+**
+** xPhraseSize:
+** Returns the number of tokens in phrase iPhrase of the query. Phrases
+** are numbered starting from zero.
+**
+** xInstCount:
+** Set *pnInst to the total number of occurrences of all phrases within
+** the query within the current row. Return SQLITE_OK if successful, or
+** an error code (i.e. SQLITE_NOMEM) if an error occurs.
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option. If the FTS5 table is created
** with either "detail=none" or "detail=column" and "content=" option
-** (i.e. if it is a contentless table), then this API always returns 0.
-**
-** xInst:
-** Query for the details of phrase match iIdx within the current row.
-** Phrase matches are numbered starting from zero, so the iIdx argument
-** should be greater than or equal to zero and smaller than the value
-** output by xInstCount().
-**
-** Usually, output parameter *piPhrase is set to the phrase number, *piCol
-** to the column in which it occurs and *piOff the token offset of the
+** (i.e. if it is a contentless table), then this API always returns 0.
+**
+** xInst:
+** Query for the details of phrase match iIdx within the current row.
+** Phrase matches are numbered starting from zero, so the iIdx argument
+** should be greater than or equal to zero and smaller than the value
+** output by xInstCount().
+**
+** Usually, output parameter *piPhrase is set to the phrase number, *piCol
+** to the column in which it occurs and *piOff the token offset of the
** first token of the phrase. Returns SQLITE_OK if successful, or an error
** code (i.e. SQLITE_NOMEM) if an error occurs.
-**
-** This API can be quite slow if used with an FTS5 table created with the
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
-**
-** xRowid:
-** Returns the rowid of the current row.
-**
-** xTokenize:
-** Tokenize text using the tokenizer belonging to the FTS5 table.
-**
-** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
-** This API function is used to query the FTS table for phrase iPhrase
-** of the current query. Specifically, a query equivalent to:
-**
-** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
-**
-** with $p set to a phrase equivalent to the phrase iPhrase of the
-** current query is executed. Any column filter that applies to
+**
+** xRowid:
+** Returns the rowid of the current row.
+**
+** xTokenize:
+** Tokenize text using the tokenizer belonging to the FTS5 table.
+**
+** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
+** This API function is used to query the FTS table for phrase iPhrase
+** of the current query. Specifically, a query equivalent to:
+**
+** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
+**
+** with $p set to a phrase equivalent to the phrase iPhrase of the
+** current query is executed. Any column filter that applies to
** phrase iPhrase of the current query is included in $p. For each
** row visited, the callback function passed as the fourth argument
** is invoked. The context and API objects passed to the callback
-** function may be used to access the properties of each matched row.
+** function may be used to access the properties of each matched row.
** Invoking Api.xUserData() returns a copy of the pointer passed as
-** the third argument to pUserData.
-**
-** If the callback function returns any value other than SQLITE_OK, the
-** query is abandoned and the xQueryPhrase function returns immediately.
-** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
-** Otherwise, the error code is propagated upwards.
-**
-** If the query runs to completion without incident, SQLITE_OK is returned.
-** Or, if some error occurs before the query completes or is aborted by
-** the callback, an SQLite error code is returned.
-**
-**
-** xSetAuxdata(pFts5, pAux, xDelete)
-**
+** the third argument to pUserData.
+**
+** If the callback function returns any value other than SQLITE_OK, the
+** query is abandoned and the xQueryPhrase function returns immediately.
+** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
+** Otherwise, the error code is propagated upwards.
+**
+** If the query runs to completion without incident, SQLITE_OK is returned.
+** Or, if some error occurs before the query completes or is aborted by
+** the callback, an SQLite error code is returned.
+**
+**
+** xSetAuxdata(pFts5, pAux, xDelete)
+**
** Save the pointer passed as the second argument as the extension function's
-** "auxiliary data". The pointer may then be retrieved by the current or any
-** future invocation of the same fts5 extension function made as part of
+** "auxiliary data". The pointer may then be retrieved by the current or any
+** future invocation of the same fts5 extension function made as part of
** the same MATCH query using the xGetAuxdata() API.
-**
-** Each extension function is allocated a single auxiliary data slot for
+**
+** Each extension function is allocated a single auxiliary data slot for
** each FTS query (MATCH expression). If the extension function is invoked
** more than once for a single FTS query, then all invocations share a
-** single auxiliary data context.
-**
-** If there is already an auxiliary data pointer when this function is
-** invoked, then it is replaced by the new pointer. If an xDelete callback
-** was specified along with the original pointer, it is invoked at this
-** point.
-**
-** The xDelete callback, if one is specified, is also invoked on the
-** auxiliary data pointer after the FTS5 query has finished.
-**
+** single auxiliary data context.
+**
+** If there is already an auxiliary data pointer when this function is
+** invoked, then it is replaced by the new pointer. If an xDelete callback
+** was specified along with the original pointer, it is invoked at this
+** point.
+**
+** The xDelete callback, if one is specified, is also invoked on the
+** auxiliary data pointer after the FTS5 query has finished.
+**
** If an error (e.g. an OOM condition) occurs within this function,
-** the auxiliary data is set to NULL and an error code returned. If the
-** xDelete parameter was not NULL, it is invoked on the auxiliary data
-** pointer before returning.
-**
-**
-** xGetAuxdata(pFts5, bClear)
-**
+** the auxiliary data is set to NULL and an error code returned. If the
+** xDelete parameter was not NULL, it is invoked on the auxiliary data
+** pointer before returning.
+**
+**
+** xGetAuxdata(pFts5, bClear)
+**
** Returns the current auxiliary data pointer for the fts5 extension
-** function. See the xSetAuxdata() method for details.
-**
-** If the bClear argument is non-zero, then the auxiliary data is cleared
-** (set to NULL) before this function returns. In this case the xDelete,
-** if any, is not invoked.
-**
-**
-** xRowCount(pFts5, pnRow)
-**
-** This function is used to retrieve the total number of rows in the table.
-** In other words, the same value that would be returned by:
-**
-** SELECT count(*) FROM ftstable;
-**
-** xPhraseFirst()
-** This function is used, along with type Fts5PhraseIter and the xPhraseNext
-** method, to iterate through all instances of a single query phrase within
-** the current row. This is the same information as is accessible via the
-** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
+** function. See the xSetAuxdata() method for details.
+**
+** If the bClear argument is non-zero, then the auxiliary data is cleared
+** (set to NULL) before this function returns. In this case the xDelete,
+** if any, is not invoked.
+**
+**
+** xRowCount(pFts5, pnRow)
+**
+** This function is used to retrieve the total number of rows in the table.
+** In other words, the same value that would be returned by:
+**
+** SELECT count(*) FROM ftstable;
+**
+** xPhraseFirst()
+** This function is used, along with type Fts5PhraseIter and the xPhraseNext
+** method, to iterate through all instances of a single query phrase within
+** the current row. This is the same information as is accessible via the
+** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
** to use, this API may be faster under some circumstances. To iterate
-** through instances of phrase iPhrase, use the following code:
-**
-** Fts5PhraseIter iter;
-** int iCol, iOff;
-** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
-** iCol>=0;
-** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
-** ){
-** // An instance of phrase iPhrase at offset iOff of column iCol
-** }
-**
-** The Fts5PhraseIter structure is defined above. Applications should not
-** modify this structure directly - it should only be used as shown above
-** with the xPhraseFirst() and xPhraseNext() API methods (and by
-** xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
-**
-** This API can be quite slow if used with an FTS5 table created with the
+** through instances of phrase iPhrase, use the following code:
+**
+** Fts5PhraseIter iter;
+** int iCol, iOff;
+** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
+** iCol>=0;
+** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
+** ){
+** // An instance of phrase iPhrase at offset iOff of column iCol
+** }
+**
+** The Fts5PhraseIter structure is defined above. Applications should not
+** modify this structure directly - it should only be used as shown above
+** with the xPhraseFirst() and xPhraseNext() API methods (and by
+** xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option. If the FTS5 table is created
** with either "detail=none" or "detail=column" and "content=" option
-** (i.e. if it is a contentless table), then this API always iterates
-** through an empty set (all calls to xPhraseFirst() set iCol to -1).
-**
-** xPhraseNext()
-** See xPhraseFirst above.
-**
-** xPhraseFirstColumn()
-** This function and xPhraseNextColumn() are similar to the xPhraseFirst()
-** and xPhraseNext() APIs described above. The difference is that instead
-** of iterating through all instances of a phrase in the current row, these
-** APIs are used to iterate through the set of columns in the current row
-** that contain one or more instances of a specified phrase. For example:
-**
-** Fts5PhraseIter iter;
-** int iCol;
-** for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
-** iCol>=0;
-** pApi->xPhraseNextColumn(pFts, &iter, &iCol)
-** ){
-** // Column iCol contains at least one instance of phrase iPhrase
-** }
-**
-** This API can be quite slow if used with an FTS5 table created with the
+** (i.e. if it is a contentless table), then this API always iterates
+** through an empty set (all calls to xPhraseFirst() set iCol to -1).
+**
+** xPhraseNext()
+** See xPhraseFirst above.
+**
+** xPhraseFirstColumn()
+** This function and xPhraseNextColumn() are similar to the xPhraseFirst()
+** and xPhraseNext() APIs described above. The difference is that instead
+** of iterating through all instances of a phrase in the current row, these
+** APIs are used to iterate through the set of columns in the current row
+** that contain one or more instances of a specified phrase. For example:
+**
+** Fts5PhraseIter iter;
+** int iCol;
+** for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
+** iCol>=0;
+** pApi->xPhraseNextColumn(pFts, &iter, &iCol)
+** ){
+** // Column iCol contains at least one instance of phrase iPhrase
+** }
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" option. If the FTS5 table is created with either
** "detail=none" "content=" option (i.e. if it is a contentless table),
** then this API always iterates through an empty set (all calls to
-** xPhraseFirstColumn() set iCol to -1).
-**
-** The information accessed using this API and its companion
-** xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
-** (or xInst/xInstCount). The chief advantage of this API is that it is
-** significantly more efficient than those alternatives when used with
+** xPhraseFirstColumn() set iCol to -1).
+**
+** The information accessed using this API and its companion
+** xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
+** (or xInst/xInstCount). The chief advantage of this API is that it is
+** significantly more efficient than those alternatives when used with
** "detail=column" tables.
-**
-** xPhraseNextColumn()
-** See xPhraseFirstColumn above.
-*/
-struct Fts5ExtensionApi {
- int iVersion; /* Currently always set to 3 */
-
- void *(*xUserData)(Fts5Context*);
-
- int (*xColumnCount)(Fts5Context*);
- int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
- int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
-
+**
+** xPhraseNextColumn()
+** See xPhraseFirstColumn above.
+*/
+struct Fts5ExtensionApi {
+ int iVersion; /* Currently always set to 3 */
+
+ void *(*xUserData)(Fts5Context*);
+
+ int (*xColumnCount)(Fts5Context*);
+ int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
+ int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
+
int (*xTokenize)(Fts5Context*,
- const char *pText, int nText, /* Text to tokenize */
- void *pCtx, /* Context passed to xToken() */
- int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
- );
-
- int (*xPhraseCount)(Fts5Context*);
- int (*xPhraseSize)(Fts5Context*, int iPhrase);
-
- int (*xInstCount)(Fts5Context*, int *pnInst);
- int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
-
- sqlite3_int64 (*xRowid)(Fts5Context*);
- int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
- int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
-
- int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
- int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
- );
- int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
- void *(*xGetAuxdata)(Fts5Context*, int bClear);
-
- int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
- void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
-
- int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
- void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
-};
-
-/*
-** CUSTOM AUXILIARY FUNCTIONS
-*************************************************************************/
-
-/*************************************************************************
-** CUSTOM TOKENIZERS
-**
+ const char *pText, int nText, /* Text to tokenize */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+ );
+
+ int (*xPhraseCount)(Fts5Context*);
+ int (*xPhraseSize)(Fts5Context*, int iPhrase);
+
+ int (*xInstCount)(Fts5Context*, int *pnInst);
+ int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
+
+ sqlite3_int64 (*xRowid)(Fts5Context*);
+ int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
+ int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
+
+ int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
+ int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
+ );
+ int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
+ void *(*xGetAuxdata)(Fts5Context*, int bClear);
+
+ int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
+ void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
+
+ int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
+ void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
+};
+
+/*
+** CUSTOM AUXILIARY FUNCTIONS
+*************************************************************************/
+
+/*************************************************************************
+** CUSTOM TOKENIZERS
+**
** Applications may also register custom tokenizer types. A tokenizer
** is registered by providing fts5 with a populated instance of the
-** following structure. All structure methods must be defined, setting
-** any member of the fts5_tokenizer struct to NULL leads to undefined
-** behaviour. The structure methods are expected to function as follows:
-**
-** xCreate:
-** This function is used to allocate and initialize a tokenizer instance.
-** A tokenizer instance is required to actually tokenize text.
-**
-** The first argument passed to this function is a copy of the (void*)
-** pointer provided by the application when the fts5_tokenizer object
+** following structure. All structure methods must be defined, setting
+** any member of the fts5_tokenizer struct to NULL leads to undefined
+** behaviour. The structure methods are expected to function as follows:
+**
+** xCreate:
+** This function is used to allocate and initialize a tokenizer instance.
+** A tokenizer instance is required to actually tokenize text.
+**
+** The first argument passed to this function is a copy of the (void*)
+** pointer provided by the application when the fts5_tokenizer object
** was registered with FTS5 (the third argument to xCreateTokenizer()).
-** The second and third arguments are an array of nul-terminated strings
-** containing the tokenizer arguments, if any, specified following the
-** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
-** to create the FTS5 table.
-**
+** The second and third arguments are an array of nul-terminated strings
+** containing the tokenizer arguments, if any, specified following the
+** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
+** to create the FTS5 table.
+**
** The final argument is an output variable. If successful, (*ppOut)
-** should be set to point to the new tokenizer handle and SQLITE_OK
-** returned. If an error occurs, some value other than SQLITE_OK should
+** should be set to point to the new tokenizer handle and SQLITE_OK
+** returned. If an error occurs, some value other than SQLITE_OK should
** be returned. In this case, fts5 assumes that the final value of *ppOut
-** is undefined.
-**
-** xDelete:
-** This function is invoked to delete a tokenizer handle previously
-** allocated using xCreate(). Fts5 guarantees that this function will
-** be invoked exactly once for each successful call to xCreate().
-**
-** xTokenize:
+** is undefined.
+**
+** xDelete:
+** This function is invoked to delete a tokenizer handle previously
+** allocated using xCreate(). Fts5 guarantees that this function will
+** be invoked exactly once for each successful call to xCreate().
+**
+** xTokenize:
** This function is expected to tokenize the nText byte string indicated
-** by argument pText. pText may or may not be nul-terminated. The first
-** argument passed to this function is a pointer to an Fts5Tokenizer object
-** returned by an earlier call to xCreate().
-**
-** The second argument indicates the reason that FTS5 is requesting
-** tokenization of the supplied text. This is always one of the following
-** four values:
-**
-** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
-** or removed from the FTS table. The tokenizer is being invoked to
-** determine the set of tokens to add to (or delete from) the
-** FTS index.
-**
+** by argument pText. pText may or may not be nul-terminated. The first
+** argument passed to this function is a pointer to an Fts5Tokenizer object
+** returned by an earlier call to xCreate().
+**
+** The second argument indicates the reason that FTS5 is requesting
+** tokenization of the supplied text. This is always one of the following
+** four values:
+**
+** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
+** or removed from the FTS table. The tokenizer is being invoked to
+** determine the set of tokens to add to (or delete from) the
+** FTS index.
+**
** <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed
** against the FTS index. The tokenizer is being called to tokenize
-** a bareword or quoted string specified as part of the query.
-**
-** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
-** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
-** followed by a "*" character, indicating that the last token
-** returned by the tokenizer will be treated as a token prefix.
-**
+** a bareword or quoted string specified as part of the query.
+**
+** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
+** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
+** followed by a "*" character, indicating that the last token
+** returned by the tokenizer will be treated as a token prefix.
+**
** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
-** satisfy an fts5_api.xTokenize() request made by an auxiliary
-** function. Or an fts5_api.xColumnSize() request made by the same
+** satisfy an fts5_api.xTokenize() request made by an auxiliary
+** function. Or an fts5_api.xColumnSize() request made by the same
** on a columnsize=0 database.
-** </ul>
-**
-** For each token in the input string, the supplied callback xToken() must
-** be invoked. The first argument to it should be a copy of the pointer
-** passed as the second argument to xTokenize(). The third and fourth
-** arguments are a pointer to a buffer containing the token text, and the
-** size of the token in bytes. The 4th and 5th arguments are the byte offsets
-** of the first byte of and first byte immediately following the text from
-** which the token is derived within the input.
-**
-** The second argument passed to the xToken() callback ("tflags") should
+** </ul>
+**
+** For each token in the input string, the supplied callback xToken() must
+** be invoked. The first argument to it should be a copy of the pointer
+** passed as the second argument to xTokenize(). The third and fourth
+** arguments are a pointer to a buffer containing the token text, and the
+** size of the token in bytes. The 4th and 5th arguments are the byte offsets
+** of the first byte of and first byte immediately following the text from
+** which the token is derived within the input.
+**
+** The second argument passed to the xToken() callback ("tflags") should
** normally be set to 0. The exception is if the tokenizer supports
-** synonyms. In this case see the discussion below for details.
-**
+** synonyms. In this case see the discussion below for details.
+**
** FTS5 assumes the xToken() callback is invoked for each token in the
-** order that they occur within the input text.
-**
-** If an xToken() callback returns any value other than SQLITE_OK, then
-** the tokenization should be abandoned and the xTokenize() method should
-** immediately return a copy of the xToken() return value. Or, if the
-** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
-** if an error occurs with the xTokenize() implementation itself, it
-** may abandon the tokenization and return any error code other than
-** SQLITE_OK or SQLITE_DONE.
-**
-** SYNONYM SUPPORT
-**
-** Custom tokenizers may also support synonyms. Consider a case in which a
+** order that they occur within the input text.
+**
+** If an xToken() callback returns any value other than SQLITE_OK, then
+** the tokenization should be abandoned and the xTokenize() method should
+** immediately return a copy of the xToken() return value. Or, if the
+** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
+** if an error occurs with the xTokenize() implementation itself, it
+** may abandon the tokenization and return any error code other than
+** SQLITE_OK or SQLITE_DONE.
+**
+** SYNONYM SUPPORT
+**
+** Custom tokenizers may also support synonyms. Consider a case in which a
** user wishes to query for a phrase such as "first place". Using the
-** built-in tokenizers, the FTS5 query 'first + place' will match instances
-** of "first place" within the document set, but not alternative forms
-** such as "1st place". In some applications, it would be better to match
-** all instances of "first place" or "1st place" regardless of which form
-** the user specified in the MATCH query text.
-**
-** There are several ways to approach this in FTS5:
-**
+** built-in tokenizers, the FTS5 query 'first + place' will match instances
+** of "first place" within the document set, but not alternative forms
+** such as "1st place". In some applications, it would be better to match
+** all instances of "first place" or "1st place" regardless of which form
+** the user specified in the MATCH query text.
+**
+** There are several ways to approach this in FTS5:
+**
** <ol><li> By mapping all synonyms to a single token. In this case, using
** the above example, this means that the tokenizer returns the
-** same token for inputs "first" and "1st". Say that token is in
-** fact "first", so that when the user inserts the document "I won
-** 1st place" entries are added to the index for tokens "i", "won",
-** "first" and "place". If the user then queries for '1st + place',
-** the tokenizer substitutes "first" for "1st" and the query works
-** as expected.
-**
+** same token for inputs "first" and "1st". Say that token is in
+** fact "first", so that when the user inserts the document "I won
+** 1st place" entries are added to the index for tokens "i", "won",
+** "first" and "place". If the user then queries for '1st + place',
+** the tokenizer substitutes "first" for "1st" and the query works
+** as expected.
+**
** <li> By querying the index for all synonyms of each query term
** separately. In this case, when tokenizing query text, the
** tokenizer may provide multiple synonyms for a single term
** within the document. FTS5 then queries the index for each
** synonym individually. For example, faced with the query:
-**
-** <codeblock>
-** ... MATCH 'first place'</codeblock>
-**
-** the tokenizer offers both "1st" and "first" as synonyms for the
+**
+** <codeblock>
+** ... MATCH 'first place'</codeblock>
+**
+** the tokenizer offers both "1st" and "first" as synonyms for the
** first token in the MATCH query and FTS5 effectively runs a query
-** similar to:
-**
-** <codeblock>
-** ... MATCH '(first OR 1st) place'</codeblock>
-**
-** except that, for the purposes of auxiliary functions, the query
+** similar to:
+**
+** <codeblock>
+** ... MATCH '(first OR 1st) place'</codeblock>
+**
+** except that, for the purposes of auxiliary functions, the query
** still appears to contain just two phrases - "(first OR 1st)"
-** being treated as a single phrase.
-**
-** <li> By adding multiple synonyms for a single term to the FTS index.
-** Using this method, when tokenizing document text, the tokenizer
+** being treated as a single phrase.
+**
+** <li> By adding multiple synonyms for a single term to the FTS index.
+** Using this method, when tokenizing document text, the tokenizer
** provides multiple synonyms for each token. So that when a
-** document such as "I won first place" is tokenized, entries are
-** added to the FTS index for "i", "won", "first", "1st" and
-** "place".
-**
-** This way, even if the tokenizer does not provide synonyms
+** document such as "I won first place" is tokenized, entries are
+** added to the FTS index for "i", "won", "first", "1st" and
+** "place".
+**
+** This way, even if the tokenizer does not provide synonyms
** when tokenizing query text (it should not - to do so would be
** inefficient), it doesn't matter if the user queries for
** 'first + place' or '1st + place', as there are entries in the
-** FTS index corresponding to both forms of the first token.
-** </ol>
-**
-** Whether it is parsing document or query text, any call to xToken that
-** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
-** is considered to supply a synonym for the previous token. For example,
-** when parsing the document "I won first place", a tokenizer that supports
-** synonyms would call xToken() 5 times, as follows:
-**
-** <codeblock>
-** xToken(pCtx, 0, "i", 1, 0, 1);
-** xToken(pCtx, 0, "won", 3, 2, 5);
-** xToken(pCtx, 0, "first", 5, 6, 11);
-** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
-** xToken(pCtx, 0, "place", 5, 12, 17);
-**</codeblock>
-**
-** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
-** xToken() is called. Multiple synonyms may be specified for a single token
+** FTS index corresponding to both forms of the first token.
+** </ol>
+**
+** Whether it is parsing document or query text, any call to xToken that
+** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
+** is considered to supply a synonym for the previous token. For example,
+** when parsing the document "I won first place", a tokenizer that supports
+** synonyms would call xToken() 5 times, as follows:
+**
+** <codeblock>
+** xToken(pCtx, 0, "i", 1, 0, 1);
+** xToken(pCtx, 0, "won", 3, 2, 5);
+** xToken(pCtx, 0, "first", 5, 6, 11);
+** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
+** xToken(pCtx, 0, "place", 5, 12, 17);
+**</codeblock>
+**
+** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
+** xToken() is called. Multiple synonyms may be specified for a single token
** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence.
-** There is no limit to the number of synonyms that may be provided for a
-** single token.
-**
+** There is no limit to the number of synonyms that may be provided for a
+** single token.
+**
** In many cases, method (1) above is the best approach. It does not add
-** extra data to the FTS index or require FTS5 to query for multiple terms,
-** so it is efficient in terms of disk space and query speed. However, it
-** does not support prefix queries very well. If, as suggested above, the
+** extra data to the FTS index or require FTS5 to query for multiple terms,
+** so it is efficient in terms of disk space and query speed. However, it
+** does not support prefix queries very well. If, as suggested above, the
** token "first" is substituted for "1st" by the tokenizer, then the query:
-**
-** <codeblock>
-** ... MATCH '1s*'</codeblock>
-**
-** will not match documents that contain the token "1st" (as the tokenizer
-** will probably not map "1s" to any prefix of "first").
-**
+**
+** <codeblock>
+** ... MATCH '1s*'</codeblock>
+**
+** will not match documents that contain the token "1st" (as the tokenizer
+** will probably not map "1s" to any prefix of "first").
+**
** For full prefix support, method (3) may be preferred. In this case,
-** because the index contains entries for both "first" and "1st", prefix
-** queries such as 'fi*' or '1s*' will match correctly. However, because
-** extra entries are added to the FTS index, this method uses more space
-** within the database.
-**
-** Method (2) offers a midpoint between (1) and (3). Using this method,
+** because the index contains entries for both "first" and "1st", prefix
+** queries such as 'fi*' or '1s*' will match correctly. However, because
+** extra entries are added to the FTS index, this method uses more space
+** within the database.
+**
+** Method (2) offers a midpoint between (1) and (3). Using this method,
** a query such as '1s*' will match documents that contain the literal
-** token "1st", but not "first" (assuming the tokenizer is not able to
-** provide synonyms for prefixes). However, a non-prefix query like '1st'
-** will match against "1st" and "first". This method does not require
+** token "1st", but not "first" (assuming the tokenizer is not able to
+** provide synonyms for prefixes). However, a non-prefix query like '1st'
+** will match against "1st" and "first". This method does not require
** extra disk space, as no extra entries are added to the FTS index.
-** On the other hand, it may require more CPU cycles to run MATCH queries,
-** as separate queries of the FTS index are required for each synonym.
-**
-** When using methods (2) or (3), it is important that the tokenizer only
-** provide synonyms when tokenizing document text (method (2)) or query
-** text (method (3)), not both. Doing so will not cause any errors, but is
-** inefficient.
-*/
-typedef struct Fts5Tokenizer Fts5Tokenizer;
-typedef struct fts5_tokenizer fts5_tokenizer;
-struct fts5_tokenizer {
- int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
- void (*xDelete)(Fts5Tokenizer*);
+** On the other hand, it may require more CPU cycles to run MATCH queries,
+** as separate queries of the FTS index are required for each synonym.
+**
+** When using methods (2) or (3), it is important that the tokenizer only
+** provide synonyms when tokenizing document text (method (2)) or query
+** text (method (3)), not both. Doing so will not cause any errors, but is
+** inefficient.
+*/
+typedef struct Fts5Tokenizer Fts5Tokenizer;
+typedef struct fts5_tokenizer fts5_tokenizer;
+struct fts5_tokenizer {
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
+ void (*xDelete)(Fts5Tokenizer*);
int (*xTokenize)(Fts5Tokenizer*,
- void *pCtx,
- int flags, /* Mask of FTS5_TOKENIZE_* flags */
+ void *pCtx,
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
const char *pText, int nText,
- int (*xToken)(
- void *pCtx, /* Copy of 2nd argument to xTokenize() */
- int tflags, /* Mask of FTS5_TOKEN_* flags */
- const char *pToken, /* Pointer to buffer containing token */
- int nToken, /* Size of token in bytes */
- int iStart, /* Byte offset of token within input text */
- int iEnd /* Byte offset of end of token within input text */
- )
- );
-};
-
-/* Flags that may be passed as the third argument to xTokenize() */
-#define FTS5_TOKENIZE_QUERY 0x0001
-#define FTS5_TOKENIZE_PREFIX 0x0002
-#define FTS5_TOKENIZE_DOCUMENT 0x0004
-#define FTS5_TOKENIZE_AUX 0x0008
-
-/* Flags that may be passed by the tokenizer implementation back to FTS5
-** as the third argument to the supplied xToken callback. */
-#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
-
-/*
-** END OF CUSTOM TOKENIZERS
-*************************************************************************/
-
-/*************************************************************************
-** FTS5 EXTENSION REGISTRATION API
-*/
-typedef struct fts5_api fts5_api;
-struct fts5_api {
- int iVersion; /* Currently always set to 2 */
-
- /* Create a new tokenizer */
- int (*xCreateTokenizer)(
- fts5_api *pApi,
- const char *zName,
- void *pContext,
- fts5_tokenizer *pTokenizer,
- void (*xDestroy)(void*)
- );
-
- /* Find an existing tokenizer */
- int (*xFindTokenizer)(
- fts5_api *pApi,
- const char *zName,
- void **ppContext,
- fts5_tokenizer *pTokenizer
- );
-
- /* Create a new auxiliary function */
- int (*xCreateFunction)(
- fts5_api *pApi,
- const char *zName,
- void *pContext,
- fts5_extension_function xFunction,
- void (*xDestroy)(void*)
- );
-};
-
-/*
-** END OF REGISTRATION API
-*************************************************************************/
-
-#if 0
-} /* end of the 'extern "C"' block */
-#endif
-
-#endif /* _FTS5_H */
-
-/******** End of fts5.h *********/
-
+ int (*xToken)(
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Pointer to buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Byte offset of token within input text */
+ int iEnd /* Byte offset of end of token within input text */
+ )
+ );
+};
+
+/* Flags that may be passed as the third argument to xTokenize() */
+#define FTS5_TOKENIZE_QUERY 0x0001
+#define FTS5_TOKENIZE_PREFIX 0x0002
+#define FTS5_TOKENIZE_DOCUMENT 0x0004
+#define FTS5_TOKENIZE_AUX 0x0008
+
+/* Flags that may be passed by the tokenizer implementation back to FTS5
+** as the third argument to the supplied xToken callback. */
+#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
+
+/*
+** END OF CUSTOM TOKENIZERS
+*************************************************************************/
+
+/*************************************************************************
+** FTS5 EXTENSION REGISTRATION API
+*/
+typedef struct fts5_api fts5_api;
+struct fts5_api {
+ int iVersion; /* Currently always set to 2 */
+
+ /* Create a new tokenizer */
+ int (*xCreateTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_tokenizer *pTokenizer,
+ void (*xDestroy)(void*)
+ );
+
+ /* Find an existing tokenizer */
+ int (*xFindTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void **ppContext,
+ fts5_tokenizer *pTokenizer
+ );
+
+ /* Create a new auxiliary function */
+ int (*xCreateFunction)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_extension_function xFunction,
+ void (*xDestroy)(void*)
+ );
+};
+
+/*
+** END OF REGISTRATION API
+*************************************************************************/
+
+#if 0
+} /* end of the 'extern "C"' block */
+#endif
+
+#endif /* _FTS5_H */
+
+/******** End of fts5.h *********/
+
/************** End of sqlite3.h *********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -12805,9 +12805,9 @@ struct fts5_api {
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
*/
-#if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H)
+#if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H)
#include "config.h"
-#define SQLITECONFIG_H 1
+#define SQLITECONFIG_H 1
#endif
/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
@@ -12897,7 +12897,7 @@ struct fts5_api {
** Not currently enforced.
*/
#ifndef SQLITE_MAX_VDBE_OP
-# define SQLITE_MAX_VDBE_OP 250000000
+# define SQLITE_MAX_VDBE_OP 250000000
#endif
/*
@@ -12911,13 +12911,13 @@ struct fts5_api {
** The suggested maximum number of in-memory pages to use for
** the main database table and for temporary tables.
**
-** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000,
-** which means the cache size is limited to 2048000 bytes of memory.
+** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000,
+** which means the cache size is limited to 2048000 bytes of memory.
** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be
** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options.
*/
#ifndef SQLITE_DEFAULT_CACHE_SIZE
-# define SQLITE_DEFAULT_CACHE_SIZE -2000
+# define SQLITE_DEFAULT_CACHE_SIZE -2000
#endif
/*
@@ -12930,9 +12930,9 @@ struct fts5_api {
/*
** The maximum number of attached databases. This must be between 0
-** and 125. The upper bound of 125 is because the attached databases are
-** counted using a signed 8-bit integer which has a maximum value of 127
-** and we have to allow 2 extra counts for the "main" and "temp" databases.
+** and 125. The upper bound of 125 is because the attached databases are
+** counted using a signed 8-bit integer which has a maximum value of 127
+** and we have to allow 2 extra counts for the "main" and "temp" databases.
*/
#ifndef SQLITE_MAX_ATTACHED
# define SQLITE_MAX_ATTACHED 10
@@ -12970,7 +12970,7 @@ struct fts5_api {
** The default size of a database page.
*/
#ifndef SQLITE_DEFAULT_PAGE_SIZE
-# define SQLITE_DEFAULT_PAGE_SIZE 4096
+# define SQLITE_DEFAULT_PAGE_SIZE 4096
#endif
#if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
# undef SQLITE_DEFAULT_PAGE_SIZE
@@ -13068,7 +13068,7 @@ struct fts5_api {
** to the next, so we have developed the following set of #if statements
** to generate appropriate macros for a wide range of compilers.
**
-** The correct "ANSI" way to do this is to use the intptr_t type.
+** The correct "ANSI" way to do this is to use the intptr_t type.
** Unfortunately, that typedef is not available on all compilers, or
** if it is available, it requires an #include of specific headers
** that vary from one machine to the next.
@@ -13106,20 +13106,20 @@ struct fts5_api {
/*
** Make sure that the compiler intrinsics we desire are enabled when
-** compiling with an appropriate version of MSVC unless prevented by
-** the SQLITE_DISABLE_INTRINSIC define.
-*/
-#if !defined(SQLITE_DISABLE_INTRINSIC)
-# if defined(_MSC_VER) && _MSC_VER>=1400
-# if !defined(_WIN32_WCE)
-# include <intrin.h>
-# pragma intrinsic(_byteswap_ushort)
-# pragma intrinsic(_byteswap_ulong)
-# pragma intrinsic(_byteswap_uint64)
-# pragma intrinsic(_ReadWriteBarrier)
-# else
-# include <cmnintrin.h>
-# endif
+** compiling with an appropriate version of MSVC unless prevented by
+** the SQLITE_DISABLE_INTRINSIC define.
+*/
+#if !defined(SQLITE_DISABLE_INTRINSIC)
+# if defined(_MSC_VER) && _MSC_VER>=1400
+# if !defined(_WIN32_WCE)
+# include <intrin.h>
+# pragma intrinsic(_byteswap_ushort)
+# pragma intrinsic(_byteswap_ulong)
+# pragma intrinsic(_byteswap_uint64)
+# pragma intrinsic(_ReadWriteBarrier)
+# else
+# include <cmnintrin.h>
+# endif
# endif
#endif
@@ -13133,11 +13133,11 @@ struct fts5_api {
**
** Older versions of SQLite used an optional THREADSAFE macro.
** We support that for legacy.
-**
-** To ensure that the correct value of "THREADSAFE" is reported when querying
-** for compile-time options at runtime (e.g. "PRAGMA compile_options"), this
-** logic is partially replicated in ctime.c. If it is updated here, it should
-** also be updated there.
+**
+** To ensure that the correct value of "THREADSAFE" is reported when querying
+** for compile-time options at runtime (e.g. "PRAGMA compile_options"), this
+** logic is partially replicated in ctime.c. If it is updated here, it should
+** also be updated there.
*/
#if !defined(SQLITE_THREADSAFE)
# if defined(THREADSAFE)
@@ -13226,7 +13226,7 @@ struct fts5_api {
** is set. Thus NDEBUG becomes an opt-in rather than an opt-out
** feature.
*/
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
+#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif
#if defined(NDEBUG) && defined(SQLITE_DEBUG)
@@ -13241,7 +13241,7 @@ struct fts5_api {
#endif
/*
-** The testcase() macro is used to aid in coverage testing. When
+** The testcase() macro is used to aid in coverage testing. When
** doing coverage testing, the condition inside the argument to
** testcase() must be evaluated both true and false in order to
** get full branch coverage. The testcase() macro is inserted
@@ -13296,7 +13296,7 @@ struct fts5_api {
#endif
/*
-** The ALWAYS and NEVER macros surround boolean expressions which
+** The ALWAYS and NEVER macros surround boolean expressions which
** are intended to always be true or false, respectively. Such
** expressions could be omitted from the code completely. But they
** are included in a few cases in order to enhance the resilience
@@ -13322,36 +13322,36 @@ struct fts5_api {
#endif
/*
-** Some conditionals are optimizations only. In other words, if the
-** conditionals are replaced with a constant 1 (true) or 0 (false) then
-** the correct answer is still obtained, though perhaps not as quickly.
-**
-** The following macros mark these optimizations conditionals.
-*/
-#if defined(SQLITE_MUTATION_TEST)
-# define OK_IF_ALWAYS_TRUE(X) (1)
-# define OK_IF_ALWAYS_FALSE(X) (0)
-#else
-# define OK_IF_ALWAYS_TRUE(X) (X)
-# define OK_IF_ALWAYS_FALSE(X) (X)
-#endif
-
-/*
-** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is
-** defined. We need to defend against those failures when testing with
-** SQLITE_TEST_REALLOC_STRESS, but we don't want the unreachable branches
-** during a normal build. The following macro can be used to disable tests
-** that are always false except when SQLITE_TEST_REALLOC_STRESS is set.
-*/
-#if defined(SQLITE_TEST_REALLOC_STRESS)
-# define ONLY_IF_REALLOC_STRESS(X) (X)
-#elif !defined(NDEBUG)
-# define ONLY_IF_REALLOC_STRESS(X) ((X)?(assert(0),1):0)
-#else
-# define ONLY_IF_REALLOC_STRESS(X) (0)
-#endif
-
-/*
+** Some conditionals are optimizations only. In other words, if the
+** conditionals are replaced with a constant 1 (true) or 0 (false) then
+** the correct answer is still obtained, though perhaps not as quickly.
+**
+** The following macros mark these optimizations conditionals.
+*/
+#if defined(SQLITE_MUTATION_TEST)
+# define OK_IF_ALWAYS_TRUE(X) (1)
+# define OK_IF_ALWAYS_FALSE(X) (0)
+#else
+# define OK_IF_ALWAYS_TRUE(X) (X)
+# define OK_IF_ALWAYS_FALSE(X) (X)
+#endif
+
+/*
+** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is
+** defined. We need to defend against those failures when testing with
+** SQLITE_TEST_REALLOC_STRESS, but we don't want the unreachable branches
+** during a normal build. The following macro can be used to disable tests
+** that are always false except when SQLITE_TEST_REALLOC_STRESS is set.
+*/
+#if defined(SQLITE_TEST_REALLOC_STRESS)
+# define ONLY_IF_REALLOC_STRESS(X) (X)
+#elif !defined(NDEBUG)
+# define ONLY_IF_REALLOC_STRESS(X) ((X)?(assert(0),1):0)
+#else
+# define ONLY_IF_REALLOC_STRESS(X) (0)
+#endif
+
+/*
** Declarations used for tracing the operating system interfaces.
*/
#if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \
@@ -13378,13 +13378,13 @@ struct fts5_api {
#endif
/*
-** SQLITE_ENABLE_EXPLAIN_COMMENTS is incompatible with SQLITE_OMIT_EXPLAIN
-*/
-#ifdef SQLITE_OMIT_EXPLAIN
-# undef SQLITE_ENABLE_EXPLAIN_COMMENTS
-#endif
-
-/*
+** SQLITE_ENABLE_EXPLAIN_COMMENTS is incompatible with SQLITE_OMIT_EXPLAIN
+*/
+#ifdef SQLITE_OMIT_EXPLAIN
+# undef SQLITE_ENABLE_EXPLAIN_COMMENTS
+#endif
+
+/*
** SQLITE_OMIT_VIRTUALTABLE implies SQLITE_OMIT_ALTERTABLE
*/
#if defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_ALTERTABLE)
@@ -13424,8 +13424,8 @@ struct fts5_api {
** This is the header file for the generic hash-table implementation
** used in SQLite.
*/
-#ifndef SQLITE_HASH_H
-#define SQLITE_HASH_H
+#ifndef SQLITE_HASH_H
+#define SQLITE_HASH_H
/* Forward declarations of structures. */
typedef struct Hash Hash;
@@ -13505,7 +13505,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
*/
#define sqliteHashCount(H) ((H)->count)
-#endif /* SQLITE_HASH_H */
+#endif /* SQLITE_HASH_H */
/************** End of hash.h ************************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -13537,40 +13537,40 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_AS 24
#define TK_COMMA 25
#define TK_WITHOUT 26
-#define TK_ABORT 27
-#define TK_ACTION 28
-#define TK_AFTER 29
-#define TK_ANALYZE 30
-#define TK_ASC 31
-#define TK_ATTACH 32
-#define TK_BEFORE 33
-#define TK_BY 34
-#define TK_CASCADE 35
-#define TK_CAST 36
-#define TK_CONFLICT 37
-#define TK_DATABASE 38
-#define TK_DESC 39
-#define TK_DETACH 40
-#define TK_EACH 41
-#define TK_FAIL 42
-#define TK_OR 43
-#define TK_AND 44
-#define TK_IS 45
-#define TK_MATCH 46
-#define TK_LIKE_KW 47
-#define TK_BETWEEN 48
-#define TK_IN 49
-#define TK_ISNULL 50
-#define TK_NOTNULL 51
-#define TK_NE 52
-#define TK_EQ 53
-#define TK_GT 54
-#define TK_LE 55
-#define TK_LT 56
-#define TK_GE 57
-#define TK_ESCAPE 58
-#define TK_ID 59
-#define TK_COLUMNKW 60
+#define TK_ABORT 27
+#define TK_ACTION 28
+#define TK_AFTER 29
+#define TK_ANALYZE 30
+#define TK_ASC 31
+#define TK_ATTACH 32
+#define TK_BEFORE 33
+#define TK_BY 34
+#define TK_CASCADE 35
+#define TK_CAST 36
+#define TK_CONFLICT 37
+#define TK_DATABASE 38
+#define TK_DESC 39
+#define TK_DETACH 40
+#define TK_EACH 41
+#define TK_FAIL 42
+#define TK_OR 43
+#define TK_AND 44
+#define TK_IS 45
+#define TK_MATCH 46
+#define TK_LIKE_KW 47
+#define TK_BETWEEN 48
+#define TK_IN 49
+#define TK_ISNULL 50
+#define TK_NOTNULL 51
+#define TK_NE 52
+#define TK_EQ 53
+#define TK_GT 54
+#define TK_LE 55
+#define TK_LT 56
+#define TK_GE 57
+#define TK_ESCAPE 58
+#define TK_ID 59
+#define TK_COLUMNKW 60
#define TK_DO 61
#define TK_FOR 62
#define TK_IGNORE 63
@@ -13704,18 +13704,18 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#include <stddef.h>
/*
-** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY.
-** This allows better measurements of where memcpy() is used when running
-** cachegrind. But this macro version of memcpy() is very slow so it
-** should not be used in production. This is a performance measurement
-** hack only.
-*/
-#ifdef SQLITE_INLINE_MEMCPY
-# define memcpy(D,S,N) {char*xxd=(char*)(D);const char*xxs=(const char*)(S);\
- int xxn=(N);while(xxn-->0)*(xxd++)=*(xxs++);}
-#endif
-
-/*
+** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY.
+** This allows better measurements of where memcpy() is used when running
+** cachegrind. But this macro version of memcpy() is very slow so it
+** should not be used in production. This is a performance measurement
+** hack only.
+*/
+#ifdef SQLITE_INLINE_MEMCPY
+# define memcpy(D,S,N) {char*xxd=(char*)(D);const char*xxs=(const char*)(S);\
+ int xxn=(N);while(xxn-->0)*(xxd++)=*(xxs++);}
+#endif
+
+/*
** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point
*/
@@ -13737,7 +13737,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
/*
** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0
-** afterward. Having this macro allows us to cause the C compiler
+** afterward. Having this macro allows us to cause the C compiler
** to omit code used by TEMP tables without messy #ifndef statements.
*/
#ifdef SQLITE_OMIT_TEMPDB
@@ -13775,7 +13775,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
/*
** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if
-** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it
+** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it
** to zero.
*/
#if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0
@@ -13798,15 +13798,15 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
** pagecaches for each database connection. A positive number is the
** number of pages. A negative number N translations means that a buffer
** of -1024*N bytes is allocated and used for as many pages as it will hold.
-**
+**
** The default value of "20" was chosen to minimize the run-time of the
-** speedtest1 test program with options: --shrink-memory --reprepare
+** speedtest1 test program with options: --shrink-memory --reprepare
*/
#ifndef SQLITE_DEFAULT_PCACHE_INITSZ
-# define SQLITE_DEFAULT_PCACHE_INITSZ 20
+# define SQLITE_DEFAULT_PCACHE_INITSZ 20
#endif
-/*
+/*
** Default value for the SQLITE_CONFIG_SORTERREF_SIZE option.
*/
#ifndef SQLITE_DEFAULT_SORTERREF_SIZE
@@ -13815,12 +13815,12 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
/*
** The compile-time options SQLITE_MMAP_READWRITE and
-** SQLITE_ENABLE_BATCH_ATOMIC_WRITE are not compatible with one another.
-** You must choose one or the other (or neither) but not both.
-*/
-#if defined(SQLITE_MMAP_READWRITE) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
-#error Cannot use both SQLITE_MMAP_READWRITE and SQLITE_ENABLE_BATCH_ATOMIC_WRITE
-#endif
+** SQLITE_ENABLE_BATCH_ATOMIC_WRITE are not compatible with one another.
+** You must choose one or the other (or neither) but not both.
+*/
+#if defined(SQLITE_MMAP_READWRITE) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+#error Cannot use both SQLITE_MMAP_READWRITE and SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+#endif
/*
** GCC does not define the offsetof() macro so we'll have to do it
@@ -13833,12 +13833,12 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
/*
** Macros to compute minimum and maximum of two numbers.
*/
-#ifndef MIN
-# define MIN(A,B) ((A)<(B)?(A):(B))
-#endif
-#ifndef MAX
-# define MAX(A,B) ((A)>(B)?(A):(B))
-#endif
+#ifndef MIN
+# define MIN(A,B) ((A)<(B)?(A):(B))
+#endif
+#ifndef MAX
+# define MAX(A,B) ((A)>(B)?(A):(B))
+#endif
/*
** Swap two objects of type TYPE.
@@ -13946,7 +13946,7 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */
** 4 -> 20 1000 -> 99 1048576 -> 200
** 10 -> 33 1024 -> 100 4294967296 -> 320
**
-** The LogEst can be negative to indicate fractional values.
+** The LogEst can be negative to indicate fractional values.
** Examples:
**
** 0.5 -> -10 0.1 -> -33 0.0625 -> -40
@@ -13969,63 +13969,63 @@ typedef INT16_TYPE LogEst;
# endif
#endif
-/* The uptr type is an unsigned integer large enough to hold a pointer
-*/
-#if defined(HAVE_STDINT_H)
- typedef uintptr_t uptr;
-#elif SQLITE_PTRSIZE==4
- typedef u32 uptr;
-#else
- typedef u64 uptr;
-#endif
-
-/*
-** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to
-** something between S (inclusive) and E (exclusive).
-**
-** In other words, S is a buffer and E is a pointer to the first byte after
-** the end of buffer S. This macro returns true if P points to something
-** contained within the buffer S.
-*/
-#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E)))
-
-
-/*
+/* The uptr type is an unsigned integer large enough to hold a pointer
+*/
+#if defined(HAVE_STDINT_H)
+ typedef uintptr_t uptr;
+#elif SQLITE_PTRSIZE==4
+ typedef u32 uptr;
+#else
+ typedef u64 uptr;
+#endif
+
+/*
+** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to
+** something between S (inclusive) and E (exclusive).
+**
+** In other words, S is a buffer and E is a pointer to the first byte after
+** the end of buffer S. This macro returns true if P points to something
+** contained within the buffer S.
+*/
+#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E)))
+
+
+/*
** Macros to determine whether the machine is big or little endian,
** and whether or not that determination is run-time or compile-time.
**
** For best performance, an attempt is made to guess at the byte-order
** using C-preprocessor macros. If that is unsuccessful, or if
-** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined
+** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined
** at run-time.
*/
-#ifndef SQLITE_BYTEORDER
+#ifndef SQLITE_BYTEORDER
# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64)
-# define SQLITE_BYTEORDER 1234
+# define SQLITE_BYTEORDER 1234
# elif defined(sparc) || defined(__ppc__) || \
defined(__ARMEB__) || defined(__AARCH64EB__)
-# define SQLITE_BYTEORDER 4321
-# else
-# define SQLITE_BYTEORDER 0
-# endif
+# define SQLITE_BYTEORDER 4321
+# else
+# define SQLITE_BYTEORDER 0
+# endif
#endif
-#if SQLITE_BYTEORDER==4321
+#if SQLITE_BYTEORDER==4321
# define SQLITE_BIGENDIAN 1
# define SQLITE_LITTLEENDIAN 0
# define SQLITE_UTF16NATIVE SQLITE_UTF16BE
-#elif SQLITE_BYTEORDER==1234
-# define SQLITE_BIGENDIAN 0
-# define SQLITE_LITTLEENDIAN 1
-# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
-#else
-# ifdef SQLITE_AMALGAMATION
- const int sqlite3one = 1;
-# else
- extern const int sqlite3one;
-# endif
+#elif SQLITE_BYTEORDER==1234
+# define SQLITE_BIGENDIAN 0
+# define SQLITE_LITTLEENDIAN 1
+# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
+#else
+# ifdef SQLITE_AMALGAMATION
+ const int sqlite3one = 1;
+# else
+ extern const int sqlite3one;
+# endif
# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0)
# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
@@ -14040,7 +14040,7 @@ typedef INT16_TYPE LogEst;
#define LARGEST_UINT64 (0xffffffff|(((u64)0xffffffff)<<32))
#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
-/*
+/*
** Round up a number to the next larger multiple of 8. This is used
** to force 8-byte alignment on 64-bit architectures.
*/
@@ -14140,7 +14140,7 @@ SQLITE_PRIVATE u32 sqlite3WhereTrace;
/*
** An instance of the following structure is used to store the busy-handler
-** callback for a given sqlite handle.
+** callback for a given sqlite handle.
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
@@ -14201,9 +14201,9 @@ struct BusyHandler {
/*
** The following value as a destructor means to use sqlite3DbFree().
-** The sqlite3DbFree() routine requires two parameters instead of the
-** one parameter that destructors normally want. So we have to introduce
-** this magic value that the code knows to handle differently. Any
+** The sqlite3DbFree() routine requires two parameters instead of the
+** one parameter that destructors normally want. So we have to introduce
+** this magic value that the code knows to handle differently. Any
** pointer will work here as long as it is distinct from SQLITE_STATIC
** and SQLITE_TRANSIENT.
*/
@@ -14227,19 +14227,19 @@ struct BusyHandler {
#define SQLITE_WSD const
#define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v)))
#define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config)
-SQLITE_API int sqlite3_wsd_init(int N, int J);
-SQLITE_API void *sqlite3_wsd_find(void *K, int L);
+SQLITE_API int sqlite3_wsd_init(int N, int J);
+SQLITE_API void *sqlite3_wsd_find(void *K, int L);
#else
- #define SQLITE_WSD
+ #define SQLITE_WSD
#define GLOBAL(t,v) v
#define sqlite3GlobalConfig sqlite3Config
#endif
/*
** The following macros are used to suppress compiler warnings and to
-** make it clear to human readers when a function parameter is deliberately
+** make it clear to human readers when a function parameter is deliberately
** left unused within the body of a function. This usually happens when
-** a function is called via a function pointer. For example the
+** a function is called via a function pointer. For example the
** implementation of an SQL aggregate step callback may not use the
** parameter indicating the number of arguments passed to the aggregate,
** if it knows that this is enforced elsewhere.
@@ -14285,7 +14285,7 @@ typedef struct Module Module;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
typedef struct ParseCleanup ParseCleanup;
-typedef struct PreUpdate PreUpdate;
+typedef struct PreUpdate PreUpdate;
typedef struct PrintfArguments PrintfArguments;
typedef struct RenameToken RenameToken;
typedef struct Returning Returning;
@@ -14340,16 +14340,16 @@ typedef struct With With;
#define MASKBIT32(n) (((unsigned int)1)<<(n))
#define ALLBITS ((Bitmask)-1)
-/* A VList object records a mapping between parameters/variables/wildcards
-** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
-** variable number associated with that parameter. See the format description
-** on the sqlite3VListAdd() routine for more information. A VList is really
-** just an array of integers.
-*/
-typedef int VList;
-
+/* A VList object records a mapping between parameters/variables/wildcards
+** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
+** variable number associated with that parameter. See the format description
+** on the sqlite3VListAdd() routine for more information. A VList is really
+** just an array of integers.
+*/
+typedef int VList;
+
/*
-** Defer sourcing vdbe.h and btree.h until after the "u8" and
+** Defer sourcing vdbe.h and btree.h until after the "u8" and
** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
** pointer types (i.e. FuncDef) defined above.
*/
@@ -14617,8 +14617,8 @@ SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*);
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
*/
-#ifndef SQLITE_BTREE_H
-#define SQLITE_BTREE_H
+#ifndef SQLITE_BTREE_H
+#define SQLITE_BTREE_H
/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
@@ -14643,7 +14643,7 @@ SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*);
typedef struct Btree Btree;
typedef struct BtCursor BtCursor;
typedef struct BtShared BtShared;
-typedef struct BtreePayload BtreePayload;
+typedef struct BtreePayload BtreePayload;
SQLITE_PRIVATE int sqlite3BtreeOpen(
@@ -14668,7 +14668,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree*,int);
+SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree*,int);
#if SQLITE_MAX_MMAP_SIZE>0
SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
#endif
@@ -14694,9 +14694,9 @@ SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*);
SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree);
-#ifndef SQLITE_OMIT_SHARED_CACHE
+#ifndef SQLITE_OMIT_SHARED_CACHE
SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
-#endif
+#endif
/* Savepoints are named, nestable SQL transactions mostly implemented */
/* in vdbe.c and pager.c See https://sqlite.org/lang_savepoint.html */
@@ -14765,38 +14765,38 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);
#define BTREE_DATA_VERSION 15 /* A virtual meta-value */
/*
-** Kinds of hints that can be passed into the sqlite3BtreeCursorHint()
-** interface.
-**
-** BTREE_HINT_RANGE (arguments: Expr*, Mem*)
-**
-** The first argument is an Expr* (which is guaranteed to be constant for
-** the lifetime of the cursor) that defines constraints on which rows
-** might be fetched with this cursor. The Expr* tree may contain
-** TK_REGISTER nodes that refer to values stored in the array of registers
-** passed as the second parameter. In other words, if Expr.op==TK_REGISTER
-** then the value of the node is the value in Mem[pExpr.iTable]. Any
-** TK_COLUMN node in the expression tree refers to the Expr.iColumn-th
-** column of the b-tree of the cursor. The Expr tree will not contain
-** any function calls nor subqueries nor references to b-trees other than
-** the cursor being hinted.
-**
-** The design of the _RANGE hint is aid b-tree implementations that try
-** to prefetch content from remote machines - to provide those
-** implementations with limits on what needs to be prefetched and thereby
-** reduce network bandwidth.
-**
-** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by
-** standard SQLite. The other hints are provided for extentions that use
-** the SQLite parser and code generator but substitute their own storage
-** engine.
-*/
-#define BTREE_HINT_RANGE 0 /* Range constraints on queries */
-
-/*
-** Values that may be OR'd together to form the argument to the
-** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint():
-**
+** Kinds of hints that can be passed into the sqlite3BtreeCursorHint()
+** interface.
+**
+** BTREE_HINT_RANGE (arguments: Expr*, Mem*)
+**
+** The first argument is an Expr* (which is guaranteed to be constant for
+** the lifetime of the cursor) that defines constraints on which rows
+** might be fetched with this cursor. The Expr* tree may contain
+** TK_REGISTER nodes that refer to values stored in the array of registers
+** passed as the second parameter. In other words, if Expr.op==TK_REGISTER
+** then the value of the node is the value in Mem[pExpr.iTable]. Any
+** TK_COLUMN node in the expression tree refers to the Expr.iColumn-th
+** column of the b-tree of the cursor. The Expr tree will not contain
+** any function calls nor subqueries nor references to b-trees other than
+** the cursor being hinted.
+**
+** The design of the _RANGE hint is aid b-tree implementations that try
+** to prefetch content from remote machines - to provide those
+** implementations with limits on what needs to be prefetched and thereby
+** reduce network bandwidth.
+**
+** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by
+** standard SQLite. The other hints are provided for extentions that use
+** the SQLite parser and code generator but substitute their own storage
+** engine.
+*/
+#define BTREE_HINT_RANGE 0 /* Range constraints on queries */
+
+/*
+** Values that may be OR'd together to form the argument to the
+** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint():
+**
** The BTREE_BULKLOAD flag is set on index cursors when the index is going
** to be filled with content that is already in sorted order.
**
@@ -14810,31 +14810,31 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);
#define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */
/*
-** Flags passed as the third argument to sqlite3BtreeCursor().
-**
-** For read-only cursors the wrFlag argument is always zero. For read-write
-** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or just
-** (BTREE_WRCSR). If the BTREE_FORDELETE bit is set, then the cursor will
-** only be used by SQLite for the following:
-**
-** * to seek to and then delete specific entries, and/or
-**
-** * to read values that will be used to create keys that other
-** BTREE_FORDELETE cursors will seek to and delete.
-**
-** The BTREE_FORDELETE flag is an optimization hint. It is not used by
-** by this, the native b-tree engine of SQLite, but it is available to
-** alternative storage engines that might be substituted in place of this
-** b-tree system. For alternative storage engines in which a delete of
-** the main table row automatically deletes corresponding index rows,
-** the FORDELETE flag hint allows those alternative storage engines to
-** skip a lot of work. Namely: FORDELETE cursors may treat all SEEK
-** and DELETE operations as no-ops, and any READ operation against a
-** FORDELETE cursor may return a null row: 0x01 0x00.
-*/
-#define BTREE_WRCSR 0x00000004 /* read-write cursor */
-#define BTREE_FORDELETE 0x00000008 /* Cursor is for seek/delete only */
-
+** Flags passed as the third argument to sqlite3BtreeCursor().
+**
+** For read-only cursors the wrFlag argument is always zero. For read-write
+** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or just
+** (BTREE_WRCSR). If the BTREE_FORDELETE bit is set, then the cursor will
+** only be used by SQLite for the following:
+**
+** * to seek to and then delete specific entries, and/or
+**
+** * to read values that will be used to create keys that other
+** BTREE_FORDELETE cursors will seek to and delete.
+**
+** The BTREE_FORDELETE flag is an optimization hint. It is not used by
+** by this, the native b-tree engine of SQLite, but it is available to
+** alternative storage engines that might be substituted in place of this
+** b-tree system. For alternative storage engines in which a delete of
+** the main table row automatically deletes corresponding index rows,
+** the FORDELETE flag hint allows those alternative storage engines to
+** skip a lot of work. Namely: FORDELETE cursors may treat all SEEK
+** and DELETE operations as no-ops, and any READ operation against a
+** FORDELETE cursor may return a null row: 0x01 0x00.
+*/
+#define BTREE_WRCSR 0x00000004 /* read-write cursor */
+#define BTREE_FORDELETE 0x00000008 /* Cursor is for seek/delete only */
+
SQLITE_PRIVATE int sqlite3BtreeCursor(
Btree*, /* BTree containing table to open */
Pgno iTable, /* Index of root page */
@@ -14842,13 +14842,13 @@ SQLITE_PRIVATE int sqlite3BtreeCursor(
struct KeyInfo*, /* First argument to compare function */
BtCursor *pCursor /* Space to write cursor structure */
);
-SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void);
+SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void);
SQLITE_PRIVATE int sqlite3BtreeCursorSize(void);
SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*);
-SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
-#ifdef SQLITE_ENABLE_CURSOR_HINTS
-SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...);
-#endif
+SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...);
+#endif
SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreeTableMoveto(
@@ -14864,29 +14864,29 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto(
);
SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*);
-SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags);
-
-/* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */
-#define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */
-#define BTREE_AUXDELETE 0x04 /* not the primary delete operation */
-#define BTREE_APPEND 0x08 /* Insert is likely an append */
+SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags);
+
+/* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */
+#define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */
+#define BTREE_AUXDELETE 0x04 /* not the primary delete operation */
+#define BTREE_APPEND 0x08 /* Insert is likely an append */
#define BTREE_PREFORMAT 0x80 /* Inserted data is a preformated cell */
-
-/* An instance of the BtreePayload object describes the content of a single
-** entry in either an index or table btree.
-**
-** Index btrees (used for indexes and also WITHOUT ROWID tables) contain
+
+/* An instance of the BtreePayload object describes the content of a single
+** entry in either an index or table btree.
+**
+** Index btrees (used for indexes and also WITHOUT ROWID tables) contain
** an arbitrary key and no data. These btrees have pKey,nKey set to the
** key and the pData,nData,nZero fields are uninitialized. The aMem,nMem
** fields give an array of Mem objects that are a decomposition of the key.
** The nMem field might be zero, indicating that no decomposition is available.
-**
-** Table btrees (used for rowid tables) contain an integer rowid used as
+**
+** Table btrees (used for rowid tables) contain an integer rowid used as
** the key and passed in the nKey field. The pKey field is zero.
-** pData,nData hold the content of the new entry. nZero extra zero bytes
-** are appended to the end of the content when constructing the entry.
+** pData,nData hold the content of the new entry. nZero extra zero bytes
+** are appended to the end of the content when constructing the entry.
** The aMem,nMem fields are uninitialized for table btrees.
-**
+**
** Field usage summary:
**
** Table BTrees Index Btrees
@@ -14899,49 +14899,49 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags);
** nData length of pData not used
** nZero extra zeros after pData not used
**
-** This object is used to pass information into sqlite3BtreeInsert(). The
-** same information used to be passed as five separate parameters. But placing
+** This object is used to pass information into sqlite3BtreeInsert(). The
+** same information used to be passed as five separate parameters. But placing
** the information into this object helps to keep the interface more
-** organized and understandable, and it also helps the resulting code to
-** run a little faster by using fewer registers for parameter passing.
-*/
-struct BtreePayload {
- const void *pKey; /* Key content for indexes. NULL for tables */
- sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */
+** organized and understandable, and it also helps the resulting code to
+** run a little faster by using fewer registers for parameter passing.
+*/
+struct BtreePayload {
+ const void *pKey; /* Key content for indexes. NULL for tables */
+ sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */
const void *pData; /* Data for tables. */
- sqlite3_value *aMem; /* First of nMem value in the unpacked pKey */
- u16 nMem; /* Number of aMem[] value. Might be zero */
- int nData; /* Size of pData. 0 if none. */
- int nZero; /* Extra zero data appended after pData,nData */
-};
-
-SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
- int flags, int seekResult);
+ sqlite3_value *aMem; /* First of nMem value in the unpacked pKey */
+ u16 nMem; /* Number of aMem[] value. Might be zero */
+ int nData; /* Size of pData. 0 if none. */
+ int nZero; /* Extra zero data appended after pData,nData */
+};
+
+SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
+ int flags, int seekResult);
SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
-SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags);
+SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags);
SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
-SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
+SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
+SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*);
SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*);
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
-SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
-#endif
-SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
-SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
-SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
+#endif
+SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
+SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
+SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,Pgno*aRoot,int nRoot,int,int*);
SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
-SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*);
+SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*);
-#ifndef SQLITE_OMIT_INCRBLOB
-SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*);
+#ifndef SQLITE_OMIT_INCRBLOB
+SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *);
-#endif
+#endif
SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
@@ -14957,7 +14957,7 @@ SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree*);
#ifndef NDEBUG
SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
#endif
-SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*);
+SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
@@ -14980,15 +14980,15 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64);
#ifndef SQLITE_OMIT_SHARED_CACHE
SQLITE_PRIVATE void sqlite3BtreeEnter(Btree*);
SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3*);
-SQLITE_PRIVATE int sqlite3BtreeSharable(Btree*);
-SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree*);
+SQLITE_PRIVATE int sqlite3BtreeSharable(Btree*);
+SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor*);
+SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree*);
#else
# define sqlite3BtreeEnter(X)
# define sqlite3BtreeEnterAll(X)
-# define sqlite3BtreeSharable(X) 0
-# define sqlite3BtreeEnterCursor(X)
-# define sqlite3BtreeConnectionCount(X) 1
+# define sqlite3BtreeSharable(X) 0
+# define sqlite3BtreeEnterCursor(X)
+# define sqlite3BtreeConnectionCount(X) 1
#endif
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
@@ -15013,7 +15013,7 @@ SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*);
#endif
-#endif /* SQLITE_BTREE_H */
+#endif /* SQLITE_BTREE_H */
/************** End of btree.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -15036,8 +15036,8 @@ SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*);
** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
*/
-#ifndef SQLITE_VDBE_H
-#define SQLITE_VDBE_H
+#ifndef SQLITE_VDBE_H
+#define SQLITE_VDBE_H
/* #include <stdio.h> */
/*
@@ -15051,7 +15051,7 @@ typedef struct Vdbe Vdbe;
** The names of the following types declared in vdbeInt.h are required
** for the VdbeOp definition.
*/
-typedef struct sqlite3_value Mem;
+typedef struct sqlite3_value Mem;
typedef struct SubProgram SubProgram;
/*
@@ -15062,7 +15062,7 @@ typedef struct SubProgram SubProgram;
struct VdbeOp {
u8 opcode; /* What operation to perform */
signed char p4type; /* One of the P4_xxx constants for p4 */
- u16 p5; /* Fifth parameter is an unsigned 16-bit integer */
+ u16 p5; /* Fifth parameter is an unsigned 16-bit integer */
int p1; /* First operand */
int p2; /* Second parameter (often the jump destination) */
int p3; /* The third parameter */
@@ -15080,11 +15080,11 @@ struct VdbeOp {
KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */
u32 *ai; /* Used when p4type is P4_INTARRAY */
SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
- Table *pTab; /* Used when p4type is P4_TABLE */
-#ifdef SQLITE_ENABLE_CURSOR_HINTS
- Expr *pExpr; /* Used when p4type is P4_EXPR */
-#endif
- int (*xAdvance)(BtCursor *, int);
+ Table *pTab; /* Used when p4type is P4_TABLE */
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+ Expr *pExpr; /* Used when p4type is P4_EXPR */
+#endif
+ int (*xAdvance)(BtCursor *, int);
} p4;
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
char *zComment; /* Comment to improve readability */
@@ -15109,7 +15109,7 @@ struct SubProgram {
int nOp; /* Elements in aOp[] */
int nMem; /* Number of memory cells required */
int nCsr; /* Number of cursors required */
- u8 *aOnce; /* Array of OP_Once flags */
+ u8 *aOnce; /* Array of OP_Once flags */
void *token; /* id that may be used to recursive triggers */
SubProgram *pNext; /* Next sub-program already visited */
};
@@ -15129,27 +15129,27 @@ typedef struct VdbeOpList VdbeOpList;
/*
** Allowed values of VdbeOp.p4type
*/
-#define P4_NOTUSED 0 /* The P4 parameter is not used */
-#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
-#define P4_STATIC (-1) /* Pointer to a static string */
-#define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */
-#define P4_INT32 (-3) /* P4 is a 32-bit signed integer */
-#define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */
-#define P4_ADVANCE (-5) /* P4 is a pointer to BtreeNext() or BtreePrev() */
-#define P4_TABLE (-6) /* P4 is a pointer to a Table structure */
-/* Above do not own any resources. Must free those below */
-#define P4_FREE_IF_LE (-7)
-#define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */
-#define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */
-#define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */
-#define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */
-#define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */
-#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */
-#define P4_REAL (-13) /* P4 is a 64-bit floating point value */
-#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */
-#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
-#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */
-#define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */
+#define P4_NOTUSED 0 /* The P4 parameter is not used */
+#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
+#define P4_STATIC (-1) /* Pointer to a static string */
+#define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */
+#define P4_INT32 (-3) /* P4 is a 32-bit signed integer */
+#define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */
+#define P4_ADVANCE (-5) /* P4 is a pointer to BtreeNext() or BtreePrev() */
+#define P4_TABLE (-6) /* P4 is a pointer to a Table structure */
+/* Above do not own any resources. Must free those below */
+#define P4_FREE_IF_LE (-7)
+#define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */
+#define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */
+#define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */
+#define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */
+#define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */
+#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */
+#define P4_REAL (-13) /* P4 is a 64-bit floating point value */
+#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */
+#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
+#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */
+#define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */
/* Error message codes for OP_Halt */
#define P5_ConstraintNotNull 1
@@ -15190,11 +15190,11 @@ typedef struct VdbeOpList VdbeOpList;
/************** Include opcodes.h in the middle of vdbe.h ********************/
/************** Begin file opcodes.h *****************************************/
/* Automatically generated. Do not edit */
-/* See the tool/mkopcodeh.tcl script for details */
-#define OP_Savepoint 0
-#define OP_AutoCommit 1
-#define OP_Transaction 2
-#define OP_SorterNext 3 /* jump */
+/* See the tool/mkopcodeh.tcl script for details */
+#define OP_Savepoint 0
+#define OP_AutoCommit 1
+#define OP_Transaction 2
+#define OP_SorterNext 3 /* jump */
#define OP_Prev 4 /* jump */
#define OP_Next 5 /* jump */
#define OP_Checkpoint 6
@@ -15234,21 +15234,21 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */
#define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */
#define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */
-#define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
-#define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+#define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+#define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
#define OP_RowSetRead 45 /* jump, synopsis: r[P3]=rowset(P1) */
#define OP_RowSetTest 46 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
#define OP_Program 47 /* jump */
#define OP_FkIfZero 48 /* jump, synopsis: if fkctr[P1]==0 goto P2 */
#define OP_IfPos 49 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
-#define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
-#define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
-#define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
-#define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */
-#define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */
-#define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */
-#define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */
-#define OP_Ge 57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */
+#define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
+#define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */
+#define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */
+#define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */
+#define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */
+#define OP_Ge 57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */
#define OP_ElseEq 58 /* jump, same as TK_ESCAPE */
#define OP_IfNotZero 59 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
#define OP_DecrJumpZero 60 /* jump, synopsis: if (--r[P1])==0 goto P2 */
@@ -15378,12 +15378,12 @@ typedef struct VdbeOpList VdbeOpList;
** comments following the "case" for each opcode in the vdbe.c
** are encoded into bitvectors as follows:
*/
-#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */
-#define OPFLG_IN1 0x02 /* in1: P1 is an input */
-#define OPFLG_IN2 0x04 /* in2: P2 is an input */
-#define OPFLG_IN3 0x08 /* in3: P3 is an input */
-#define OPFLG_OUT2 0x10 /* out2: P2 is an output */
-#define OPFLG_OUT3 0x20 /* out3: P3 is an output */
+#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */
+#define OPFLG_IN1 0x02 /* in1: P1 is an input */
+#define OPFLG_IN2 0x04 /* in2: P2 is an input */
+#define OPFLG_IN3 0x08 /* in3: P3 is an input */
+#define OPFLG_OUT2 0x10 /* out2: P2 is an output */
+#define OPFLG_OUT3 0x20 /* out3: P3 is an output */
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\
/* 8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\
@@ -15410,23 +15410,23 @@ typedef struct VdbeOpList VdbeOpList;
/* 176 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}
/* The resolve3P2Values() routine is able to run faster if it knows
-** the value of the largest JUMP opcode. The smaller the maximum
-** JUMP opcode the better, so the mkopcodeh.tcl script that
-** generated this include file strives to group all JUMP opcodes
-** together near the beginning of the list.
-*/
+** the value of the largest JUMP opcode. The smaller the maximum
+** JUMP opcode the better, so the mkopcodeh.tcl script that
+** generated this include file strives to group all JUMP opcodes
+** together near the beginning of the list.
+*/
#define SQLITE_MX_JUMP_OPCODE 63 /* Maximum JUMP opcode */
-
+
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
/*
-** Additional non-public SQLITE_PREPARE_* flags
-*/
-#define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */
-#define SQLITE_PREPARE_MASK 0x0f /* Mask of public flags */
-
-/*
+** Additional non-public SQLITE_PREPARE_* flags
+*/
+#define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */
+#define SQLITE_PREPARE_MASK 0x0f /* Mask of public flags */
+
+/*
** Prototypes for the VDBE interface. See comments on the implementation
** for a description of what each of these routines does.
*/
@@ -15435,22 +15435,22 @@ SQLITE_PRIVATE Parse *sqlite3VdbeParser(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
-SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe*,int);
-SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe*,int,const char*);
-SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...);
+SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe*,int);
+SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe*,int,const char*);
+SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...);
SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall(Parse*,int,int,int,int,const FuncDef*,int);
-SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe*,int);
-#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
-SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N);
-SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p);
-#else
-# define sqlite3VdbeVerifyNoMallocRequired(A,B)
-# define sqlite3VdbeVerifyNoResultRow(A)
-#endif
+SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe*,int);
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
+SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N);
+SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p);
+#else
+# define sqlite3VdbeVerifyNoMallocRequired(A,B)
+# define sqlite3VdbeVerifyNoResultRow(A)
+#endif
#if defined(SQLITE_DEBUG)
SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int);
#else
@@ -15480,10 +15480,10 @@ SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8);
SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
-SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
+SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr);
-SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
+SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 mask, int);
@@ -15491,13 +15491,13 @@ SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 ma
# define sqlite3VdbeReleaseRegisters(P,A,N,M,F)
#endif
SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
-SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);
+SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);
SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*);
SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*);
+SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*);
@@ -15514,8 +15514,8 @@ SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
-SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8);
+SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe*);
+SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8);
#ifdef SQLITE_ENABLE_NORMALIZE
SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3*,Vdbe*,const char*);
SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*);
@@ -15533,7 +15533,7 @@ SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*);
SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
-SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*);
+SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*);
typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
@@ -15541,11 +15541,11 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*);
-SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*);
+SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*);
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*);
#endif
-
+
/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
** each VDBE opcode.
**
@@ -15645,7 +15645,7 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const ch
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*);
#endif
-#endif /* SQLITE_VDBE_H */
+#endif /* SQLITE_VDBE_H */
/************** End of vdbe.h ************************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -15679,8 +15679,8 @@ struct PgHdr {
sqlite3_pcache_page *pPage; /* Pcache object page handle */
void *pData; /* Page data */
void *pExtra; /* Extra content */
- PCache *pCache; /* PRIVATE: Cache that owns this page */
- PgHdr *pDirty; /* Transient list of dirty sorted by pgno */
+ PCache *pCache; /* PRIVATE: Cache that owns this page */
+ PgHdr *pDirty; /* Transient list of dirty sorted by pgno */
Pager *pPager; /* The pager this page is part of */
Pgno pgno; /* Page number for this page */
#ifdef SQLITE_CHECK_PAGES
@@ -15690,14 +15690,14 @@ struct PgHdr {
/**********************************************************************
** Elements above, except pCache, are public. All that follow are
- ** private to pcache.c and should not be accessed by other modules.
- ** pCache is grouped with the public elements for efficiency.
+ ** private to pcache.c and should not be accessed by other modules.
+ ** pCache is grouped with the public elements for efficiency.
*/
i16 nRef; /* Number of users of this page */
PgHdr *pDirtyNext; /* Next element in list of dirty pages */
PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */
- /* NB: pDirtyNext and pDirtyPrev are undefined if the
- ** PgHdr object is not dirty */
+ /* NB: pDirtyNext and pDirtyPrev are undefined if the
+ ** PgHdr object is not dirty */
};
/* Bit values for PgHdr.flags */
@@ -15706,11 +15706,11 @@ struct PgHdr {
#define PGHDR_WRITEABLE 0x004 /* Journaled and ready to modify */
#define PGHDR_NEED_SYNC 0x008 /* Fsync the rollback journal before
** writing this page to the database */
-#define PGHDR_DONT_WRITE 0x010 /* Do not write content to disk */
-#define PGHDR_MMAP 0x020 /* This is an mmap page object */
+#define PGHDR_DONT_WRITE 0x010 /* Do not write content to disk */
+#define PGHDR_MMAP 0x020 /* This is an mmap page object */
+
+#define PGHDR_WAL_APPEND 0x040 /* Appended to wal file */
-#define PGHDR_WAL_APPEND 0x040 /* Appended to wal file */
-
/* Initialize and shutdown the page cache subsystem */
SQLITE_PRIVATE int sqlite3PcacheInitialize(void);
SQLITE_PRIVATE void sqlite3PcacheShutdown(void);
@@ -15753,7 +15753,7 @@ SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache
SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */
SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */
SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */
-SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache*);
+SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache*);
/* Change a page number. Used by incr-vacuum. */
SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr*, Pgno);
@@ -15792,11 +15792,11 @@ SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*);
SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *));
#endif
-#if defined(SQLITE_DEBUG)
-/* Check invariants on a PgHdr object */
-SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr*);
-#endif
-
+#if defined(SQLITE_DEBUG)
+/* Check invariants on a PgHdr object */
+SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr*);
+#endif
+
/* Set and get the suggested cache-size for the specified pager-cache.
**
** If no global maximum is configured, then the system attempts to limit
@@ -15808,13 +15808,13 @@ SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *, int);
SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *);
#endif
-/* Set or get the suggested spill-size for the specified pager-cache.
-**
-** The spill-size is the minimum number of pages in cache before the cache
-** will attempt to spill dirty pages by calling xStress.
-*/
-SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *, int);
-
+/* Set or get the suggested spill-size for the specified pager-cache.
+**
+** The spill-size is the minimum number of pages in cache before the cache
+** will attempt to spill dirty pages by calling xStress.
+*/
+SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *, int);
+
/* Free up as much memory as possible from the page cache */
SQLITE_PRIVATE void sqlite3PcacheShrink(PCache*);
@@ -15833,9 +15833,9 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
SQLITE_PRIVATE int sqlite3HeaderSizePcache(void);
SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);
-/* Number of dirty pages as a percentage of the configured cache size */
-SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*);
-
+/* Number of dirty pages as a percentage of the configured cache size */
+SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*);
+
#ifdef SQLITE_DIRECT_OVERFLOW_READ
SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
#endif
@@ -15889,8 +15889,8 @@ SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
** This file contains pre-processor directives related to operating system
** detection and/or setup.
*/
-#ifndef SQLITE_OS_SETUP_H
-#define SQLITE_OS_SETUP_H
+#ifndef SQLITE_OS_SETUP_H
+#define SQLITE_OS_SETUP_H
/*
** Figure out if we are dealing with Unix, Windows, or some other operating
@@ -15930,7 +15930,7 @@ SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
# endif
#endif
-#endif /* SQLITE_OS_SETUP_H */
+#endif /* SQLITE_OS_SETUP_H */
/************** End of os_setup.h ********************************************/
/************** Continuing where we left off in os.h *************************/
@@ -15949,13 +15949,13 @@ SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
#endif
/*
-** The default size of a disk sector
-*/
-#ifndef SQLITE_DEFAULT_SECTOR_SIZE
-# define SQLITE_DEFAULT_SECTOR_SIZE 4096
-#endif
-
-/*
+** The default size of a disk sector
+*/
+#ifndef SQLITE_DEFAULT_SECTOR_SIZE
+# define SQLITE_DEFAULT_SECTOR_SIZE 4096
+#endif
+
+/*
** Temporary files are named starting with this prefix followed by 16 random
** alphanumeric characters, and no file extension. They are stored in the
** OS's standard temporary file directory, and are deleted prior to exit.
@@ -15981,29 +15981,29 @@ SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
#endif
/*
-** The following values may be passed as the second argument to
-** sqlite3OsLock(). The various locks exhibit the following semantics:
-**
-** SHARED: Any number of processes may hold a SHARED lock simultaneously.
-** RESERVED: A single process may hold a RESERVED lock on a file at
-** any time. Other processes may hold and obtain new SHARED locks.
-** PENDING: A single process may hold a PENDING lock on a file at
-** any one time. Existing SHARED locks may persist, but no new
-** SHARED locks may be obtained by other processes.
-** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks.
-**
-** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a
-** process that requests an EXCLUSIVE lock may actually obtain a PENDING
-** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to
-** sqlite3OsLock().
-*/
-#define NO_LOCK 0
-#define SHARED_LOCK 1
-#define RESERVED_LOCK 2
-#define PENDING_LOCK 3
-#define EXCLUSIVE_LOCK 4
-
-/*
+** The following values may be passed as the second argument to
+** sqlite3OsLock(). The various locks exhibit the following semantics:
+**
+** SHARED: Any number of processes may hold a SHARED lock simultaneously.
+** RESERVED: A single process may hold a RESERVED lock on a file at
+** any time. Other processes may hold and obtain new SHARED locks.
+** PENDING: A single process may hold a PENDING lock on a file at
+** any one time. Existing SHARED locks may persist, but no new
+** SHARED locks may be obtained by other processes.
+** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks.
+**
+** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a
+** process that requests an EXCLUSIVE lock may actually obtain a PENDING
+** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to
+** sqlite3OsLock().
+*/
+#define NO_LOCK 0
+#define SHARED_LOCK 1
+#define RESERVED_LOCK 2
+#define PENDING_LOCK 3
+#define EXCLUSIVE_LOCK 4
+
+/*
** File Locking Notes: (Mostly about windows but also some info for Unix)
**
** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
@@ -16075,7 +16075,7 @@ SQLITE_PRIVATE int sqlite3OsInit(void);
/*
** Functions for accessing sqlite3_file methods
*/
-SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*);
+SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*);
SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size);
@@ -16089,12 +16089,12 @@ SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*);
#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0
SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id);
SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
-#ifndef SQLITE_OMIT_WAL
+#ifndef SQLITE_OMIT_WAL
SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int);
SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id);
SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int);
-#endif /* SQLITE_OMIT_WAL */
+#endif /* SQLITE_OMIT_WAL */
SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **);
SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *);
@@ -16114,7 +16114,7 @@ SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *);
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int);
-SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*);
+SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*);
SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*);
/*
@@ -16122,7 +16122,7 @@ SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*);
** sqlite3_malloc() to obtain space for the file-handle structure.
*/
SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*);
-SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *);
+SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *);
#endif /* _SQLITE_OS_H_ */
@@ -16205,38 +16205,38 @@ SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
/************** End of mutex.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
-/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default
-** synchronous setting to EXTRA. It is no longer supported.
-*/
-#ifdef SQLITE_EXTRA_DURABLE
-# warning Use SQLITE_DEFAULT_SYNCHRONOUS=3 instead of SQLITE_EXTRA_DURABLE
-# define SQLITE_DEFAULT_SYNCHRONOUS 3
-#endif
-
-/*
-** Default synchronous levels.
-**
-** Note that (for historcal reasons) the PAGER_SYNCHRONOUS_* macros differ
-** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1.
-**
-** PAGER_SYNCHRONOUS DEFAULT_SYNCHRONOUS
-** OFF 1 0
-** NORMAL 2 1
-** FULL 3 2
-** EXTRA 4 3
-**
-** The "PRAGMA synchronous" statement also uses the zero-based numbers.
-** In other words, the zero-based numbers are used for all external interfaces
-** and the one-based values are used internally.
-*/
-#ifndef SQLITE_DEFAULT_SYNCHRONOUS
-# define SQLITE_DEFAULT_SYNCHRONOUS 2
-#endif
-#ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS
-# define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS
-#endif
-
-/*
+/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default
+** synchronous setting to EXTRA. It is no longer supported.
+*/
+#ifdef SQLITE_EXTRA_DURABLE
+# warning Use SQLITE_DEFAULT_SYNCHRONOUS=3 instead of SQLITE_EXTRA_DURABLE
+# define SQLITE_DEFAULT_SYNCHRONOUS 3
+#endif
+
+/*
+** Default synchronous levels.
+**
+** Note that (for historcal reasons) the PAGER_SYNCHRONOUS_* macros differ
+** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1.
+**
+** PAGER_SYNCHRONOUS DEFAULT_SYNCHRONOUS
+** OFF 1 0
+** NORMAL 2 1
+** FULL 3 2
+** EXTRA 4 3
+**
+** The "PRAGMA synchronous" statement also uses the zero-based numbers.
+** In other words, the zero-based numbers are used for all external interfaces
+** and the one-based values are used internally.
+*/
+#ifndef SQLITE_DEFAULT_SYNCHRONOUS
+# define SQLITE_DEFAULT_SYNCHRONOUS 2
+#endif
+#ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS
+# define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS
+#endif
+
+/*
** Each database file to be accessed by the system is an instance
** of the following structure. There are normally two of these structures
** in the sqlite.aDb[] array. aDb[0] is the main database file and
@@ -16244,10 +16244,10 @@ SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
** databases may be attached.
*/
struct Db {
- char *zDbSName; /* Name of this database. (schema name, not filename) */
+ char *zDbSName; /* Name of this database. (schema name, not filename) */
Btree *pBt; /* The B*Tree structure for this database file */
u8 safety_level; /* How aggressive at syncing data to disk */
- u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */
+ u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */
Schema *pSchema; /* Pointer to database schema (possibly shared) */
};
@@ -16258,7 +16258,7 @@ struct Db {
** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing.
** In shared cache mode, a single Schema object can be shared by multiple
** Btrees that refer to the same underlying BtShared object.
-**
+**
** Schema objects are automatically deallocated when the last Btree that
** references them is destroyed. The TEMP Schema is manually freed by
** sqlite3_close().
@@ -16283,7 +16283,7 @@ struct Schema {
};
/*
-** These macros can be used to test, set, or clear bits in the
+** These macros can be used to test, set, or clear bits in the
** Db.pSchema->flags field.
*/
#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P))
@@ -16303,7 +16303,7 @@ struct Schema {
*/
#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */
#define DB_UnresetViews 0x0002 /* Some views have defined column names */
-#define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */
+#define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */
/*
** The number of different kinds of things that can be limited
@@ -16357,13 +16357,13 @@ struct Schema {
** SQLITE_OMIT_TWOSIZE_LOOKASIDE.
*/
struct Lookaside {
- u32 bDisable; /* Only operate the lookaside when zero */
+ u32 bDisable; /* Only operate the lookaside when zero */
u16 sz; /* Size of each buffer in bytes */
u16 szTrue; /* True value of sz, even if disabled */
u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */
- u32 nSlot; /* Number of lookaside slots allocated */
- u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */
- LookasideSlot *pInit; /* List of buffers not previously used */
+ u32 nSlot; /* Number of lookaside slots allocated */
+ u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */
+ LookasideSlot *pInit; /* List of buffers not previously used */
LookasideSlot *pFree; /* List of available buffers */
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
LookasideSlot *pSmallInit; /* List of small buffers not prediously used */
@@ -16390,16 +16390,16 @@ struct LookasideSlot {
#endif
/*
-** A hash table for built-in function definitions. (Application-defined
-** functions use a regular table table from hash.h.)
+** A hash table for built-in function definitions. (Application-defined
+** functions use a regular table table from hash.h.)
**
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH()
** macro to compute a hash on the function name.
*/
-#define SQLITE_FUNC_HASH_SZ 23
+#define SQLITE_FUNC_HASH_SZ 23
struct FuncDefHash {
- FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
+ FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
};
#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
@@ -16441,16 +16441,16 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
const char*);
#endif
-#ifndef SQLITE_OMIT_DEPRECATED
-/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing
-** in the style of sqlite3_trace()
-*/
+#ifndef SQLITE_OMIT_DEPRECATED
+/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing
+** in the style of sqlite3_trace()
+*/
#define SQLITE_TRACE_LEGACY 0x40 /* Use the legacy xTrace */
#define SQLITE_TRACE_XPROFILE 0x80 /* Use the legacy xProfile */
-#else
+#else
#define SQLITE_TRACE_LEGACY 0
#define SQLITE_TRACE_XPROFILE 0
-#endif /* SQLITE_OMIT_DEPRECATED */
+#endif /* SQLITE_OMIT_DEPRECATED */
#define SQLITE_TRACE_NONLEGACY_MASK 0x0f /* Normal flags */
/*
@@ -16458,7 +16458,7 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
** databases plus 2 for "main" and "temp".
*/
#define SQLITE_MAX_DB (SQLITE_MAX_ATTACHED+2)
-
+
/*
** Each database connection is an instance of the following structure.
*/
@@ -16469,29 +16469,29 @@ struct sqlite3 {
sqlite3_mutex *mutex; /* Connection mutex */
Db *aDb; /* All backends */
int nDb; /* Number of backends currently in use */
- u32 mDbFlags; /* flags recording internal state */
+ u32 mDbFlags; /* flags recording internal state */
u64 flags; /* flags settable by pragmas. See below */
i64 lastRowid; /* ROWID of most recent insert (see above) */
i64 szMmap; /* Default mmap_size setting */
- u32 nSchemaLock; /* Do not reset the schema when non-zero */
+ u32 nSchemaLock; /* Do not reset the schema when non-zero */
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
int errCode; /* Most recent error code (SQLITE_*) */
int errMask; /* & result codes with this before returning */
- int iSysErrno; /* Errno value from last system error */
+ int iSysErrno; /* Errno value from last system error */
u32 dbOptFlags; /* Flags to enable/disable optimizations */
u8 enc; /* Text encoding */
u8 autoCommit; /* The auto-commit flag. */
u8 temp_store; /* 1: file 2: memory 0: default */
u8 mallocFailed; /* True if we have seen a malloc failure */
- u8 bBenignMalloc; /* Do not require OOMs if true */
+ u8 bBenignMalloc; /* Do not require OOMs if true */
u8 dfltLockMode; /* Default locking-mode for attached dbs */
signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */
u8 suppressErr; /* Do not issue error messages if true */
u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
- u8 mTrace; /* zero or more SQLITE_TRACE flags */
+ u8 mTrace; /* zero or more SQLITE_TRACE flags */
u8 noSharedCache; /* True if no shared-cache backends */
- u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */
+ u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */
u8 eOpenState; /* Current condition of the connection */
int nextPagesize; /* Pagesize after VACUUM if >0 */
i64 nChange; /* Value returned by sqlite3_changes() */
@@ -16523,9 +16523,9 @@ struct sqlite3 {
void (*xProfile)(void*,const char*,u64); /* Profiling function */
void *pProfileArg; /* Argument to profile function */
#endif
- void *pCommitArg; /* Argument to xCommitCallback() */
+ void *pCommitArg; /* Argument to xCommitCallback() */
int (*xCommitCallback)(void*); /* Invoked at every commit. */
- void *pRollbackArg; /* Argument to xRollbackCallback() */
+ void *pRollbackArg; /* Argument to xRollbackCallback() */
void (*xRollbackCallback)(void*); /* Invoked at every commit. */
void *pUpdateArg;
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
@@ -16533,13 +16533,13 @@ struct sqlite3 {
void (*xAutovacDestr)(void*); /* Destructor for pAutovacPAgesArg */
unsigned int (*xAutovacPages)(void*,const char*,u32,u32,u32);
Parse *pParse; /* Current parse */
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
- void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
- void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
- void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
- );
- PreUpdate *pPreUpdate; /* Context for active pre-update callback */
-#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
+ void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
+ void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
+ );
+ PreUpdate *pPreUpdate; /* Context for active pre-update callback */
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
#ifndef SQLITE_OMIT_WAL
int (*xWalCallback)(void *, sqlite3 *, const char *, int);
void *pWalArg;
@@ -16567,9 +16567,9 @@ struct sqlite3 {
Hash aModule; /* populated by sqlite3_create_module() */
VtabCtx *pVtabCtx; /* Context for active vtab connect/create */
VTable **aVTrans; /* Virtual tables with open transactions */
- VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
+ VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
#endif
- Hash aFunc; /* Hash table of connection functions */
+ Hash aFunc; /* Hash table of connection functions */
Hash aCollSeq; /* All collating sequences */
BusyHandler busyHandler; /* Busy callback */
Db aDbStatic[2]; /* Static space for the 2 default backends */
@@ -16583,7 +16583,7 @@ struct sqlite3 {
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
/* The following variables are all protected by the STATIC_MAIN
- ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
+ ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
**
** When X.pUnlockConnection==Y, that means that X is waiting for Y to
** unlock so that it can proceed.
@@ -16618,39 +16618,39 @@ struct sqlite3 {
/*
** Possible values for the sqlite3.flags.
-**
-** Value constraints (enforced via assert()):
-** SQLITE_FullFSync == PAGER_FULLFSYNC
-** SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC
-** SQLITE_CacheSpill == PAGER_CACHE_SPILL
+**
+** Value constraints (enforced via assert()):
+** SQLITE_FullFSync == PAGER_FULLFSYNC
+** SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC
+** SQLITE_CacheSpill == PAGER_CACHE_SPILL
*/
#define SQLITE_WriteSchema 0x00000001 /* OK to update SQLITE_SCHEMA */
-#define SQLITE_LegacyFileFmt 0x00000002 /* Create new databases in format 1 */
-#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */
-#define SQLITE_FullFSync 0x00000008 /* Use full fsync on the backend */
-#define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */
-#define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */
+#define SQLITE_LegacyFileFmt 0x00000002 /* Create new databases in format 1 */
+#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */
+#define SQLITE_FullFSync 0x00000008 /* Use full fsync on the backend */
+#define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */
+#define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */
#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */
#define SQLITE_TrustedSchema 0x00000080 /* Allow unsafe functions and
** vtabs in the schema definition */
#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */
/* result set is empty */
-#define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */
-#define SQLITE_ReadUncommit 0x00000400 /* READ UNCOMMITTED in shared-cache */
-#define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */
-#define SQLITE_ReverseOrder 0x00001000 /* Reverse unordered SELECTs */
-#define SQLITE_RecTriggers 0x00002000 /* Enable recursive triggers */
-#define SQLITE_ForeignKeys 0x00004000 /* Enforce foreign key constraints */
-#define SQLITE_AutoIndex 0x00008000 /* Enable automatic indexes */
-#define SQLITE_LoadExtension 0x00010000 /* Enable load_extension */
-#define SQLITE_LoadExtFunc 0x00020000 /* Enable load_extension() SQL func */
-#define SQLITE_EnableTrigger 0x00040000 /* True to enable triggers */
-#define SQLITE_DeferFKs 0x00080000 /* Defer all FK constraints */
-#define SQLITE_QueryOnly 0x00100000 /* Disable database changes */
-#define SQLITE_CellSizeCk 0x00200000 /* Check btree cell sizes on load */
-#define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */
-#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/
-#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */
+#define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */
+#define SQLITE_ReadUncommit 0x00000400 /* READ UNCOMMITTED in shared-cache */
+#define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */
+#define SQLITE_ReverseOrder 0x00001000 /* Reverse unordered SELECTs */
+#define SQLITE_RecTriggers 0x00002000 /* Enable recursive triggers */
+#define SQLITE_ForeignKeys 0x00004000 /* Enforce foreign key constraints */
+#define SQLITE_AutoIndex 0x00008000 /* Enable automatic indexes */
+#define SQLITE_LoadExtension 0x00010000 /* Enable load_extension */
+#define SQLITE_LoadExtFunc 0x00020000 /* Enable load_extension() SQL func */
+#define SQLITE_EnableTrigger 0x00040000 /* True to enable triggers */
+#define SQLITE_DeferFKs 0x00080000 /* Defer all FK constraints */
+#define SQLITE_QueryOnly 0x00100000 /* Disable database changes */
+#define SQLITE_CellSizeCk 0x00200000 /* Check btree cell sizes on load */
+#define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */
+#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/
+#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */
#define SQLITE_ResetDatabase 0x02000000 /* Reset the database */
#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */
#define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/
@@ -16663,28 +16663,28 @@ struct sqlite3 {
/* the count using a callback. */
#define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */
-/* Flags used only if debugging */
-#ifdef SQLITE_DEBUG
+/* Flags used only if debugging */
+#ifdef SQLITE_DEBUG
#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
#define SQLITE_VdbeTrace HI(0x0400000) /* True to trace VDBE execution */
#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */
#define SQLITE_VdbeEQP HI(0x1000000) /* Debug EXPLAIN QUERY PLAN */
#define SQLITE_ParserTrace HI(0x2000000) /* PRAGMA parser_trace=ON */
-#endif
+#endif
/*
-** Allowed values for sqlite3.mDbFlags
-*/
-#define DBFLAG_SchemaChange 0x0001 /* Uncommitted Hash table changes */
-#define DBFLAG_PreferBuiltin 0x0002 /* Preference to built-in funcs */
-#define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */
+** Allowed values for sqlite3.mDbFlags
+*/
+#define DBFLAG_SchemaChange 0x0001 /* Uncommitted Hash table changes */
+#define DBFLAG_PreferBuiltin 0x0002 /* Preference to built-in funcs */
+#define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */
#define DBFLAG_VacuumInto 0x0008 /* Currently running VACUUM INTO */
#define DBFLAG_SchemaKnownOk 0x0010 /* Schema is known to be valid */
#define DBFLAG_InternalFunc 0x0020 /* Allow use of internal functions */
#define DBFLAG_EncodingFixed 0x0040 /* No longer possible to change enc. */
-
-/*
+
+/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
@@ -16737,27 +16737,27 @@ struct sqlite3 {
/*
** Each SQL function is defined by an instance of the following
-** structure. For global built-in functions (ex: substr(), max(), count())
-** a pointer to this structure is held in the sqlite3BuiltinFunctions object.
-** For per-connection application-defined functions, a pointer to this
-** structure is held in the db->aHash hash table.
-**
-** The u.pHash field is used by the global built-ins. The u.pDestructor
-** field is used by per-connection app-def functions.
+** structure. For global built-in functions (ex: substr(), max(), count())
+** a pointer to this structure is held in the sqlite3BuiltinFunctions object.
+** For per-connection application-defined functions, a pointer to this
+** structure is held in the db->aHash hash table.
+**
+** The u.pHash field is used by the global built-ins. The u.pDestructor
+** field is used by per-connection app-def functions.
*/
struct FuncDef {
- i8 nArg; /* Number of arguments. -1 means unlimited */
+ i8 nArg; /* Number of arguments. -1 means unlimited */
u32 funcFlags; /* Some combination of SQLITE_FUNC_* */
void *pUserData; /* User data parameter */
FuncDef *pNext; /* Next function with same name */
- void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
- void (*xFinalize)(sqlite3_context*); /* Agg finalizer */
+ void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
+ void (*xFinalize)(sqlite3_context*); /* Agg finalizer */
void (*xValue)(sqlite3_context*); /* Current agg value */
void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */
- const char *zName; /* SQL name of the function. */
- union {
- FuncDef *pHash; /* Next with a different name but the same hash */
- FuncDestructor *pDestructor; /* Reference counted destructor function */
+ const char *zName; /* SQL name of the function. */
+ union {
+ FuncDef *pHash; /* Next with a different name but the same hash */
+ FuncDestructor *pDestructor; /* Reference counted destructor function */
} u; /* pHash if SQLITE_FUNC_BUILTIN, pDestructor otherwise */
};
@@ -16765,7 +16765,7 @@ struct FuncDef {
** This structure encapsulates a user-function destructor callback (as
** configured using create_function_v2()) and a reference counter. When
** create_function_v2() is called to create a function with a destructor,
-** a single object of this type is allocated. FuncDestructor.nRef is set to
+** a single object of this type is allocated. FuncDestructor.nRef is set to
** the number of FuncDef objects created (either 1 or 3, depending on whether
** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor
** member of each of the new FuncDef objects is set to point to the allocated
@@ -16783,11 +16783,11 @@ struct FuncDestructor {
/*
** Possible values for FuncDef.flags. Note that the _LENGTH and _TYPEOF
-** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. And
-** SQLITE_FUNC_CONSTANT must be the same as SQLITE_DETERMINISTIC. There
+** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. And
+** SQLITE_FUNC_CONSTANT must be the same as SQLITE_DETERMINISTIC. There
** are assert() statements in the code to verify this.
-**
-** Value constraints (enforced via assert()):
+**
+** Value constraints (enforced via assert()):
** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg
** SQLITE_FUNC_ANYORDER == NC_OrderAgg == SF_OrderByReqd
** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG
@@ -16795,24 +16795,24 @@ struct FuncDestructor {
** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API
** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API
** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS
-** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API
-*/
-#define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
-#define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */
-#define SQLITE_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */
-#define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */
-#define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/
-#define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */
-#define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */
-#define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */
+** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API
+*/
+#define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
+#define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */
+#define SQLITE_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */
+#define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */
+#define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/
+#define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */
+#define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */
+#define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */
/* 0x0200 -- available for reuse */
-#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
-#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
-#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
-#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
- ** single query - might change over time */
+#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
+#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
+#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
+#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
+ ** single query - might change over time */
#define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */
-#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
+#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
@@ -16836,10 +16836,10 @@ struct FuncDestructor {
** used to create the initializers for the FuncDef structures.
**
** FUNCTION(zName, nArg, iArg, bNC, xFunc)
-** Used to create a scalar function definition of a function zName
+** Used to create a scalar function definition of a function zName
** implemented by C function xFunc that accepts nArg arguments. The
** value passed as iArg is cast to a (void*) and made available
-** as the user-data (sqlite3_user_data()) for the function. If
+** as the user-data (sqlite3_user_data()) for the function. If
** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
**
** VFUNCTION(zName, nArg, iArg, bNC, xFunc)
@@ -16861,22 +16861,22 @@ struct FuncDestructor {
** parameter determines the function id. The mFlags parameter is
** optional SQLITE_FUNC_ flags for this function.
**
-** DFUNCTION(zName, nArg, iArg, bNC, xFunc)
-** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and
-** adds the SQLITE_FUNC_SLOCHNG flag. Used for date & time functions
-** and functions like sqlite_version() that can change, but not during
-** a single query. The iArg is ignored. The user-data is always set
-** to a NULL pointer. The bNC parameter is not used.
-**
+** DFUNCTION(zName, nArg, iArg, bNC, xFunc)
+** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and
+** adds the SQLITE_FUNC_SLOCHNG flag. Used for date & time functions
+** and functions like sqlite_version() that can change, but not during
+** a single query. The iArg is ignored. The user-data is always set
+** to a NULL pointer. The bNC parameter is not used.
+**
** MFUNCTION(zName, nArg, xPtr, xFunc)
** For math-library functions. xPtr is an arbitrary pointer.
**
-** PURE_DATE(zName, nArg, iArg, bNC, xFunc)
-** Used for "pure" date/time functions, this macro is like DFUNCTION
-** except that it does set the SQLITE_FUNC_CONSTANT flags. iArg is
+** PURE_DATE(zName, nArg, iArg, bNC, xFunc)
+** Used for "pure" date/time functions, this macro is like DFUNCTION
+** except that it does set the SQLITE_FUNC_CONSTANT flags. iArg is
** ignored and the user-data for these functions is set to an
-** arbitrary non-NULL pointer. The bNC parameter is not used.
-**
+** arbitrary non-NULL pointer. The bNC parameter is not used.
+**
** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)
** Used to create an aggregate function definition implemented by
** the C functions xStep and xFinal. The first four parameters
@@ -16890,8 +16890,8 @@ struct FuncDestructor {
** FUNCTION().
**
** LIKEFUNC(zName, nArg, pArg, flags)
-** Used to create a scalar function definition of a function zName
-** that accepts nArg arguments and is implemented by a call to C
+** Used to create a scalar function definition of a function zName
+** that accepts nArg arguments and is implemented by a call to C
** function likeFunc. Argument pArg is cast to a (void *) and made
** available as the function user-data (sqlite3_user_data()). The
** FuncDef.flags variable is set to the value passed as the flags
@@ -16919,10 +16919,10 @@ struct FuncDestructor {
SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \
SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
-#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
+#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
0, 0, xFunc, 0, 0, 0, #zName, {0} }
-#define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \
+#define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|\
SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
(void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} }
@@ -16979,7 +16979,7 @@ struct Module {
int nRefModule; /* Number of pointers to this object */
void *pAux; /* pAux passed to create_module() */
void (*xDestroy)(void *); /* Module destructor function */
- Table *pEpoTab; /* Eponymous table for this module */
+ Table *pEpoTab; /* Eponymous table for this module */
};
/*
@@ -17076,14 +17076,14 @@ struct CollSeq {
*/
#define SQLITE_SO_ASC 0 /* Sort in ascending order */
#define SQLITE_SO_DESC 1 /* Sort in ascending order */
-#define SQLITE_SO_UNDEFINED -1 /* No sort order specified */
+#define SQLITE_SO_UNDEFINED -1 /* No sort order specified */
/*
** Column affinity types.
**
** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and
** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve
-** the speed a little by numbering the values consecutively.
+** the speed a little by numbering the values consecutively.
**
** But rather than start with 0 or 1, we begin with 'A'. That way,
** when multiple affinity types are concatenated into a string and
@@ -17103,7 +17103,7 @@ struct CollSeq {
/*
** The SQLITE_AFF_MASK values masks off the significant bits of an
-** affinity value.
+** affinity value.
*/
#define SQLITE_AFF_MASK 0x47
@@ -17122,20 +17122,20 @@ struct CollSeq {
/*
** An object of this type is created for each virtual table present in
-** the database schema.
+** the database schema.
**
** If the database schema is shared, then there is one instance of this
** structure for each database connection (sqlite3*) that uses the shared
** schema. This is because each database connection requires its own unique
-** instance of the sqlite3_vtab* handle used to access the virtual table
-** implementation. sqlite3_vtab* handles can not be shared between
-** database connections, even when the rest of the in-memory database
+** instance of the sqlite3_vtab* handle used to access the virtual table
+** implementation. sqlite3_vtab* handles can not be shared between
+** database connections, even when the rest of the in-memory database
** schema is shared, as the implementation often stores the database
** connection handle passed to it via the xConnect() or xCreate() method
** during initialization internally. This database connection handle may
-** then be used by the virtual table implementation to access real tables
-** within the database. So that they appear as part of the callers
-** transaction, these accesses need to be made via the same database
+** then be used by the virtual table implementation to access real tables
+** within the database. So that they appear as part of the callers
+** transaction, these accesses need to be made via the same database
** connection as that used to execute SQL operations on the virtual table.
**
** All VTable objects that correspond to a single table in a shared
@@ -17147,19 +17147,19 @@ struct CollSeq {
** sqlite3_vtab* handle in the compiled query.
**
** When an in-memory Table object is deleted (for example when the
-** schema is being reloaded for some reason), the VTable objects are not
-** deleted and the sqlite3_vtab* handles are not xDisconnect()ed
+** schema is being reloaded for some reason), the VTable objects are not
+** deleted and the sqlite3_vtab* handles are not xDisconnect()ed
** immediately. Instead, they are moved from the Table.pVTable list to
** another linked list headed by the sqlite3.pDisconnect member of the
-** corresponding sqlite3 structure. They are then deleted/xDisconnected
+** corresponding sqlite3 structure. They are then deleted/xDisconnected
** next time a statement is prepared using said sqlite3*. This is done
** to avoid deadlock issues involving multiple sqlite3.mutex mutexes.
** Refer to comments above function sqlite3VtabUnlockList() for an
** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect
** list without holding the corresponding sqlite3.mutex mutex.
**
-** The memory for objects of this type is always allocated by
-** sqlite3DbMalloc(), using the connection handle stored in VTable.db as
+** The memory for objects of this type is always allocated by
+** sqlite3DbMalloc(), using the connection handle stored in VTable.db as
** the first argument.
*/
struct VTable {
@@ -17189,10 +17189,10 @@ struct Table {
Index *pIndex; /* List of SQL indexes on this table. */
char *zColAff; /* String defining the affinity of each column */
ExprList *pCheck; /* All CHECK constraints */
- /* ... also used as column name list in a VIEW */
+ /* ... also used as column name list in a VIEW */
Pgno tnum; /* Root BTree page for this table */
- u32 nTabRef; /* Number of pointers to this Table */
- u32 tabFlags; /* Mask of TF_* values */
+ u32 nTabRef; /* Number of pointers to this Table */
+ u32 tabFlags; /* Mask of TF_* values */
i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
i16 nCol; /* Number of columns in this table */
i16 nNVCol; /* Number of columns that are not VIRTUAL */
@@ -17226,7 +17226,7 @@ struct Table {
/*
** Allowed values for Table.tabFlags.
**
-** TF_OOOHidden applies to tables or view that have hidden columns that are
+** TF_OOOHidden applies to tables or view that have hidden columns that are
** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING
** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden,
** the TF_OOOHidden attribute would apply in this case. Such tables require
@@ -17248,7 +17248,7 @@ struct Table {
#define TF_HasGenerated 0x00000060 /* Combo: HasVirtual + HasStored */
#define TF_WithoutRowid 0x00000080 /* No rowid. PRIMARY KEY is the key */
#define TF_StatsUsed 0x00000100 /* Query planner decisions affected by
- ** Index.aiRowLogEst[] values */
+ ** Index.aiRowLogEst[] values */
#define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */
#define TF_OOOHidden 0x00000400 /* Out-of-Order hidden columns */
#define TF_HasNotNull 0x00000800 /* Contains NOT NULL constraints */
@@ -17282,24 +17282,24 @@ struct Table {
# define ExprIsVtab(X) 0
#endif
-/*
-** Macros to determine if a column is hidden. IsOrdinaryHiddenColumn()
-** only works for non-virtual tables (ordinary tables and views) and is
-** always false unless SQLITE_ENABLE_HIDDEN_COLUMNS is defined. The
-** IsHiddenColumn() macro is general purpose.
-*/
-#if defined(SQLITE_ENABLE_HIDDEN_COLUMNS)
-# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
-# define IsOrdinaryHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
-#elif !defined(SQLITE_OMIT_VIRTUALTABLE)
-# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
-# define IsOrdinaryHiddenColumn(X) 0
-#else
-# define IsHiddenColumn(X) 0
-# define IsOrdinaryHiddenColumn(X) 0
-#endif
-
-
+/*
+** Macros to determine if a column is hidden. IsOrdinaryHiddenColumn()
+** only works for non-virtual tables (ordinary tables and views) and is
+** always false unless SQLITE_ENABLE_HIDDEN_COLUMNS is defined. The
+** IsHiddenColumn() macro is general purpose.
+*/
+#if defined(SQLITE_ENABLE_HIDDEN_COLUMNS)
+# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
+# define IsOrdinaryHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
+#elif !defined(SQLITE_OMIT_VIRTUALTABLE)
+# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
+# define IsOrdinaryHiddenColumn(X) 0
+#else
+# define IsHiddenColumn(X) 0
+# define IsOrdinaryHiddenColumn(X) 0
+#endif
+
+
/* Does the table have a rowid */
#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0)
@@ -17373,7 +17373,7 @@ struct FKey {
** to its default value. CASCADE means that a DELETE or UPDATE of the
** referenced table row is propagated into the row that holds the
** foreign key.
-**
+**
** The OE_Default value is a place holder that means to use whatever
** conflict resolution algorthm is required from context.
**
@@ -17396,7 +17396,7 @@ struct FKey {
/*
** An instance of the following structure is passed as the first
-** argument to sqlite3VdbeKeyCompare and is used to control the
+** argument to sqlite3VdbeKeyCompare and is used to control the
** comparison of the two index keys.
**
** Note that aSortOrder[] and aColl[] have nField+1 slots. There
@@ -17406,8 +17406,8 @@ struct FKey {
struct KeyInfo {
u32 nRef; /* Number of references to this KeyInfo object */
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
- u16 nKeyField; /* Number of key columns in the index */
- u16 nAllField; /* Total columns, including key plus others */
+ u16 nKeyField; /* Number of key columns in the index */
+ u16 nAllField; /* Total columns, including key plus others */
sqlite3 *db; /* The database connection */
u8 *aSortFlags; /* Sort order for each column. */
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
@@ -17420,8 +17420,8 @@ struct KeyInfo {
#define KEYINFO_ORDER_BIGNULL 0x02 /* NULL is larger than any other value */
/*
-** This object holds a record which has been parsed out into individual
-** fields, for the purposes of doing a comparison.
+** This object holds a record which has been parsed out into individual
+** fields, for the purposes of doing a comparison.
**
** 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
@@ -17429,40 +17429,40 @@ struct KeyInfo {
** the OP_MakeRecord opcode of the VDBE and is disassembled by the
** OP_Column opcode.
**
-** An instance of this object serves as a "key" for doing a search on
-** an index b+tree. The goal of the search is to find the entry that
-** is closed to the key described by this object. This object might hold
-** just a prefix of the key. The number of fields is given by
-** pKeyInfo->nField.
-**
-** The r1 and r2 fields are the values to return if this key is less than
-** or greater than a key in the btree, respectively. These are normally
-** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree
-** is in DESC order.
-**
-** The key comparison functions actually return default_rc when they find
-** an equals comparison. default_rc can be -1, 0, or +1. If there are
-** multiple entries in the b-tree with the same key (when only looking
-** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to
-** cause the search to find the last match, or +1 to cause the search to
-** find the first match.
-**
-** The key comparison functions will set eqSeen to true if they ever
-** get and equal results when comparing this structure to a b-tree record.
-** When default_rc!=0, the search might end up on the record immediately
-** before the first match or immediately after the last match. The
-** eqSeen field will indicate whether or not an exact match exists in the
-** b-tree.
+** An instance of this object serves as a "key" for doing a search on
+** an index b+tree. The goal of the search is to find the entry that
+** is closed to the key described by this object. This object might hold
+** just a prefix of the key. The number of fields is given by
+** pKeyInfo->nField.
+**
+** The r1 and r2 fields are the values to return if this key is less than
+** or greater than a key in the btree, respectively. These are normally
+** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree
+** is in DESC order.
+**
+** The key comparison functions actually return default_rc when they find
+** an equals comparison. default_rc can be -1, 0, or +1. If there are
+** multiple entries in the b-tree with the same key (when only looking
+** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to
+** cause the search to find the last match, or +1 to cause the search to
+** find the first match.
+**
+** The key comparison functions will set eqSeen to true if they ever
+** get and equal results when comparing this structure to a b-tree record.
+** When default_rc!=0, the search might end up on the record immediately
+** before the first match or immediately after the last match. The
+** eqSeen field will indicate whether or not an exact match exists in the
+** b-tree.
*/
struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Collation and sort-order information */
- Mem *aMem; /* Values */
+ Mem *aMem; /* Values */
u16 nField; /* Number of entries in apMem[] */
i8 default_rc; /* Comparison result if keys are equal */
u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
- i8 r1; /* Value to return if (lhs < rhs) */
- i8 r2; /* Value to return if (lhs > rhs) */
- u8 eqSeen; /* True if an equality comparison has been seen */
+ i8 r1; /* Value to return if (lhs < rhs) */
+ i8 r2; /* Value to return if (lhs > rhs) */
+ u8 eqSeen; /* True if an equality comparison has been seen */
};
@@ -17480,7 +17480,7 @@ struct UnpackedRecord {
** In the Table structure describing Ex1, nCol==3 because there are
** three columns in the table. In the Index structure describing
** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
-** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the
+** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the
** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
** The second column to be indexed (c1) has an index of 0 in
** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
@@ -17488,7 +17488,7 @@ struct UnpackedRecord {
** The Index.onError field determines whether or not the indexed columns
** must be unique and what to do if they are not. When Index.onError=OE_None,
** it means this is not a unique index. Otherwise it is a unique index
-** and the value of Index.onError indicate the which conflict resolution
+** and the value of Index.onError indicate the which conflict resolution
** algorithm to employ whenever an attempt is made to insert a non-unique
** element.
**
@@ -17509,9 +17509,9 @@ struct Index {
Index *pNext; /* The next index associated with the same table */
Schema *pSchema; /* Schema containing this index */
u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
- const char **azColl; /* Array of collation sequence names for index */
+ const char **azColl; /* Array of collation sequence names for index */
Expr *pPartIdxWhere; /* WHERE clause for partial indices */
- ExprList *aColExpr; /* Column expressions */
+ ExprList *aColExpr; /* Column expressions */
Pgno tnum; /* DB Page containing root of this index */
LogEst szIdxRow; /* Estimated average row size in bytes */
u16 nKeyCol; /* Number of columns forming the key */
@@ -17523,8 +17523,8 @@ struct Index {
unsigned isResized:1; /* True if resizeIndexObject() has been called */
unsigned isCovering:1; /* True if this is a covering index */
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
- unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
- unsigned bNoQuery:1; /* Do not use this index to optimize queries */
+ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
+ unsigned bNoQuery:1; /* Do not use this index to optimize queries */
unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */
unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */
#ifdef SQLITE_ENABLE_STAT4
@@ -17552,12 +17552,12 @@ struct Index {
/* Return true if index X is a UNIQUE index */
#define IsUniqueIndex(X) ((X)->onError!=OE_None)
-/* The Index.aiColumn[] values are normally positive integer. But
-** there are some negative values that have special meaning:
-*/
-#define XN_ROWID (-1) /* Indexed column is the rowid */
-#define XN_EXPR (-2) /* Indexed column is an expression */
-
+/* The Index.aiColumn[] values are normally positive integer. But
+** there are some negative values that have special meaning:
+*/
+#define XN_ROWID (-1) /* Indexed column is the rowid */
+#define XN_EXPR (-2) /* Indexed column is an expression */
+
/*
** Each sample stored in the sqlite_stat4 table is represented in memory
** using a structure of this type. See documentation at the top of the
@@ -17664,7 +17664,7 @@ typedef int ynVar;
** to represent the greater-than-or-equal-to operator in the expression
** tree.
**
-** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
+** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
** or TK_STRING), then Expr.u.zToken contains the text of the SQL literal. If
** the expression is a variable (TK_VARIABLE), then Expr.u.zToken contains the
** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
@@ -17677,7 +17677,7 @@ typedef int ynVar;
** a CASE expression or an IN expression of the form "<lhs> IN (<y>, <z>...)".
** Expr.x.pSelect is used if the expression is a sub-select or an expression of
** the form "<lhs> IN (SELECT ...)". If the EP_xIsSelect bit is set in the
-** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
+** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
** valid.
**
** An expression of the form ID or ID.ID refers to a column in a table.
@@ -17688,8 +17688,8 @@ typedef int ynVar;
** value is also stored in the Expr.iAgg column in the aggregate so that
** it can be accessed after all aggregates are computed.
**
-** If the expression is an unbound variable marker (a question mark
-** character '?' in the original SQL) then the Expr.iTable holds the index
+** If the expression is an unbound variable marker (a question mark
+** character '?' in the original SQL) then the Expr.iTable holds the index
** number for that variable.
**
** If the expression is a subquery then Expr.iColumn holds an integer
@@ -17735,7 +17735,7 @@ struct Expr {
/* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
** space is allocated for the fields below this point. An attempt to
- ** access them will result in a segfault or malfunction.
+ ** access them will result in a segfault or malfunction.
*********************************************************************/
Expr *pLeft; /* Left subnode */
@@ -17756,13 +17756,13 @@ struct Expr {
int iTable; /* TK_COLUMN: cursor number of table holding column
** TK_REGISTER: register number
** TK_TRIGGER: 1 -> new, 0 -> old
- ** EP_Unlikely: 134217728 times likelihood
+ ** EP_Unlikely: 134217728 times likelihood
** TK_IN: ephemerial table holding RHS
** TK_SELECT_COLUMN: Number of columns on the LHS
- ** TK_SELECT: 1st register of result vector */
+ ** TK_SELECT: 1st register of result vector */
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
- ** TK_VARIABLE: variable number (always >= 1).
- ** TK_SELECT_COLUMN: column of the result vector */
+ ** TK_VARIABLE: variable number (always >= 1).
+ ** TK_SELECT_COLUMN: column of the result vector */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
@@ -17817,9 +17817,9 @@ struct Expr {
/* 0x80000000 // Available */
/* The EP_Propagate mask is a set of properties that automatically propagate
-** upwards into parent nodes.
+** upwards into parent nodes.
*/
-#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
+#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
/* Macros can be used to test, set, or clear bits in the
** Expr.flags field.
@@ -17862,8 +17862,8 @@ struct Expr {
#endif
/*
-** Macros to determine the number of bytes required by a normal Expr
-** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
+** Macros to determine the number of bytes required by a normal Expr
+** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
** and an Expr struct with the EP_TokenOnly flag set.
*/
#define EXPR_FULLSIZE sizeof(Expr) /* Full size */
@@ -17871,7 +17871,7 @@ struct Expr {
#define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */
/*
-** Flags passed to the sqlite3ExprDup() function. See the header comment
+** Flags passed to the sqlite3ExprDup() function. See the header comment
** above sqlite3ExprDup() for details.
*/
#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */
@@ -17914,7 +17914,7 @@ struct ExprList {
int nExpr; /* Number of expressions on the list */
int nAlloc; /* Number of a[] slots allocated */
struct ExprList_item { /* For each expression in the list */
- Expr *pExpr; /* The parse tree for this expression */
+ Expr *pExpr; /* The parse tree for this expression */
char *zEName; /* Token associated with this expression */
u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */
unsigned eEName :2; /* Meaning of zEName */
@@ -17930,7 +17930,7 @@ struct ExprList {
int iConstExprReg; /* Register in which Expr value is cached. Used only
** by Parse.pConstExpr */
} u;
- } a[1]; /* One slot for each expression in the list */
+ } a[1]; /* One slot for each expression in the list */
};
/*
@@ -18050,28 +18050,28 @@ struct SrcList {
/*
** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
** and the WhereInfo.wctrlFlags member.
-**
-** Value constraints (enforced via assert()):
-** WHERE_USE_LIMIT == SF_FixedLimit
+**
+** Value constraints (enforced via assert()):
+** WHERE_USE_LIMIT == SF_FixedLimit
*/
#define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */
#define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */
#define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */
#define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */
-#define WHERE_ONEPASS_MULTIROW 0x0008 /* ONEPASS is ok with multiple rows */
-#define WHERE_DUPLICATES_OK 0x0010 /* Ok to return a row more than once */
-#define WHERE_OR_SUBCLAUSE 0x0020 /* Processing a sub-WHERE as part of
- ** the OR optimization */
-#define WHERE_GROUPBY 0x0040 /* pOrderBy is really a GROUP BY */
-#define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */
-#define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */
-#define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */
+#define WHERE_ONEPASS_MULTIROW 0x0008 /* ONEPASS is ok with multiple rows */
+#define WHERE_DUPLICATES_OK 0x0010 /* Ok to return a row more than once */
+#define WHERE_OR_SUBCLAUSE 0x0020 /* Processing a sub-WHERE as part of
+ ** the OR optimization */
+#define WHERE_GROUPBY 0x0040 /* pOrderBy is really a GROUP BY */
+#define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */
+#define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */
+#define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */
#define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */
-#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */
+#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */
/* 0x1000 not currently used */
- /* 0x2000 not currently used */
-#define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */
- /* 0x8000 not currently used */
+ /* 0x2000 not currently used */
+#define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */
+ /* 0x8000 not currently used */
/* Allowed return values from sqlite3WhereIsDistinct()
*/
@@ -18089,12 +18089,12 @@ struct SrcList {
** pEList corresponds to the result set of a SELECT and is NULL for
** other statements.
**
-** NameContexts can be nested. When resolving names, the inner-most
+** NameContexts can be nested. When resolving names, the inner-most
** context is searched first. If no match is found, the next outer
** context is checked. If there is still no match, the next context
** is checked. This process continues until either a match is found
** or all contexts are check. When a match is found, the nRef member of
-** the context containing the match is incremented.
+** the context containing the match is incremented.
**
** Each subquery gets a new NameContext. The pNext field points to the
** NameContext in the parent query. Thus the process of scanning the
@@ -18120,12 +18120,12 @@ struct NameContext {
/*
** Allowed values for the NameContext, ncFlags field.
**
-** Value constraints (all checked via assert()):
+** Value constraints (all checked via assert()):
** NC_HasAgg == SF_HasAgg == EP_Agg
** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
** NC_OrderAgg == SF_OrderByReqd == SQLITE_FUNC_ANYORDER
** NC_HasWin == EP_Win
-**
+**
*/
#define NC_AllowAgg 0x000001 /* Aggregate functions are allowed here */
#define NC_PartIdx 0x000002 /* True if resolving a partial index WHERE */
@@ -18204,8 +18204,8 @@ struct Upsert {
*/
struct Select {
u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
- LogEst nSelectRow; /* Estimated number of result rows */
- u32 selFlags; /* Various SF_* values */
+ LogEst nSelectRow; /* Estimated number of result rows */
+ u32 selFlags; /* Various SF_* values */
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
u32 selId; /* Unique identifier number for this SELECT */
int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
@@ -18228,8 +18228,8 @@ struct Select {
/*
** Allowed values for Select.selFlags. The "SF" prefix stands for
** "Select Flag".
-**
-** Value constraints (all checked via assert())
+**
+** Value constraints (all checked via assert())
** SF_HasAgg == NC_HasAgg
** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX
** SF_OrderByReqd == NC_OrderAgg == SQLITE_FUNC_ANYORDER
@@ -18269,7 +18269,7 @@ struct Select {
** by one of the following macros. The "SRT" prefix means "SELECT Result
** Type".
**
-** SRT_Union Store results as a key in a temporary index
+** SRT_Union Store results as a key in a temporary index
** identified by pDest->iSDParm.
**
** SRT_Except Remove results from the temporary index pDest->iSDParm.
@@ -18290,7 +18290,7 @@ struct Select {
** of the query. This destination implies "LIMIT 1".
**
** SRT_Set The result must be a single column. Store each
-** row of result as the key in table pDest->iSDParm.
+** row of result as the key in table pDest->iSDParm.
** Apply the affinity pDest->affSdst before storing
** results. Used to implement "IN (SELECT ...)".
**
@@ -18368,16 +18368,16 @@ struct SelectDest {
int iSDParm2; /* A second parameter for the eDest disposal method */
int iSdst; /* Base register where results are written */
int nSdst; /* Number of registers allocated */
- char *zAffSdst; /* Affinity used when eDest==SRT_Set */
+ char *zAffSdst; /* Affinity used when eDest==SRT_Set */
ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */
};
/*
-** During code generation of statements that do inserts into AUTOINCREMENT
+** During code generation of statements that do inserts into AUTOINCREMENT
** tables, the following information is attached to the Table.u.autoInc.p
** pointer of each autoincrement table to record some side information that
** the code generator needs. We have to keep per-table autoincrement
-** information in case inserts are done within triggers. Triggers do not
+** information in case inserts are done within triggers. Triggers do not
** normally coordinate their activities, but we do need to coordinate the
** loading and saving of autoincrement information.
*/
@@ -18389,7 +18389,7 @@ struct AutoincInfo {
};
/*
-** At least one instance of the following structure is created for each
+** At least one instance of the following structure is created for each
** trigger that may be fired while parsing an INSERT, UPDATE or DELETE
** statement. All such objects are stored in the linked list headed at
** Parse.pTriggerPrg and deleted once statement compilation has been
@@ -18402,7 +18402,7 @@ struct AutoincInfo {
** values for both pTrigger and orconf.
**
** The TriggerPrg.aColmask[0] variable is set to a mask of old.* columns
-** accessed (or set to 0 for triggers fired as a result of INSERT
+** accessed (or set to 0 for triggers fired as a result of INSERT
** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to
** a mask of new.* columns used by the program.
*/
@@ -18454,7 +18454,7 @@ struct ParseCleanup {
** is constant but the second part is reset at the beginning and end of
** each recursion.
**
-** The nTableLock and aTableLock variables are only used if the shared-cache
+** The nTableLock and aTableLock variables are only used if the shared-cache
** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are
** used to store the set of table-locks required by the statement being
** compiled. Function sqlite3TableLock() is used to add entries to the
@@ -18473,7 +18473,7 @@ struct Parse {
u8 mayAbort; /* True if statement may throw an ABORT exception */
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
u8 okConstFactor; /* OK to factor out constants */
- u8 disableLookaside; /* Number of times lookaside has been disabled */
+ u8 disableLookaside; /* Number of times lookaside has been disabled */
u8 disableVtab; /* Disable all virtual tables for this parse */
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */
@@ -18483,9 +18483,9 @@ struct Parse {
int nErr; /* Number of errors seen */
int nTab; /* Number of previously allocated VDBE cursors */
int nMem; /* Number of memory cells used so far */
- int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
- int iSelfTab; /* Table associated with an index on expr, or negative
- ** of the base register during check-constraint eval */
+ int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
+ int iSelfTab; /* Table associated with an index on expr, or negative
+ ** of the base register during check-constraint eval */
int nLabel; /* The *negative* of the number of labels used */
int nLabelAlloc; /* Number of slots in aLabel */
int *aLabel; /* Space to hold the labels */
@@ -18518,25 +18518,25 @@ struct Parse {
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
u8 disableTriggers; /* True to disable triggers */
- /**************************************************************************
- ** Fields above must be initialized to zero. The fields that follow,
- ** down to the beginning of the recursive section, do not need to be
- ** initialized as they will be set before being used. The boundary is
+ /**************************************************************************
+ ** Fields above must be initialized to zero. The fields that follow,
+ ** down to the beginning of the recursive section, do not need to be
+ ** initialized as they will be set before being used. The boundary is
** determined by offsetof(Parse,aTempReg).
- **************************************************************************/
-
- int aTempReg[8]; /* Holding area for temporary registers */
- Token sNameToken; /* Token with unqualified schema object name */
-
+ **************************************************************************/
+
+ int aTempReg[8]; /* Holding area for temporary registers */
+ Token sNameToken; /* Token with unqualified schema object name */
+
/************************************************************************
** Above is constant between recursions. Below is reset before and after
** each recursion. The boundary between these two regions is determined
- ** using offsetof(Parse,sLastToken) so the sLastToken field must be the
- ** first field in the recursive region.
+ ** using offsetof(Parse,sLastToken) so the sLastToken field must be the
+ ** first field in the recursive region.
************************************************************************/
- Token sLastToken; /* The last token parsed */
- ynVar nVar; /* Number of '?' variables seen in the SQL so far */
+ Token sLastToken; /* The last token parsed */
+ ynVar nVar; /* Number of '?' variables seen in the SQL so far */
u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
u8 explain; /* True if the EXPLAIN flag is found on the query */
u8 eParseMode; /* PARSE_MODE_XXX constant */
@@ -18547,7 +18547,7 @@ struct Parse {
#ifndef SQLITE_OMIT_EXPLAIN
int addrExplain; /* Address of current OP_Explain opcode */
#endif
- VList *pVList; /* Mapping between variable names and numbers */
+ VList *pVList; /* Mapping between variable names and numbers */
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
const char *zTail; /* All SQL text past the last semicolon parsed */
Table *pNewTable; /* A table being constructed by CREATE TABLE */
@@ -18574,14 +18574,14 @@ struct Parse {
#define PARSE_MODE_UNMAP 3
/*
-** Sizes and pointers of various parts of the Parse object.
-*/
+** Sizes and pointers of various parts of the Parse object.
+*/
#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/
-#define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */
-#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
-#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */
-
-/*
+#define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */
+#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
+#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */
+
+/*
** Return true if currently inside an sqlite3_declare_vtab() call.
*/
#ifdef SQLITE_OMIT_VIRTUALTABLE
@@ -18613,43 +18613,43 @@ struct AuthContext {
/*
** Bitfield flags for P5 value in various opcodes.
-**
-** Value constraints (enforced via assert()):
-** OPFLAG_LENGTHARG == SQLITE_FUNC_LENGTH
-** OPFLAG_TYPEOFARG == SQLITE_FUNC_TYPEOF
-** OPFLAG_BULKCSR == BTREE_BULKLOAD
-** OPFLAG_SEEKEQ == BTREE_SEEK_EQ
-** OPFLAG_FORDELETE == BTREE_FORDELETE
-** OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION
-** OPFLAG_AUXDELETE == BTREE_AUXDELETE
-*/
-#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
- /* Also used in P2 (not P5) of OP_Delete */
+**
+** Value constraints (enforced via assert()):
+** OPFLAG_LENGTHARG == SQLITE_FUNC_LENGTH
+** OPFLAG_TYPEOFARG == SQLITE_FUNC_TYPEOF
+** OPFLAG_BULKCSR == BTREE_BULKLOAD
+** OPFLAG_SEEKEQ == BTREE_SEEK_EQ
+** OPFLAG_FORDELETE == BTREE_FORDELETE
+** OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION
+** OPFLAG_AUXDELETE == BTREE_AUXDELETE
+*/
+#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
+ /* Also used in P2 (not P5) of OP_Delete */
#define OPFLAG_NOCHNG 0x01 /* OP_VColumn nochange for UPDATE */
#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
-#define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */
+#define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */
#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
#define OPFLAG_APPEND 0x08 /* This is likely to be an append */
#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
-#define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */
+#define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */
#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
#define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */
-#define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */
-#define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */
+#define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */
+#define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
-#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */
-#define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */
-#define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */
+#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */
+#define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */
+#define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */
#define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */
/*
* Each trigger present in the database schema is stored as an instance of
- * struct Trigger.
+ * struct Trigger.
*
* Pointers to instances of struct Trigger are stored in two ways.
- * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
+ * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
* database). This allows Trigger structures to be retrieved by name.
* 2. All triggers associated with a single table form a linked list, using the
* pNext member of struct Trigger. A pointer to the first element of the
@@ -18676,7 +18676,7 @@ struct Trigger {
/*
** A trigger is either a BEFORE or an AFTER trigger. The following constants
-** determine which.
+** determine which.
**
** If there are multiple triggers, you might of some BEFORE and some AFTER.
** In that cases, the constants below can be ORed together.
@@ -18686,15 +18686,15 @@ struct Trigger {
/*
* An instance of struct TriggerStep is used to store a single SQL statement
- * that is a part of a trigger-program.
+ * that is a part of a trigger-program.
*
* Instances of struct TriggerStep are stored in a singly linked list (linked
- * using the "pNext" member) referenced by the "step_list" member of the
+ * using the "pNext" member) referenced by the "step_list" member of the
* associated struct Trigger instance. The first element of the linked list is
* the first step of the trigger-program.
- *
+ *
* The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
- * "SELECT" statement. The meanings of the other members is determined by the
+ * "SELECT" statement. The meanings of the other members is determined by the
* value of "op" as follows:
*
* (op == TK_INSERT)
@@ -18704,7 +18704,7 @@ struct Trigger {
* zTarget -> Dequoted name of the table to insert into.
* pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
* this stores values to be inserted. Otherwise NULL.
- * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
+ * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
* statement, then this stores the column-names to be
* inserted into.
*
@@ -18712,7 +18712,7 @@ struct Trigger {
* zTarget -> Dequoted name of the table to delete from.
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
* Otherwise NULL.
- *
+ *
* (op == TK_UPDATE)
* zTarget -> Dequoted name of the table to update.
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
@@ -18720,7 +18720,7 @@ struct Trigger {
* pExprList -> A list of the columns to update and the expressions to update
* them to. See sqlite3Update() documentation of "pChanges"
* argument.
- *
+ *
*/
struct TriggerStep {
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT,
@@ -18734,7 +18734,7 @@ struct TriggerStep {
ExprList *pExprList; /* SET clause for UPDATE, or RETURNING clause */
IdList *pIdList; /* Column names for INSERT */
Upsert *pUpsert; /* Upsert clauses on an INSERT */
- char *zSpan; /* Original SQL text of this command */
+ char *zSpan; /* Original SQL text of this command */
TriggerStep *pNext; /* Next in the link-list */
TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
};
@@ -18759,19 +18759,19 @@ struct Returning {
struct sqlite3_str {
sqlite3 *db; /* Optional database for lookaside. Can be NULL */
char *zText; /* The string collected so far */
- u32 nAlloc; /* Amount of space allocated in zText */
- u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
- u32 nChar; /* Length of the string so far */
+ u32 nAlloc; /* Amount of space allocated in zText */
+ u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
+ u32 nChar; /* Length of the string so far */
u8 accError; /* SQLITE_NOMEM or SQLITE_TOOBIG */
- u8 printfFlags; /* SQLITE_PRINTF flags below */
+ u8 printfFlags; /* SQLITE_PRINTF flags below */
};
-#define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */
-#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
-#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
+#define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */
+#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
+#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
+
+#define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
+
-#define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
-
-
/*
** A pointer to this structure is used to communicate information
** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
@@ -18827,7 +18827,7 @@ struct Sqlite3Config {
int neverCorrupt; /* Database is always well-formed */
int szLookaside; /* Default lookaside buffer size */
int nLookaside; /* Default lookaside buffer count */
- int nStmtSpill; /* Stmt-journal spill-to-disk threshold */
+ int nStmtSpill; /* Stmt-journal spill-to-disk threshold */
sqlite3_mem_methods m; /* Low-level memory allocation interface */
sqlite3_mutex_methods mutex; /* Low-level mutex interface */
sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */
@@ -18867,11 +18867,11 @@ struct Sqlite3Config {
#ifndef SQLITE_OMIT_DESERIALIZE
sqlite3_int64 mxMemdbSize; /* Default max memdb size */
#endif
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
#endif
int bLocaltimeFault; /* True to fail localtime() calls */
- int iOnceResetThreshold; /* When to reset OP_Once counters */
+ int iOnceResetThreshold; /* When to reset OP_Once counters */
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
/* vvvv--- must be last ---vvv */
@@ -18902,23 +18902,23 @@ struct Sqlite3Config {
** Context pointer passed down through the tree-walk.
*/
struct Walker {
- Parse *pParse; /* Parser context. */
+ Parse *pParse; /* Parser context. */
int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */
int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */
void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
int walkerDepth; /* Number of subqueries */
u16 eCode; /* A small processing code */
union { /* Extra data for callback */
- NameContext *pNC; /* Naming context */
- int n; /* A counter */
- int iCur; /* A cursor number */
- SrcList *pSrcList; /* FROM clause */
- struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
+ NameContext *pNC; /* Naming context */
+ int n; /* A counter */
+ int iCur; /* A cursor number */
+ SrcList *pSrcList; /* FROM clause */
+ struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */
- int *aiCol; /* array of column indexes */
- struct IdxCover *pIdxCover; /* Check for index coverage */
+ int *aiCol; /* array of column indexes */
+ struct IdxCover *pIdxCover; /* Check for index coverage */
struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
- ExprList *pGroupBy; /* GROUP BY clause */
+ ExprList *pGroupBy; /* GROUP BY clause */
Select *pSelect; /* HAVING to WHERE clause ctx */
struct WindowRewrite *pRewrite; /* Window rewrite context */
struct WhereConst *pConst; /* WHERE clause constants */
@@ -18950,16 +18950,16 @@ SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*);
SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*);
SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*);
SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
-SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*);
-SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*);
-SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*);
+SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*);
+SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*);
+SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*);
SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker*,Select*);
SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker*,Select*);
SQLITE_PRIVATE void sqlite3WalkWinDefnDummyCallback(Walker*,Select*);
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*);
-#endif
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*);
+#endif
#ifndef SQLITE_OMIT_CTE
SQLITE_PRIVATE void sqlite3SelectPopWith(Walker*, Select*);
@@ -19132,36 +19132,36 @@ SQLITE_PRIVATE Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprLis
** using sqlite3_log(). The routines also provide a convenient place
** to set a debugger breakpoint.
*/
-SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType);
+SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType);
SQLITE_PRIVATE int sqlite3CorruptError(int);
SQLITE_PRIVATE int sqlite3MisuseError(int);
SQLITE_PRIVATE int sqlite3CantopenError(int);
#define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__)
#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__)
#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__)
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3NomemError(int);
-SQLITE_PRIVATE int sqlite3IoerrnomemError(int);
-# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__)
-# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__)
-#else
-# define SQLITE_NOMEM_BKPT SQLITE_NOMEM
-# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3NomemError(int);
+SQLITE_PRIVATE int sqlite3IoerrnomemError(int);
+# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__)
+# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__)
+#else
+# define SQLITE_NOMEM_BKPT SQLITE_NOMEM
+# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_CORRUPT_PGNO)
SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P))
#else
-# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptError(__LINE__)
-#endif
+# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptError(__LINE__)
+#endif
-/*
-** FTS3 and FTS4 both require virtual table support
-*/
-#if defined(SQLITE_OMIT_VIRTUALTABLE)
-# undef SQLITE_ENABLE_FTS3
-# undef SQLITE_ENABLE_FTS4
-#endif
+/*
+** FTS3 and FTS4 both require virtual table support
+*/
+#if defined(SQLITE_OMIT_VIRTUALTABLE)
+# undef SQLITE_ENABLE_FTS3
+# undef SQLITE_ENABLE_FTS4
+#endif
/*
** FTS4 is really an extension for FTS3. It is enabled using the
@@ -19194,7 +19194,7 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04)
# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)])
-# define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80)
+# define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80)
#else
# define sqlite3Toupper(x) toupper((unsigned char)(x))
# define sqlite3Isspace(x) isspace((unsigned char)(x))
@@ -19203,17 +19203,17 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
# define sqlite3Isdigit(x) isdigit((unsigned char)(x))
# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
# define sqlite3Tolower(x) tolower((unsigned char)(x))
-# define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
+# define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
#endif
SQLITE_PRIVATE int sqlite3IsIdChar(u8);
/*
** Internal function prototypes
*/
-SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*);
+SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*);
SQLITE_PRIVATE int sqlite3Strlen30(const char*);
#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff)
-SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*);
+SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*);
#define sqlite3StrNICmp sqlite3_strnicmp
SQLITE_PRIVATE int sqlite3MallocInit(void);
@@ -19222,21 +19222,21 @@ SQLITE_PRIVATE void *sqlite3Malloc(u64);
SQLITE_PRIVATE void *sqlite3MallocZero(u64);
SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, u64);
SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, u64);
-SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3*, u64);
+SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3*, u64);
SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*);
SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64);
-SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3*,const char*,const char*);
+SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3*,const char*,const char*);
SQLITE_PRIVATE void *sqlite3Realloc(void*, u64);
SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64);
SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*);
-SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*);
+SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*);
SQLITE_PRIVATE int sqlite3MallocSize(const void*);
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, const void*);
SQLITE_PRIVATE void *sqlite3PageMalloc(int);
SQLITE_PRIVATE void sqlite3PageFree(void*);
SQLITE_PRIVATE void sqlite3MemSetDefault(void);
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
#endif
SQLITE_PRIVATE int sqlite3HeapNearlyFull(void);
@@ -19252,20 +19252,20 @@ SQLITE_PRIVATE int sqlite3HeapNearlyFull(void);
#ifdef SQLITE_USE_ALLOCA
# define sqlite3StackAllocRaw(D,N) alloca(N)
# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N)
-# define sqlite3StackFree(D,P)
+# define sqlite3StackFree(D,P)
#else
# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N)
# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N)
# define sqlite3StackFree(D,P) sqlite3DbFree(D,P)
#endif
-/* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they
-** are, disable MEMSYS3
-*/
-#ifdef SQLITE_ENABLE_MEMSYS5
-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
-#undef SQLITE_ENABLE_MEMSYS3
-#endif
+/* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they
+** are, disable MEMSYS3
+*/
+#ifdef SQLITE_ENABLE_MEMSYS5
+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
+#undef SQLITE_ENABLE_MEMSYS3
+#endif
#ifdef SQLITE_ENABLE_MEMSYS3
SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
#endif
@@ -19278,28 +19278,28 @@ SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int);
SQLITE_PRIVATE int sqlite3MutexInit(void);
SQLITE_PRIVATE int sqlite3MutexEnd(void);
#endif
-#if !defined(SQLITE_MUTEX_OMIT) && !defined(SQLITE_MUTEX_NOOP)
-SQLITE_PRIVATE void sqlite3MemoryBarrier(void);
-#else
-# define sqlite3MemoryBarrier()
-#endif
+#if !defined(SQLITE_MUTEX_OMIT) && !defined(SQLITE_MUTEX_NOOP)
+SQLITE_PRIVATE void sqlite3MemoryBarrier(void);
+#else
+# define sqlite3MemoryBarrier()
+#endif
SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int);
SQLITE_PRIVATE void sqlite3StatusUp(int, int);
SQLITE_PRIVATE void sqlite3StatusDown(int, int);
-SQLITE_PRIVATE void sqlite3StatusHighwater(int, int);
-SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3*,int*);
+SQLITE_PRIVATE void sqlite3StatusHighwater(int, int);
+SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3*,int*);
/* Access to mutexes used by sqlite3_status() */
SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void);
SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void);
-#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT)
-SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
-#else
-# define sqlite3MutexWarnOnContention(x)
-#endif
-
+#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT)
+SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
+#else
+# define sqlite3MutexWarnOnContention(x)
+#endif
+
#ifndef SQLITE_OMIT_FLOATING_POINT
# define EXP754 (((u64)0x7ff)<<52)
# define MAN754 ((((u64)1)<<52)-1)
@@ -19331,11 +19331,11 @@ SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
#if defined(SQLITE_DEBUG)
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
-SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
+SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
-SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
+SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
@@ -19346,10 +19346,10 @@ SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int);
-SQLITE_PRIVATE void sqlite3Dequote(char*);
+SQLITE_PRIVATE void sqlite3Dequote(char*);
SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*);
SQLITE_PRIVATE void sqlite3DequoteToken(Token*);
-SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*);
+SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*);
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
SQLITE_PRIVATE void sqlite3FinishCoding(Parse*);
@@ -19358,28 +19358,28 @@ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int);
SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int);
SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int);
SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*);
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int);
-#endif
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int);
+#endif
SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
-SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
-SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
+SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
+SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int);
SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*);
-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
+SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
-SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
+SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse*, int, ExprList*);
SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int);
SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int);
-SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
+SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*);
@@ -19387,9 +19387,9 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32);
SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName);
-#endif
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName);
+#endif
SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*);
SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int);
SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*);
@@ -19398,9 +19398,9 @@ SQLITE_PRIVATE void sqlite3ColumnSetExpr(Parse*,Table*,Column*,Expr*);
SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table*,Column*);
SQLITE_PRIVATE void sqlite3ColumnSetColl(sqlite3*,Column*,const char*zColl);
SQLITE_PRIVATE const char *sqlite3ColumnColl(Column*);
-SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*);
+SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*);
SQLITE_PRIVATE void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect);
-SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
+SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *, int);
@@ -19414,16 +19414,16 @@ SQLITE_PRIVATE i16 sqlite3TableColumnToStorage(Table*, i16);
SQLITE_PRIVATE i16 sqlite3StorageColumnToTable(Table*, i16);
#endif
SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
-#if SQLITE_ENABLE_HIDDEN_COLUMNS
-SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table*, Column*);
-#else
-# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
-#endif
+#if SQLITE_ENABLE_HIDDEN_COLUMNS
+SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table*, Column*);
+#else
+# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
+#endif
SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token,Token);
SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*);
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
+SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
SQLITE_PRIVATE void sqlite3AddGenerated(Parse*,Expr*,Token*);
SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u32,Select*);
@@ -19433,7 +19433,7 @@ SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
#define sqlite3CodecQueryParameters(A,B,C) 0
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
-#ifdef SQLITE_UNTESTABLE
+#ifdef SQLITE_UNTESTABLE
# define sqlite3FaultSim(X) SQLITE_OK
#else
SQLITE_PRIVATE int sqlite3FaultSim(int);
@@ -19446,7 +19446,7 @@ SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32);
SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*);
SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*);
SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*);
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
#endif
@@ -19457,7 +19457,7 @@ SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64);
SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64);
SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*);
-SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int);
+SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int);
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*);
@@ -19492,32 +19492,32 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
Token*, Select*, Expr*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
-SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
+SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *);
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
-SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
- Expr*, int, int, u8);
+SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
+ Expr*, int, int, u8);
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
- Expr*,ExprList*,u32,Expr*);
+ Expr*,ExprList*,u32,Expr*);
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
-SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
+SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
#endif
-SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
+SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
Upsert*);
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
-SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
+SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
@@ -19526,11 +19526,11 @@ SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*);
-#define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */
-#define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */
-#define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */
+#define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */
+#define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */
+#define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */
SQLITE_PRIVATE int sqlite3WhereUsesDeferredSeek(WhereInfo*);
-SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
+SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
@@ -19538,23 +19538,23 @@ SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int);
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int);
#endif
-SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int);
+SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
-SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);
+SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);
#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */
#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */
-#define SQLITE_ECEL_REF 0x04 /* Use ExprList.u.x.iOrderByCol */
-#define SQLITE_ECEL_OMITREF 0x08 /* Omit if ExprList.u.x.iOrderByCol */
+#define SQLITE_ECEL_REF 0x04 /* Use ExprList.u.x.iOrderByCol */
+#define SQLITE_ECEL_OMITREF 0x08 /* Omit if ExprList.u.x.iOrderByCol */
SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
-#define LOCATE_VIEW 0x01
-#define LOCATE_NOERR 0x02
-SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
+#define LOCATE_VIEW 0x01
+#define LOCATE_NOERR 0x02
+SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char*);
SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *);
SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
@@ -19571,10 +19571,10 @@ SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int);
SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
-SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
+SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse*, Expr*, SrcList*);
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
#endif
@@ -19582,7 +19582,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*,int);
SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int);
-SQLITE_PRIVATE void sqlite3EndTransaction(Parse*,int);
+SQLITE_PRIVATE void sqlite3EndTransaction(Parse*,int);
SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
@@ -19592,30 +19592,30 @@ SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
+SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
-#ifdef SQLITE_ENABLE_CURSOR_HINTS
-SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
-#endif
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
+#endif
SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
-SQLITE_PRIVATE void sqlite3GenerateRowDelete(
- Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
-SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
+SQLITE_PRIVATE void sqlite3GenerateRowDelete(
+ Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
+SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int);
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
u8,u8,int,int*,int*,Upsert*);
-#ifdef SQLITE_ENABLE_NULL_TRIM
-SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe*,Table*);
-#else
-# define sqlite3SetMakeRecordP5(A,B)
-#endif
+#ifdef SQLITE_ENABLE_NULL_TRIM
+SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe*,Table*);
+#else
+# define sqlite3SetMakeRecordP5(A,B)
+#endif
SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
-SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*);
+SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*);
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
SQLITE_PRIVATE void sqlite3MultiWrite(Parse*);
SQLITE_PRIVATE void sqlite3MayAbort(Parse*);
@@ -19628,18 +19628,18 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,const SrcList*,int);
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,const IdList*);
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,const Select*,int);
SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*);
-SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
-SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
-SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
+SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
+SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
+SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
-SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
+SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p);
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
-SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int);
+SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int);
#endif
#ifndef SQLITE_OMIT_TRIGGER
@@ -19655,11 +19655,11 @@ SQLITE_PRIVATE void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, i
SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int);
void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*,
- const char*,const char*);
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*,
+ const char*,const char*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*,
Select*,u8,Upsert*,
- const char*,const char*);
+ const char*,const char*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,SrcList*,ExprList*,
Expr*, u8, const char*,const char*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*,
@@ -19669,7 +19669,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int);
SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc(Parse*, TriggerStep*);
# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p))
-# define sqlite3IsToplevel(p) ((p)->pToplevel==0)
+# define sqlite3IsToplevel(p) ((p)->pToplevel==0)
#else
# define sqlite3TriggersExist(B,C,D,E,F) 0
# define sqlite3DeleteTrigger(A,B)
@@ -19679,7 +19679,7 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc(Parse*, TriggerStep*);
# define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F)
# define sqlite3TriggerList(X, Y) 0
# define sqlite3ParseToplevel(p) p
-# define sqlite3IsToplevel(p) 1
+# define sqlite3IsToplevel(p) 1
# define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0
# define sqlite3TriggerStepSrc(A,B) 0
#endif
@@ -19715,9 +19715,9 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8);
SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*);
SQLITE_PRIVATE int sqlite3Atoi(const char*);
-#ifndef SQLITE_OMIT_UTF16
+#ifndef SQLITE_OMIT_UTF16
SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
-#endif
+#endif
SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
SQLITE_PRIVATE LogEst sqlite3LogEst(u64);
@@ -19725,14 +19725,14 @@ SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst);
#ifndef SQLITE_OMIT_VIRTUALTABLE
SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
#endif
-#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
+#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
defined(SQLITE_ENABLE_STAT4) || \
- defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
+ defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
-#endif
-SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
-SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int);
-SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int);
+#endif
+SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
+SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int);
+SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int);
/*
** Routines to read and write variable-length integers. These used to
@@ -19760,7 +19760,7 @@ SQLITE_PRIVATE int sqlite3VarintLen(u64 v);
#define putVarint sqlite3PutVarint
-SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
+SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int);
SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2);
SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
@@ -19771,7 +19771,7 @@ SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*);
SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
SQLITE_PRIVATE void sqlite3Error(sqlite3*,int);
SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3*);
-SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int);
+SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int);
SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
SQLITE_PRIVATE u8 sqlite3HexToInt(int h);
SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
@@ -19814,7 +19814,7 @@ SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8);
SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
-SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
+SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
void(*)(void*));
SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
@@ -19822,14 +19822,14 @@ SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context*);
#endif
SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
-#ifndef SQLITE_OMIT_UTF16
+#ifndef SQLITE_OMIT_UTF16
SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
-#endif
+#endif
SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, const Expr *, u8, u8, sqlite3_value **);
SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[];
-SQLITE_PRIVATE const char sqlite3StrBINARY[];
+SQLITE_PRIVATE const char sqlite3StrBINARY[];
SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[];
SQLITE_PRIVATE const char sqlite3StdTypeAffinity[];
SQLITE_PRIVATE const char sqlite3StdTypeMap[];
@@ -19840,7 +19840,7 @@ SQLITE_PRIVATE const unsigned char *sqlite3aEQb;
SQLITE_PRIVATE const unsigned char *sqlite3aGTb;
SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[];
SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config;
-SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
+SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
#ifndef SQLITE_OMIT_WSD
SQLITE_PRIVATE int sqlite3PendingByte;
#endif
@@ -19870,7 +19870,7 @@ SQLITE_PRIVATE int sqlite3MatchEName(
SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr*);
SQLITE_PRIVATE u8 sqlite3StrIHash(const char*);
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
-SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*);
+SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*);
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
SQLITE_PRIVATE int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
@@ -19907,7 +19907,7 @@ SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse*, ExprList*);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*);
#endif
-SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
+SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
void (*)(sqlite3_context*,int,sqlite3_value **),
void (*)(sqlite3_context*,int,sqlite3_value **),
void (*)(sqlite3_context*),
@@ -19916,8 +19916,8 @@ SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
FuncDestructor *pDestructor
);
SQLITE_PRIVATE void sqlite3NoopDestructor(void*);
-SQLITE_PRIVATE void sqlite3OomFault(sqlite3*);
-SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
+SQLITE_PRIVATE void sqlite3OomFault(sqlite3*);
+SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
@@ -19931,28 +19931,28 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
-#ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse*, Expr*);
-#else
-# define sqlite3ExprCheckIN(x,y) SQLITE_OK
-#endif
-
+#ifndef SQLITE_OMIT_SUBQUERY
+SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse*, Expr*);
+#else
+# define sqlite3ExprCheckIN(x,y) SQLITE_OK
+#endif
+
#ifdef SQLITE_ENABLE_STAT4
-SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(
- Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*);
+SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(
+ Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*);
SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**);
SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*);
SQLITE_PRIVATE int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**);
-SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3*, Index*, int);
+SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3*, Index*, int);
#endif
/*
** The interface to the LEMON-generated parser
*/
-#ifndef SQLITE_AMALGAMATION
+#ifndef SQLITE_AMALGAMATION
SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64), Parse*);
-SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
-#endif
+SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
+#endif
SQLITE_PRIVATE void sqlite3Parser(void*, int, Token);
SQLITE_PRIVATE int sqlite3ParserFallback(int);
#ifdef YYTRACKMAXSTACKDEPTH
@@ -19982,7 +19982,7 @@ SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*);
# define sqlite3VtabRollback(X)
# define sqlite3VtabCommit(X)
# define sqlite3VtabInSync(db) 0
-# define sqlite3VtabLock(X)
+# define sqlite3VtabLock(X)
# define sqlite3VtabUnlock(X)
# define sqlite3VtabModuleUnref(D,X)
# define sqlite3VtabUnlockList(X)
@@ -20001,13 +20001,13 @@ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*);
SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int);
SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
-SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
- sqlite3*,
- const char*,
- const sqlite3_module*,
- void*,
- void(*)(void*)
- );
+SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
+ sqlite3*,
+ const char*,
+ const sqlite3_module*,
+ void*,
+ void(*)(void*)
+ );
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db);
@@ -20020,8 +20020,8 @@ SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3*, Table*);
# define sqlite3IsShadowTableOf(A,B,C) 0
# define sqlite3MarkAllShadowTablesOf(A,B)
#endif
-SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
-SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
+SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
+SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
@@ -20084,7 +20084,7 @@ SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert*);
** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
** key functionality is available. If OMIT_TRIGGER is defined but
** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In
-** this case foreign keys are parsed, but no other functionality is
+** this case foreign keys are parsed, but no other functionality is
** provided (enforcement of FK constraints requires the triggers sub-system).
*/
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
@@ -20101,7 +20101,7 @@ SQLITE_PRIVATE void sqlite3FkClearTriggerCache(sqlite3*,int);
#define sqlite3FkDropTable(a,b,c)
#define sqlite3FkOldmask(a,b) 0
#define sqlite3FkRequired(a,b,c,d) 0
- #define sqlite3FkReferences(a) 0
+ #define sqlite3FkReferences(a) 0
#define sqlite3FkClearTriggerCache(a,b)
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
@@ -20121,10 +20121,10 @@ SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**);
/*
** The interface to the code in fault.c used for identifying "benign"
-** malloc failures. This is only present if SQLITE_UNTESTABLE
+** malloc failures. This is only present if SQLITE_UNTESTABLE
** is not defined.
*/
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void);
SQLITE_PRIVATE void sqlite3EndBenignMalloc(void);
#else
@@ -20148,14 +20148,14 @@ SQLITE_PRIVATE void sqlite3EndBenignMalloc(void);
#define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */
SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*);
-SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
-SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
-#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
- || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
+SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *);
#endif
-SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p);
+SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p);
SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *);
SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
@@ -20183,14 +20183,14 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *);
#endif
-#if defined(YYCOVERAGE)
-SQLITE_PRIVATE int sqlite3ParserCoverage(FILE*);
-#endif
+#if defined(YYCOVERAGE)
+SQLITE_PRIVATE int sqlite3ParserCoverage(FILE*);
+#endif
/*
** If the SQLITE_ENABLE IOTRACE exists then the global variable
** sqlite3IoTrace is a pointer to a printf-like routine used to
-** print I/O tracing messages.
+** print I/O tracing messages.
*/
#ifdef SQLITE_ENABLE_IOTRACE
# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
@@ -20224,7 +20224,7 @@ SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...);
** that allocations that might have been satisfied by lookaside are not
** passed back to non-lookaside free() routines. Asserts such as the
** example above are placed on the non-lookaside free() routines to verify
-** this constraint.
+** this constraint.
**
** All of this is no-op for a production build. It only comes into
** play when the SQLITE_MEMDEBUG compile-time option is used.
@@ -20240,7 +20240,7 @@ SQLITE_PRIVATE int sqlite3MemdebugNoType(const void*,u8);
#endif
#define MEMTYPE_HEAP 0x01 /* General heap allocations */
#define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */
-#define MEMTYPE_PCACHE 0x04 /* Page cache allocations */
+#define MEMTYPE_PCACHE 0x04 /* Page cache allocations */
/*
** Threading interface
@@ -20250,25 +20250,25 @@ SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
#endif
-#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)
-SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3*);
-#endif
+#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)
+SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3*);
+#endif
#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*);
#endif
SQLITE_PRIVATE int sqlite3ExprVectorSize(const Expr *pExpr);
SQLITE_PRIVATE int sqlite3ExprIsVector(const Expr *pExpr);
-SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr*, int);
+SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr*, int);
SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(Parse*,Expr*,int,int);
-SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse*, Expr*);
-
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt);
-#endif
-
-#endif /* SQLITEINT_H */
-
+SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse*, Expr*);
+
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt);
+#endif
+
+#endif /* SQLITEINT_H */
+
/************** End of sqliteInt.h *******************************************/
/************** Begin file os_common.h ***************************************/
/*
@@ -21355,7 +21355,7 @@ SQLITE_PRIVATE const unsigned char *sqlite3aGTb = &sqlite3UpperToLower[256+12-OP
** isxdigit() 0x08
** toupper() 0x20
** SQLite identifier character 0x40
-** Quote character 0x80
+** Quote character 0x80
**
** Bit 0x20 is set if the mapped character requires translation to upper
** case. i.e. if the character is a lower-case ASCII character.
@@ -21364,7 +21364,7 @@ SQLITE_PRIVATE const unsigned char *sqlite3aGTb = &sqlite3UpperToLower[256+12-OP
**
** (x & ~(map[x]&0x20))
**
-** The equivalent of tolower() is implemented using the sqlite3UpperToLower[]
+** The equivalent of tolower() is implemented using the sqlite3UpperToLower[]
** array. tolower() is used more often than toupper() by SQLite.
**
** Bit 0x40 is set if the character is non-alphanumeric and can be used in an
@@ -21377,7 +21377,7 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */
- 0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80, /* 20..27 !"#$%&' */
+ 0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80, /* 20..27 !"#$%&' */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */
0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */
@@ -21385,8 +21385,8 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */
- 0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */
- 0x80, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */
+ 0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */
+ 0x80, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */
0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */
@@ -21447,40 +21447,40 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
# define SQLITE_SORTER_PMASZ 250
#endif
-/* Statement journals spill to disk when their size exceeds the following
-** threshold (in bytes). 0 means that statement journals are created and
-** written to disk immediately (the default behavior for SQLite versions
-** before 3.12.0). -1 means always keep the entire statement journal in
-** memory. (The statement journal is also always held entirely in memory
-** if journal_mode=MEMORY or if temp_store=MEMORY, regardless of this
-** setting.)
-*/
+/* Statement journals spill to disk when their size exceeds the following
+** threshold (in bytes). 0 means that statement journals are created and
+** written to disk immediately (the default behavior for SQLite versions
+** before 3.12.0). -1 means always keep the entire statement journal in
+** memory. (The statement journal is also always held entirely in memory
+** if journal_mode=MEMORY or if temp_store=MEMORY, regardless of this
+** setting.)
+*/
#ifndef SQLITE_STMTJRNL_SPILL
-# define SQLITE_STMTJRNL_SPILL (64*1024)
-#endif
-
+# define SQLITE_STMTJRNL_SPILL (64*1024)
+#endif
+
/*
-** The default lookaside-configuration, the format "SZ,N". SZ is the
-** number of bytes in each lookaside slot (should be a multiple of 8)
-** and N is the number of slots. The lookaside-configuration can be
-** changed as start-time using sqlite3_config(SQLITE_CONFIG_LOOKASIDE)
-** or at run-time for an individual database connection using
-** sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE);
+** The default lookaside-configuration, the format "SZ,N". SZ is the
+** number of bytes in each lookaside slot (should be a multiple of 8)
+** and N is the number of slots. The lookaside-configuration can be
+** changed as start-time using sqlite3_config(SQLITE_CONFIG_LOOKASIDE)
+** or at run-time for an individual database connection using
+** sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE);
**
** With the two-size-lookaside enhancement, less lookaside is required.
** The default configuration of 1200,40 actually provides 30 1200-byte slots
** and 93 128-byte slots, which is more lookaside than is available
** using the older 1200,100 configuration without two-size-lookaside.
-*/
-#ifndef SQLITE_DEFAULT_LOOKASIDE
+*/
+#ifndef SQLITE_DEFAULT_LOOKASIDE
# ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE
# define SQLITE_DEFAULT_LOOKASIDE 1200,100 /* 120KB of memory */
# else
# define SQLITE_DEFAULT_LOOKASIDE 1200,40 /* 48KB of memory */
# endif
-#endif
-
-
+#endif
+
+
/* The default maximum size of an in-memory database created using
** sqlite3_deserialize()
*/
@@ -21488,7 +21488,7 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
# define SQLITE_MEMDB_DEFAULT_MAXSIZE 1073741824
#endif
-/*
+/*
** The following singleton contains the global configuration for
** the SQLite library.
*/
@@ -21498,12 +21498,12 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
SQLITE_THREADSAFE==1, /* bFullMutex */
SQLITE_USE_URI, /* bOpenUri */
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
- 0, /* bSmallMalloc */
+ 0, /* bSmallMalloc */
1, /* bExtraSchemaChecks */
0x7ffffffe, /* mxStrlen */
0, /* neverCorrupt */
- SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */
- SQLITE_STMTJRNL_SPILL, /* nStmtSpill */
+ SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */
+ SQLITE_STMTJRNL_SPILL, /* nStmtSpill */
{0,0,0,0,0,0,0,0}, /* m */
{0,0,0,0,0,0,0,0,0}, /* mutex */
{0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
@@ -21539,10 +21539,10 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
#ifndef SQLITE_OMIT_DESERIALIZE
SQLITE_MEMDB_DEFAULT_MAXSIZE, /* mxMemdbSize */
#endif
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
0, /* xTestCallback */
#endif
- 0, /* bLocaltimeFault */
+ 0, /* bLocaltimeFault */
0x7ffffffe, /* iOnceResetThreshold */
SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
0, /* iPrngSeed */
@@ -21553,7 +21553,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
** database connections. After initialization, this table is
** read-only.
*/
-SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
+SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
/*
@@ -21579,7 +21579,7 @@ SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt = 0;
** The value of the "pending" byte must be 0x40000000 (1 byte past the
** 1-gibabyte boundary) in a compatible database. SQLite never uses
** the database page that contains the pending byte. It never attempts
-** to read or write that page. The pending byte page is set aside
+** to read or write that page. The pending byte page is set aside
** for use by the VFS layers as space for managing file locks.
**
** During testing, it is often desirable to move the pending byte to
@@ -21594,7 +21594,7 @@ SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt = 0;
** and incorrect behavior.
*/
#ifndef SQLITE_OMIT_WSD
-int sqlite3PendingByte = 0x40000000;
+int sqlite3PendingByte = 0x40000000;
#endif
/*
@@ -21613,9 +21613,9 @@ SQLITE_PRIVATE u32 sqlite3WhereTrace = 0;
SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
/*
-** Name of the default collating sequence
+** Name of the default collating sequence
*/
-SQLITE_PRIVATE const char sqlite3StrBINARY[] = "BINARY";
+SQLITE_PRIVATE const char sqlite3StrBINARY[] = "BINARY";
/*
** Standard typenames. These names must match the COLTYPE_* definitions.
@@ -21659,7 +21659,7 @@ SQLITE_PRIVATE const char *sqlite3StdType[] = {
"TEXT"
};
-/************** End of global.c **********************************************/
+/************** End of global.c **********************************************/
/************** Begin file status.c ******************************************/
/*
** 2008 June 18
@@ -21696,8 +21696,8 @@ SQLITE_PRIVATE const char *sqlite3StdType[] = {
** 6000 lines long) it was split up into several smaller files and
** this header information was factored out.
*/
-#ifndef SQLITE_VDBEINT_H
-#define SQLITE_VDBEINT_H
+#ifndef SQLITE_VDBEINT_H
+#define SQLITE_VDBEINT_H
/*
** The maximum number of times that a statement will try to reparse
@@ -21708,18 +21708,18 @@ SQLITE_PRIVATE const char *sqlite3StdType[] = {
#endif
/*
-** VDBE_DISPLAY_P4 is true or false depending on whether or not the
-** "explain" P4 display logic is enabled.
-*/
-#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
+** VDBE_DISPLAY_P4 is true or false depending on whether or not the
+** "explain" P4 display logic is enabled.
+*/
+#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) \
|| defined(SQLITE_ENABLE_BYTECODE_VTAB)
-# define VDBE_DISPLAY_P4 1
-#else
-# define VDBE_DISPLAY_P4 0
-#endif
-
-/*
+# define VDBE_DISPLAY_P4 1
+#else
+# define VDBE_DISPLAY_P4 0
+#endif
+
+/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine. Each instruction is an instance
** of the following structure.
@@ -21737,89 +21737,89 @@ typedef struct VdbeSorter VdbeSorter;
/* Elements of the linked list at Vdbe.pAuxData */
typedef struct AuxData AuxData;
-/* Types of VDBE cursors */
-#define CURTYPE_BTREE 0
-#define CURTYPE_SORTER 1
-#define CURTYPE_VTAB 2
-#define CURTYPE_PSEUDO 3
-
+/* Types of VDBE cursors */
+#define CURTYPE_BTREE 0
+#define CURTYPE_SORTER 1
+#define CURTYPE_VTAB 2
+#define CURTYPE_PSEUDO 3
+
/*
-** A VdbeCursor is an superclass (a wrapper) for various cursor objects:
+** A VdbeCursor is an superclass (a wrapper) for various cursor objects:
**
-** * A b-tree cursor
-** - In the main database or in an ephemeral database
-** - On either an index or a table
-** * A sorter
-** * A virtual table
-** * A one-row "pseudotable" stored in a single register
+** * A b-tree cursor
+** - In the main database or in an ephemeral database
+** - On either an index or a table
+** * A sorter
+** * A virtual table
+** * A one-row "pseudotable" stored in a single register
*/
-typedef struct VdbeCursor VdbeCursor;
+typedef struct VdbeCursor VdbeCursor;
struct VdbeCursor {
- u8 eCurType; /* One of the CURTYPE_* values above */
- i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
- u8 nullRow; /* True if pointing to a row with no data */
- u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
- u8 isTable; /* True for rowid tables. False for indexes */
+ u8 eCurType; /* One of the CURTYPE_* values above */
+ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
+ u8 nullRow; /* True if pointing to a row with no data */
+ u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
+ u8 isTable; /* True for rowid tables. False for indexes */
#ifdef SQLITE_DEBUG
- u8 seekOp; /* Most recent seek operation on this cursor */
- u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */
+ u8 seekOp; /* Most recent seek operation on this cursor */
+ u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */
#endif
- Bool isEphemeral:1; /* True for an ephemeral table */
- Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
- Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
+ Bool isEphemeral:1; /* True for an ephemeral table */
+ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
+ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
Bool hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */
u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */
- Btree *pBtx; /* Separate file holding temporary table */
- i64 seqCount; /* Sequence counter */
+ Btree *pBtx; /* Separate file holding temporary table */
+ i64 seqCount; /* Sequence counter */
u32 *aAltMap; /* Mapping from table to index column numbers */
-
- /* Cached OP_Column parse information is only valid if cacheStatus matches
- ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
- ** CACHE_STALE (0) and so setting cacheStatus=CACHE_STALE guarantees that
- ** the cache is out of date. */
- u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
- int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0
- ** if there have been no prior seeks on the cursor. */
- /* seekResult does not distinguish between "no seeks have ever occurred
- ** on this cursor" and "the most recent seek was an exact match".
- ** For CURTYPE_PSEUDO, seekResult is the register holding the record */
-
- /* When a new VdbeCursor is allocated, only the fields above are zeroed.
- ** The fields that follow are uninitialized, and must be individually
- ** initialized prior to first use. */
- VdbeCursor *pAltCursor; /* Associated index cursor from which to read */
- union {
- BtCursor *pCursor; /* CURTYPE_BTREE or _PSEUDO. Btree cursor */
- sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */
- VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */
- } uc;
- KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
- u32 iHdrOffset; /* Offset to next unparsed byte of the header */
- Pgno pgnoRoot; /* Root page of the open btree cursor */
- i16 nField; /* Number of fields in the header */
- u16 nHdrParsed; /* Number of header fields parsed so far */
- i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
- u32 *aOffset; /* Pointer to aType[nField] */
- const u8 *aRow; /* Data for the current row, if all on one page */
- u32 payloadSize; /* Total number of bytes in the record */
- u32 szRow; /* Byte available in aRow */
+
+ /* Cached OP_Column parse information is only valid if cacheStatus matches
+ ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
+ ** CACHE_STALE (0) and so setting cacheStatus=CACHE_STALE guarantees that
+ ** the cache is out of date. */
+ u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
+ int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0
+ ** if there have been no prior seeks on the cursor. */
+ /* seekResult does not distinguish between "no seeks have ever occurred
+ ** on this cursor" and "the most recent seek was an exact match".
+ ** For CURTYPE_PSEUDO, seekResult is the register holding the record */
+
+ /* When a new VdbeCursor is allocated, only the fields above are zeroed.
+ ** The fields that follow are uninitialized, and must be individually
+ ** initialized prior to first use. */
+ VdbeCursor *pAltCursor; /* Associated index cursor from which to read */
+ union {
+ BtCursor *pCursor; /* CURTYPE_BTREE or _PSEUDO. Btree cursor */
+ sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */
+ VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */
+ } uc;
+ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
+ u32 iHdrOffset; /* Offset to next unparsed byte of the header */
+ Pgno pgnoRoot; /* Root page of the open btree cursor */
+ i16 nField; /* Number of fields in the header */
+ u16 nHdrParsed; /* Number of header fields parsed so far */
+ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
+ u32 *aOffset; /* Pointer to aType[nField] */
+ const u8 *aRow; /* Data for the current row, if all on one page */
+ u32 payloadSize; /* Total number of bytes in the record */
+ u32 szRow; /* Byte available in aRow */
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
- u64 maskUsed; /* Mask of columns used by this cursor */
+ u64 maskUsed; /* Mask of columns used by this cursor */
#endif
/* 2*nField extra array elements allocated for aType[], beyond the one
** static element declared in the structure. nField total array slots for
** aType[] and nField+1 array slots for aOffset[] */
- u32 aType[1]; /* Type values record decode. MUST BE LAST */
+ u32 aType[1]; /* Type values record decode. MUST BE LAST */
};
-
+
+/*
+** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
+*/
+#define CACHE_STALE 0
+
/*
-** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
-*/
-#define CACHE_STALE 0
-
-/*
** When a sub-program is executed (OP_Program), a structure of this type
** is allocated to store the current value of the program counter, as
** well as the current memory cell array and various other frame specific
@@ -21848,10 +21848,10 @@ struct VdbeFrame {
i64 *anExec; /* Event counters from parent frame */
Mem *aMem; /* Array of memory cells for parent frame */
VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
- u8 *aOnce; /* Bitmask used by OP_Once */
+ u8 *aOnce; /* Bitmask used by OP_Once */
void *token; /* Copy of SubProgram.token */
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
- AuxData *pAuxData; /* Linked list of auxdata allocations */
+ AuxData *pAuxData; /* Linked list of auxdata allocations */
#if SQLITE_DEBUG
u32 iFrameMagic; /* magic number for sanity checking */
#endif
@@ -21879,17 +21879,17 @@ struct VdbeFrame {
** structures. Each Mem struct may cache multiple representations (string,
** integer etc.) of the same value.
*/
-struct sqlite3_value {
+struct sqlite3_value {
union MemValue {
double r; /* Real value used when MEM_Real is set in flags */
i64 i; /* Integer value used when MEM_Int is set in flags */
- int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
- const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
+ int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
+ const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
FuncDef *pDef; /* Used only when flags==MEM_Agg */
} u;
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
- u8 eSubtype; /* Subtype for this value */
+ u8 eSubtype; /* Subtype for this value */
int n; /* Number of characters in string value, excluding '\0' */
char *z; /* String or BLOB value */
/* ShallowCopy only needs to copy the information above */
@@ -21914,8 +21914,8 @@ struct sqlite3_value {
** representations of the value stored in the Mem struct.
**
** If the MEM_Null flag is set, then the value is an SQL NULL value.
-** For a pointer type created using sqlite3_bind_pointer() or
-** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
+** For a pointer type created using sqlite3_bind_pointer() or
+** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
**
** If the MEM_Str flag is set then Mem.z points at a string representation.
** Usually this is encoded in the same unicode encoding as the main
@@ -21923,7 +21923,7 @@ struct sqlite3_value {
** set, then the string is nul terminated. The MEM_Int and MEM_Real
** flags may coexist with the MEM_Str flag.
*/
-#define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
+#define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
#define MEM_Str 0x0002 /* Value is a string */
#define MEM_Int 0x0004 /* Value is an integer */
#define MEM_Real 0x0008 /* Value is a real number */
@@ -21941,24 +21941,24 @@ struct sqlite3_value {
** policy for Mem.z. The MEM_Term flag tells us whether or not the
** string is \000 or \u0000 terminated
*/
-#define MEM_Term 0x0200 /* String in Mem.z is zero terminated */
+#define MEM_Term 0x0200 /* String in Mem.z is zero terminated */
#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */
#define MEM_Static 0x0800 /* Mem.z points to a static string */
#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */
-#define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */
+#define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */
#ifdef SQLITE_OMIT_INCRBLOB
#undef MEM_Zero
#define MEM_Zero 0x0000
#endif
-/* Return TRUE if Mem X contains dynamically allocated content - anything
-** that needs to be deallocated to avoid a leak.
-*/
-#define VdbeMemDynamic(X) \
+/* Return TRUE if Mem X contains dynamically allocated content - anything
+** that needs to be deallocated to avoid a leak.
+*/
+#define VdbeMemDynamic(X) \
(((X)->flags&(MEM_Agg|MEM_Dyn))!=0)
-
+
/*
** Clear any existing type flags from a Mem and replace them with f
*/
@@ -21988,11 +21988,11 @@ struct sqlite3_value {
** when the VM is halted (if not before).
*/
struct AuxData {
- int iAuxOp; /* Instruction number of OP_Function opcode */
- int iAuxArg; /* Index of function argument. */
+ int iAuxOp; /* Instruction number of OP_Function opcode */
+ int iAuxArg; /* Index of function argument. */
void *pAux; /* Aux data pointer */
- void (*xDeleteAux)(void*); /* Destructor for the aux data */
- AuxData *pNextAux; /* Next element in list */
+ void (*xDeleteAux)(void*); /* Destructor for the aux data */
+ AuxData *pNextAux; /* Next element in list */
};
/*
@@ -22060,39 +22060,39 @@ struct DblquoteStr {
*/
struct Vdbe {
sqlite3 *db; /* The database connection that owns this statement */
- Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
- Parse *pParse; /* Parsing context used to create this Vdbe */
- ynVar nVar; /* Number of entries in aVar[] */
+ Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
+ Parse *pParse; /* Parsing context used to create this Vdbe */
+ ynVar nVar; /* Number of entries in aVar[] */
u32 iVdbeMagic; /* Magic number defining state of the SQL statement */
- int nMem; /* Number of memory locations currently allocated */
- int nCursor; /* Number of slots in apCsr[] */
- u32 cacheCtr; /* VdbeCursor row cache generation counter */
- int pc; /* The program counter */
- int rc; /* Value to return */
+ int nMem; /* Number of memory locations currently allocated */
+ int nCursor; /* Number of slots in apCsr[] */
+ u32 cacheCtr; /* VdbeCursor row cache generation counter */
+ int pc; /* The program counter */
+ int rc; /* Value to return */
i64 nChange; /* Number of db changes made since last reset */
int iStatement; /* Statement number (or 0 if has no opened stmt) */
- i64 iCurrentTime; /* Value of julianday('now') for this statement */
- i64 nFkConstraint; /* Number of imm. FK constraints this VM */
- i64 nStmtDefCons; /* Number of def. constraints when stmt started */
- i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
+ i64 iCurrentTime; /* Value of julianday('now') for this statement */
+ i64 nFkConstraint; /* Number of imm. FK constraints this VM */
+ i64 nStmtDefCons; /* Number of def. constraints when stmt started */
+ i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
Mem *aMem; /* The memory locations */
Mem **apArg; /* Arguments to currently executing user function */
VdbeCursor **apCsr; /* One element of this array for each open cursor */
Mem *aVar; /* Values for the OP_Variable opcode. */
-
- /* When allocating a new Vdbe object, all of the fields below should be
- ** initialized to zero or NULL */
-
+
+ /* When allocating a new Vdbe object, all of the fields below should be
+ ** initialized to zero or NULL */
+
Op *aOp; /* Space to hold the virtual machine's program */
int nOp; /* Number of instructions in the program */
int nOpAlloc; /* Slots allocated for aOp[] */
Mem *aColName; /* Column names to return */
Mem *pResultSet; /* Pointer to an array of results */
char *zErrMsg; /* Error message written here */
- VList *pVList; /* Name of variables */
-#ifndef SQLITE_OMIT_TRACE
- i64 startTime; /* Time when query started - used for profiling */
-#endif
+ VList *pVList; /* Name of variables */
+#ifndef SQLITE_OMIT_TRACE
+ i64 startTime; /* Time when query started - used for profiling */
+#endif
#ifdef SQLITE_DEBUG
int rcApp; /* errcode set by sqlite3_result_error_code() */
u32 nWrite; /* Number of write operations that have occurred */
@@ -22100,7 +22100,7 @@ struct Vdbe {
u16 nResColumn; /* Number of columns in one row of the result set */
u8 errorAction; /* Recovery action to do in case of an error */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
- u8 prepFlags; /* SQLITE_PREPARE_* flags */
+ u8 prepFlags; /* SQLITE_PREPARE_* flags */
u8 doingRerun; /* True if rerunning after an auto-reprepare */
bft expired:2; /* 1: recompile VM immediately 2: when convenient */
bft explain:2; /* True if EXPLAIN present on SQL command */
@@ -22111,7 +22111,7 @@ struct Vdbe {
bft bIsReader:1; /* True for statements that read */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
- u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
+ u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
char *zSql; /* Text of the SQL statement that generated this */
#ifdef SQLITE_ENABLE_NORMALIZE
char *zNormSql; /* Normalization of the associated SQL statement */
@@ -22134,34 +22134,34 @@ struct Vdbe {
/*
** The following are allowed values for Vdbe.magic
*/
-#define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */
-#define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */
-#define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */
-#define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */
-#define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */
+#define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */
+#define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */
+#define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */
+#define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */
+#define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */
/*
** Structure used to store the context required by the
-** sqlite3_preupdate_*() API functions.
-*/
-struct PreUpdate {
- Vdbe *v;
- VdbeCursor *pCsr; /* Cursor to read old values from */
- int op; /* One of SQLITE_INSERT, UPDATE, DELETE */
- u8 *aRecord; /* old.* database record */
- KeyInfo keyinfo;
- UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */
- UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */
- int iNewReg; /* Register for new.* values */
+** sqlite3_preupdate_*() API functions.
+*/
+struct PreUpdate {
+ Vdbe *v;
+ VdbeCursor *pCsr; /* Cursor to read old values from */
+ int op; /* One of SQLITE_INSERT, UPDATE, DELETE */
+ u8 *aRecord; /* old.* database record */
+ KeyInfo keyinfo;
+ UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */
+ UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */
+ int iNewReg; /* Register for new.* values */
int iBlobWrite; /* Value returned by preupdate_blobwrite() */
- i64 iKey1; /* First key value passed to hook */
- i64 iKey2; /* Second key value passed to hook */
- Mem *aNew; /* Array of new.* values */
+ i64 iKey1; /* First key value passed to hook */
+ i64 iKey2; /* Second key value passed to hook */
+ Mem *aNew; /* Array of new.* values */
Table *pTab; /* Schema object being upated */
- Index *pPk; /* PK index if pTab is WITHOUT ROWID */
-};
-
-/*
+ Index *pPk; /* PK index if pTab is WITHOUT ROWID */
+};
+
+/*
** Function prototypes
*/
SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
@@ -22171,10 +22171,10 @@ SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, u32*);
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
-SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
+SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
@@ -22204,7 +22204,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64);
#else
SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
#endif
-SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
+SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
#ifndef SQLITE_OMIT_INCRBLOB
@@ -22227,7 +22227,7 @@ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8);
-SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
+SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
@@ -22246,17 +22246,17 @@ SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*);
SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */
SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */
SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int,int);
-#endif
+#endif
SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *);
SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *);
SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
-SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *);
+SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *);
SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
@@ -22270,11 +22270,11 @@ SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe*);
#endif
#if !defined(SQLITE_OMIT_SHARED_CACHE)
-SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*);
-#else
-# define sqlite3VdbeEnter(X)
-#endif
-
+SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*);
+#else
+# define sqlite3VdbeEnter(X)
+#endif
+
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*);
#else
@@ -22296,10 +22296,10 @@ SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int);
SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr);
#endif
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8);
-SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
-#endif
+#ifndef SQLITE_OMIT_UTF16
+SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8);
+SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
+#endif
#ifndef SQLITE_OMIT_INCRBLOB
SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *);
@@ -22309,7 +22309,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *);
#define ExpandBlob(P) SQLITE_OK
#endif
-#endif /* !defined(SQLITE_VDBEINT_H) */
+#endif /* !defined(SQLITE_VDBEINT_H) */
/************** End of vdbeInt.h *********************************************/
/************** Continuing where we left off in status.c *********************/
@@ -22318,14 +22318,14 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *);
** Variables in which to record status information.
*/
#if SQLITE_PTRSIZE>4
-typedef sqlite3_int64 sqlite3StatValueType;
+typedef sqlite3_int64 sqlite3StatValueType;
#else
-typedef u32 sqlite3StatValueType;
+typedef u32 sqlite3StatValueType;
#endif
-typedef struct sqlite3StatType sqlite3StatType;
-static SQLITE_WSD struct sqlite3StatType {
- sqlite3StatValueType nowValue[10]; /* Current value */
- sqlite3StatValueType mxValue[10]; /* Maximum value */
+typedef struct sqlite3StatType sqlite3StatType;
+static SQLITE_WSD struct sqlite3StatType {
+ sqlite3StatValueType nowValue[10]; /* Current value */
+ sqlite3StatValueType mxValue[10]; /* Maximum value */
} sqlite3Stat = { {0,}, {0,} };
/*
@@ -22406,30 +22406,30 @@ SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){
}
/*
-** Adjust the highwater mark if necessary.
-** The caller must hold the appropriate mutex.
+** Adjust the highwater mark if necessary.
+** The caller must hold the appropriate mutex.
*/
-SQLITE_PRIVATE void sqlite3StatusHighwater(int op, int X){
- sqlite3StatValueType newValue;
+SQLITE_PRIVATE void sqlite3StatusHighwater(int op, int X){
+ sqlite3StatValueType newValue;
wsdStatInit;
- assert( X>=0 );
- newValue = (sqlite3StatValueType)X;
+ assert( X>=0 );
+ newValue = (sqlite3StatValueType)X;
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
assert( op>=0 && op<ArraySize(statMutex) );
assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
: sqlite3MallocMutex()) );
- assert( op==SQLITE_STATUS_MALLOC_SIZE
- || op==SQLITE_STATUS_PAGECACHE_SIZE
- || op==SQLITE_STATUS_PARSER_STACK );
- if( newValue>wsdStat.mxValue[op] ){
- wsdStat.mxValue[op] = newValue;
+ assert( op==SQLITE_STATUS_MALLOC_SIZE
+ || op==SQLITE_STATUS_PAGECACHE_SIZE
+ || op==SQLITE_STATUS_PARSER_STACK );
+ if( newValue>wsdStat.mxValue[op] ){
+ wsdStat.mxValue[op] = newValue;
}
}
/*
** Query status information.
*/
-SQLITE_API int sqlite3_status64(
+SQLITE_API int sqlite3_status64(
int op,
sqlite3_int64 *pCurrent,
sqlite3_int64 *pHighwater,
@@ -22454,8 +22454,8 @@ SQLITE_API int sqlite3_status64(
(void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */
return SQLITE_OK;
}
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
- sqlite3_int64 iCur = 0, iHwtr = 0;
+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
+ sqlite3_int64 iCur = 0, iHwtr = 0;
int rc;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
@@ -22469,35 +22469,35 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
}
/*
-** Return the number of LookasideSlot elements on the linked list
-*/
-static u32 countLookasideSlots(LookasideSlot *p){
- u32 cnt = 0;
- while( p ){
- p = p->pNext;
- cnt++;
- }
- return cnt;
-}
-
-/*
-** Count the number of slots of lookaside memory that are outstanding
-*/
-SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){
- u32 nInit = countLookasideSlots(db->lookaside.pInit);
- u32 nFree = countLookasideSlots(db->lookaside.pFree);
+** Return the number of LookasideSlot elements on the linked list
+*/
+static u32 countLookasideSlots(LookasideSlot *p){
+ u32 cnt = 0;
+ while( p ){
+ p = p->pNext;
+ cnt++;
+ }
+ return cnt;
+}
+
+/*
+** Count the number of slots of lookaside memory that are outstanding
+*/
+SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){
+ u32 nInit = countLookasideSlots(db->lookaside.pInit);
+ u32 nFree = countLookasideSlots(db->lookaside.pFree);
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
nInit += countLookasideSlots(db->lookaside.pSmallInit);
nFree += countLookasideSlots(db->lookaside.pSmallFree);
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
- if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit;
- return db->lookaside.nSlot - (nInit+nFree);
-}
-
-/*
+ if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit;
+ return db->lookaside.nSlot - (nInit+nFree);
+}
+
+/*
** Query status information for a single database connection
*/
-SQLITE_API int sqlite3_db_status(
+SQLITE_API int sqlite3_db_status(
sqlite3 *db, /* The database connection whose status is desired */
int op, /* Status verb */
int *pCurrent, /* Write current value here */
@@ -22513,15 +22513,15 @@ SQLITE_API int sqlite3_db_status(
sqlite3_mutex_enter(db->mutex);
switch( op ){
case SQLITE_DBSTATUS_LOOKASIDE_USED: {
- *pCurrent = sqlite3LookasideUsed(db, pHighwater);
+ *pCurrent = sqlite3LookasideUsed(db, pHighwater);
if( resetFlag ){
- LookasideSlot *p = db->lookaside.pFree;
- if( p ){
- while( p->pNext ) p = p->pNext;
- p->pNext = db->lookaside.pInit;
- db->lookaside.pInit = db->lookaside.pFree;
- db->lookaside.pFree = 0;
- }
+ LookasideSlot *p = db->lookaside.pFree;
+ if( p ){
+ while( p->pNext ) p = p->pNext;
+ p->pNext = db->lookaside.pInit;
+ db->lookaside.pInit = db->lookaside.pFree;
+ db->lookaside.pFree = 0;
+ }
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
p = db->lookaside.pSmallFree;
if( p ){
@@ -22556,7 +22556,7 @@ SQLITE_API int sqlite3_db_status(
** by all pagers associated with the given database connection. The
** highwater mark is meaningless and is returned as zero.
*/
- case SQLITE_DBSTATUS_CACHE_USED_SHARED:
+ case SQLITE_DBSTATUS_CACHE_USED_SHARED:
case SQLITE_DBSTATUS_CACHE_USED: {
int totalUsed = 0;
int i;
@@ -22565,11 +22565,11 @@ SQLITE_API int sqlite3_db_status(
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
Pager *pPager = sqlite3BtreePager(pBt);
- int nByte = sqlite3PagerMemUsed(pPager);
- if( op==SQLITE_DBSTATUS_CACHE_USED_SHARED ){
- nByte = nByte / sqlite3BtreeConnectionCount(pBt);
- }
- totalUsed += nByte;
+ int nByte = sqlite3PagerMemUsed(pPager);
+ if( op==SQLITE_DBSTATUS_CACHE_USED_SHARED ){
+ nByte = nByte / sqlite3BtreeConnectionCount(pBt);
+ }
+ totalUsed += nByte;
}
}
sqlite3BtreeLeaveAll(db);
@@ -22600,10 +22600,10 @@ SQLITE_API int sqlite3_db_status(
+ pSchema->idxHash.count
+ pSchema->fkeyHash.count
);
- nByte += sqlite3_msize(pSchema->tblHash.ht);
- nByte += sqlite3_msize(pSchema->trigHash.ht);
- nByte += sqlite3_msize(pSchema->idxHash.ht);
- nByte += sqlite3_msize(pSchema->fkeyHash.ht);
+ nByte += sqlite3_msize(pSchema->tblHash.ht);
+ nByte += sqlite3_msize(pSchema->trigHash.ht);
+ nByte += sqlite3_msize(pSchema->idxHash.ht);
+ nByte += sqlite3_msize(pSchema->fkeyHash.ht);
for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
@@ -22733,7 +22733,7 @@ SQLITE_API int sqlite3_db_status(
**
** Jean Meeus
** Astronomical Algorithms, 2nd Edition, 1998
-** ISBN 0-943396-61-1
+** ISBN 0-943396-61-1
** Willmann-Bell, Inc
** Richmond, Virginia (USA)
*/
@@ -22744,80 +22744,80 @@ SQLITE_API int sqlite3_db_status(
#ifndef SQLITE_OMIT_DATETIME_FUNCS
-/*
-** The MSVC CRT on Windows CE may not have a localtime() function.
-** So declare a substitute. The substitute function itself is
-** defined in "os_win.c".
-*/
-#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
- (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
-struct tm *__cdecl localtime(const time_t *);
-#endif
+/*
+** The MSVC CRT on Windows CE may not have a localtime() function.
+** So declare a substitute. The substitute function itself is
+** defined in "os_win.c".
+*/
+#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
+ (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
+struct tm *__cdecl localtime(const time_t *);
+#endif
/*
** A structure for holding a single date and time.
*/
typedef struct DateTime DateTime;
struct DateTime {
- sqlite3_int64 iJD; /* The julian day number times 86400000 */
- int Y, M, D; /* Year, month, and day */
- int h, m; /* Hour and minutes */
- int tz; /* Timezone offset in minutes */
- double s; /* Seconds */
- char validJD; /* True (1) if iJD is valid */
- char rawS; /* Raw numeric value stored in s */
- char validYMD; /* True (1) if Y,M,D are valid */
- char validHMS; /* True (1) if h,m,s are valid */
- char validTZ; /* True (1) if tz is valid */
- char tzSet; /* Timezone was set explicitly */
- char isError; /* An overflow has occurred */
+ sqlite3_int64 iJD; /* The julian day number times 86400000 */
+ int Y, M, D; /* Year, month, and day */
+ int h, m; /* Hour and minutes */
+ int tz; /* Timezone offset in minutes */
+ double s; /* Seconds */
+ char validJD; /* True (1) if iJD is valid */
+ char rawS; /* Raw numeric value stored in s */
+ char validYMD; /* True (1) if Y,M,D are valid */
+ char validHMS; /* True (1) if h,m,s are valid */
+ char validTZ; /* True (1) if tz is valid */
+ char tzSet; /* Timezone was set explicitly */
+ char isError; /* An overflow has occurred */
};
/*
-** Convert zDate into one or more integers according to the conversion
-** specifier zFormat.
-**
-** zFormat[] contains 4 characters for each integer converted, except for
-** the last integer which is specified by three characters. The meaning
-** of a four-character format specifiers ABCD is:
-**
-** A: number of digits to convert. Always "2" or "4".
-** B: minimum value. Always "0" or "1".
-** C: maximum value, decoded as:
-** a: 12
-** b: 14
-** c: 24
-** d: 31
-** e: 59
-** f: 9999
-** D: the separator character, or \000 to indicate this is the
-** last number to convert.
-**
-** Example: To translate an ISO-8601 date YYYY-MM-DD, the format would
-** be "40f-21a-20c". The "40f-" indicates the 4-digit year followed by "-".
-** The "21a-" indicates the 2-digit month followed by "-". The "20c" indicates
-** the 2-digit day which is the last integer in the set.
-**
+** Convert zDate into one or more integers according to the conversion
+** specifier zFormat.
+**
+** zFormat[] contains 4 characters for each integer converted, except for
+** the last integer which is specified by three characters. The meaning
+** of a four-character format specifiers ABCD is:
+**
+** A: number of digits to convert. Always "2" or "4".
+** B: minimum value. Always "0" or "1".
+** C: maximum value, decoded as:
+** a: 12
+** b: 14
+** c: 24
+** d: 31
+** e: 59
+** f: 9999
+** D: the separator character, or \000 to indicate this is the
+** last number to convert.
+**
+** Example: To translate an ISO-8601 date YYYY-MM-DD, the format would
+** be "40f-21a-20c". The "40f-" indicates the 4-digit year followed by "-".
+** The "21a-" indicates the 2-digit month followed by "-". The "20c" indicates
+** the 2-digit day which is the last integer in the set.
+**
** The function returns the number of successful conversions.
*/
-static int getDigits(const char *zDate, const char *zFormat, ...){
- /* The aMx[] array translates the 3rd character of each format
- ** spec into a max size: a b c d e f */
- static const u16 aMx[] = { 12, 14, 24, 31, 59, 9999 };
+static int getDigits(const char *zDate, const char *zFormat, ...){
+ /* The aMx[] array translates the 3rd character of each format
+ ** spec into a max size: a b c d e f */
+ static const u16 aMx[] = { 12, 14, 24, 31, 59, 9999 };
va_list ap;
int cnt = 0;
- char nextC;
- va_start(ap, zFormat);
+ char nextC;
+ va_start(ap, zFormat);
do{
- char N = zFormat[0] - '0';
- char min = zFormat[1] - '0';
- int val = 0;
- u16 max;
-
- assert( zFormat[2]>='a' && zFormat[2]<='f' );
- max = aMx[zFormat[2] - 'a'];
- nextC = zFormat[3];
+ char N = zFormat[0] - '0';
+ char min = zFormat[1] - '0';
+ int val = 0;
+ u16 max;
+
+ assert( zFormat[2]>='a' && zFormat[2]<='f' );
+ max = aMx[zFormat[2] - 'a'];
+ nextC = zFormat[3];
val = 0;
while( N-- ){
if( !sqlite3Isdigit(*zDate) ){
@@ -22826,13 +22826,13 @@ static int getDigits(const char *zDate, const char *zFormat, ...){
val = val*10 + *zDate - '0';
zDate++;
}
- if( val<(int)min || val>(int)max || (nextC!=0 && nextC!=*zDate) ){
+ if( val<(int)min || val>(int)max || (nextC!=0 && nextC!=*zDate) ){
goto end_getDigits;
}
- *va_arg(ap,int*) = val;
+ *va_arg(ap,int*) = val;
zDate++;
cnt++;
- zFormat += 4;
+ zFormat += 4;
}while( nextC );
end_getDigits:
va_end(ap);
@@ -22873,14 +22873,14 @@ static int parseTimezone(const char *zDate, DateTime *p){
return c!=0;
}
zDate++;
- if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){
+ if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){
return 1;
}
zDate += 5;
p->tz = sgn*(nMn + nHr*60);
zulu_time:
while( sqlite3Isspace(*zDate) ){ zDate++; }
- p->tzSet = 1;
+ p->tzSet = 1;
return *zDate!=0;
}
@@ -22894,13 +22894,13 @@ zulu_time:
static int parseHhMmSs(const char *zDate, DateTime *p){
int h, m, s;
double ms = 0.0;
- if( getDigits(zDate, "20c:20e", &h, &m)!=2 ){
+ if( getDigits(zDate, "20c:20e", &h, &m)!=2 ){
return 1;
}
zDate += 5;
if( *zDate==':' ){
zDate++;
- if( getDigits(zDate, "20e", &s)!=1 ){
+ if( getDigits(zDate, "20e", &s)!=1 ){
return 1;
}
zDate += 2;
@@ -22918,7 +22918,7 @@ static int parseHhMmSs(const char *zDate, DateTime *p){
s = 0;
}
p->validJD = 0;
- p->rawS = 0;
+ p->rawS = 0;
p->validHMS = 1;
p->h = h;
p->m = m;
@@ -22929,14 +22929,14 @@ static int parseHhMmSs(const char *zDate, DateTime *p){
}
/*
-** Put the DateTime object into its error state.
-*/
-static void datetimeError(DateTime *p){
- memset(p, 0, sizeof(*p));
- p->isError = 1;
-}
-
-/*
+** Put the DateTime object into its error state.
+*/
+static void datetimeError(DateTime *p){
+ memset(p, 0, sizeof(*p));
+ p->isError = 1;
+}
+
+/*
** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume
** that the YYYY-MM-DD is according to the Gregorian calendar.
**
@@ -22955,10 +22955,10 @@ static void computeJD(DateTime *p){
M = 1;
D = 1;
}
- if( Y<-4713 || Y>9999 || p->rawS ){
- datetimeError(p);
- return;
- }
+ if( Y<-4713 || Y>9999 || p->rawS ){
+ datetimeError(p);
+ return;
+ }
if( M<=2 ){
Y--;
M += 12;
@@ -23001,7 +23001,7 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){
}else{
neg = 0;
}
- if( getDigits(zDate, "40f-21a-21d", &Y, &M, &D)!=3 ){
+ if( getDigits(zDate, "40f-21a-21d", &Y, &M, &D)!=3 ){
return 1;
}
zDate += 10;
@@ -23040,21 +23040,21 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
}
/*
-** Input "r" is a numeric quantity which might be a julian day number,
-** or the number of seconds since 1970. If the value if r is within
-** range of a julian day number, install it as such and set validJD.
-** If the value is a valid unix timestamp, put it in p->s and set p->rawS.
-*/
-static void setRawDateNumber(DateTime *p, double r){
- p->s = r;
- p->rawS = 1;
- if( r>=0.0 && r<5373484.5 ){
- p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
- p->validJD = 1;
- }
-}
-
-/*
+** Input "r" is a numeric quantity which might be a julian day number,
+** or the number of seconds since 1970. If the value if r is within
+** range of a julian day number, install it as such and set validJD.
+** If the value is a valid unix timestamp, put it in p->s and set p->rawS.
+*/
+static void setRawDateNumber(DateTime *p, double r){
+ p->s = r;
+ p->rawS = 1;
+ if( r>=0.0 && r<5373484.5 ){
+ p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
+ p->validJD = 1;
+ }
+}
+
+/*
** Attempt to parse the given string into a julian day number. Return
** the number of errors.
**
@@ -23080,34 +23080,34 @@ static int parseDateOrTime(
return 0;
}else if( parseHhMmSs(zDate, p)==0 ){
return 0;
- }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){
+ }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){
return setDateTimeToCurrent(context, p);
}else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){
- setRawDateNumber(p, r);
+ setRawDateNumber(p, r);
return 0;
}
return 1;
}
-/* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999.
-** Multiplying this by 86400000 gives 464269060799999 as the maximum value
-** for DateTime.iJD.
-**
+/* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999.
+** Multiplying this by 86400000 gives 464269060799999 as the maximum value
+** for DateTime.iJD.
+**
** But some older compilers (ex: gcc 4.2.1 on older Macs) cannot deal with
-** such a large integer literal, so we have to encode it.
-*/
-#define INT_464269060799999 ((((i64)0x1a640)<<32)|0x1072fdff)
-
-/*
-** Return TRUE if the given julian day number is within range.
-**
-** The input is the JulianDay times 86400000.
-*/
-static int validJulianDay(sqlite3_int64 iJD){
- return iJD>=0 && iJD<=INT_464269060799999;
-}
-
-/*
+** such a large integer literal, so we have to encode it.
+*/
+#define INT_464269060799999 ((((i64)0x1a640)<<32)|0x1072fdff)
+
+/*
+** Return TRUE if the given julian day number is within range.
+**
+** The input is the JulianDay times 86400000.
+*/
+static int validJulianDay(sqlite3_int64 iJD){
+ return iJD>=0 && iJD<=INT_464269060799999;
+}
+
+/*
** Compute the Year, Month, and Day from the julian day number.
*/
static void computeYMD(DateTime *p){
@@ -23117,9 +23117,9 @@ static void computeYMD(DateTime *p){
p->Y = 2000;
p->M = 1;
p->D = 1;
- }else if( !validJulianDay(p->iJD) ){
- datetimeError(p);
- return;
+ }else if( !validJulianDay(p->iJD) ){
+ datetimeError(p);
+ return;
}else{
Z = (int)((p->iJD + 43200000)/86400000);
A = (int)((Z - 1867216.25)/36524.25);
@@ -23151,7 +23151,7 @@ static void computeHMS(DateTime *p){
s -= p->h*3600;
p->m = s/60;
p->s += s - p->m*60;
- p->rawS = 0;
+ p->rawS = 0;
p->validHMS = 1;
}
@@ -23172,7 +23172,7 @@ static void clearYMD_HMS_TZ(DateTime *p){
p->validTZ = 0;
}
-#ifndef SQLITE_OMIT_LOCALTIME
+#ifndef SQLITE_OMIT_LOCALTIME
/*
** On recent Windows platforms, the localtime_s() function is available
** as part of the "Secure CRT". It is essentially equivalent to
@@ -23213,14 +23213,14 @@ static int osLocaltime(time_t *t, struct tm *pTm){
#endif
sqlite3_mutex_enter(mutex);
pX = localtime(t);
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
#endif
if( pX ) *pTm = *pX;
sqlite3_mutex_leave(mutex);
rc = pX==0;
#else
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
#endif
#if HAVE_LOCALTIME_R
@@ -23291,9 +23291,9 @@ static sqlite3_int64 localtimeOffset(
y.validYMD = 1;
y.validHMS = 1;
y.validJD = 0;
- y.rawS = 0;
+ y.rawS = 0;
y.validTZ = 0;
- y.isError = 0;
+ y.isError = 0;
computeJD(&y);
*pRc = SQLITE_OK;
return y.iJD - x.iJD;
@@ -23301,29 +23301,29 @@ static sqlite3_int64 localtimeOffset(
#endif /* SQLITE_OMIT_LOCALTIME */
/*
-** The following table defines various date transformations of the form
-**
-** 'NNN days'
-**
-** Where NNN is an arbitrary floating-point number and "days" can be one
-** of several units of time.
-*/
-static const struct {
- u8 eType; /* Transformation type code */
- u8 nName; /* Length of th name */
- char *zName; /* Name of the transformation */
- double rLimit; /* Maximum NNN value for this transform */
- double rXform; /* Constant used for this transform */
-} aXformType[] = {
+** The following table defines various date transformations of the form
+**
+** 'NNN days'
+**
+** Where NNN is an arbitrary floating-point number and "days" can be one
+** of several units of time.
+*/
+static const struct {
+ u8 eType; /* Transformation type code */
+ u8 nName; /* Length of th name */
+ char *zName; /* Name of the transformation */
+ double rLimit; /* Maximum NNN value for this transform */
+ double rXform; /* Constant used for this transform */
+} aXformType[] = {
{ 0, 6, "second", 464269060800.0, 1000.0 },
{ 0, 6, "minute", 7737817680.0, 60000.0 },
{ 0, 4, "hour", 128963628.0, 3600000.0 },
{ 0, 3, "day", 5373485.0, 86400000.0 },
{ 1, 5, "month", 176546.0, 2592000000.0 },
{ 2, 4, "year", 14713.0, 31536000000.0 },
-};
-
-/*
+};
+
+/*
** Process a modifier to a date-time stamp. The modifiers are
** as follows:
**
@@ -23347,15 +23347,15 @@ static const struct {
** to context pCtx. If the error is an unrecognized modifier, no error is
** written to pCtx.
*/
-static int parseModifier(
- sqlite3_context *pCtx, /* Function context */
- const char *z, /* The text of the modifier */
- int n, /* Length of zMod in bytes */
- DateTime *p /* The date/time value to be modified */
-){
+static int parseModifier(
+ sqlite3_context *pCtx, /* Function context */
+ const char *z, /* The text of the modifier */
+ int n, /* Length of zMod in bytes */
+ DateTime *p /* The date/time value to be modified */
+){
int rc = 1;
double r;
- switch(sqlite3UpperToLower[(u8)z[0]] ){
+ switch(sqlite3UpperToLower[(u8)z[0]] ){
#ifndef SQLITE_OMIT_LOCALTIME
case 'l': {
/* localtime
@@ -23363,7 +23363,7 @@ static int parseModifier(
** Assuming the current time value is UTC (a.k.a. GMT), shift it to
** show local time.
*/
- if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
+ if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
computeJD(p);
p->iJD += localtimeOffset(p, pCtx, &rc);
clearYMD_HMS_TZ(p);
@@ -23375,33 +23375,33 @@ static int parseModifier(
/*
** unixepoch
**
- ** Treat the current value of p->s as the number of
+ ** Treat the current value of p->s as the number of
** seconds since 1970. Convert to a real julian day number.
*/
- if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
- r = p->s*1000.0 + 210866760000000.0;
- if( r>=0.0 && r<464269060800000.0 ){
- clearYMD_HMS_TZ(p);
+ if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
+ r = p->s*1000.0 + 210866760000000.0;
+ if( r>=0.0 && r<464269060800000.0 ){
+ clearYMD_HMS_TZ(p);
p->iJD = (sqlite3_int64)(r + 0.5);
- p->validJD = 1;
- p->rawS = 0;
- rc = 0;
- }
+ p->validJD = 1;
+ p->rawS = 0;
+ rc = 0;
+ }
}
#ifndef SQLITE_OMIT_LOCALTIME
- else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
- if( p->tzSet==0 ){
- sqlite3_int64 c1;
- computeJD(p);
- c1 = localtimeOffset(p, pCtx, &rc);
- if( rc==SQLITE_OK ){
- p->iJD -= c1;
- clearYMD_HMS_TZ(p);
- p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
- }
- p->tzSet = 1;
- }else{
- rc = SQLITE_OK;
+ else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
+ if( p->tzSet==0 ){
+ sqlite3_int64 c1;
+ computeJD(p);
+ c1 = localtimeOffset(p, pCtx, &rc);
+ if( rc==SQLITE_OK ){
+ p->iJD -= c1;
+ clearYMD_HMS_TZ(p);
+ p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
+ }
+ p->tzSet = 1;
+ }else{
+ rc = SQLITE_OK;
}
}
#endif
@@ -23415,7 +23415,7 @@ static int parseModifier(
** weekday N where 0==Sunday, 1==Monday, and so forth. If the
** date is already on the appropriate weekday, this is a no-op.
*/
- if( sqlite3_strnicmp(z, "weekday ", 8)==0
+ if( sqlite3_strnicmp(z, "weekday ", 8)==0
&& sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0
&& (n=(int)r)==r && n>=0 && r<7 ){
sqlite3_int64 Z;
@@ -23438,24 +23438,24 @@ static int parseModifier(
** Move the date backwards to the beginning of the current day,
** or month or year.
*/
- if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break;
- if( !p->validJD && !p->validYMD && !p->validHMS ) break;
+ if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break;
+ if( !p->validJD && !p->validYMD && !p->validHMS ) break;
z += 9;
computeYMD(p);
p->validHMS = 1;
p->h = p->m = 0;
p->s = 0.0;
- p->rawS = 0;
+ p->rawS = 0;
p->validTZ = 0;
p->validJD = 0;
- if( sqlite3_stricmp(z,"month")==0 ){
+ if( sqlite3_stricmp(z,"month")==0 ){
p->D = 1;
rc = 0;
- }else if( sqlite3_stricmp(z,"year")==0 ){
+ }else if( sqlite3_stricmp(z,"year")==0 ){
p->M = 1;
p->D = 1;
rc = 0;
- }else if( sqlite3_stricmp(z,"day")==0 ){
+ }else if( sqlite3_stricmp(z,"day")==0 ){
rc = 0;
}
break;
@@ -23473,7 +23473,7 @@ static int parseModifier(
case '8':
case '9': {
double rRounder;
- int i;
+ int i;
for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){
rc = 1;
@@ -23502,47 +23502,47 @@ static int parseModifier(
rc = 0;
break;
}
-
- /* If control reaches this point, it means the transformation is
- ** one of the forms like "+NNN days". */
+
+ /* If control reaches this point, it means the transformation is
+ ** one of the forms like "+NNN days". */
z += n;
while( sqlite3Isspace(*z) ) z++;
n = sqlite3Strlen30(z);
if( n>10 || n<3 ) break;
- if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--;
+ if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--;
computeJD(p);
- rc = 1;
+ rc = 1;
rRounder = r<0 ? -0.5 : +0.5;
- for(i=0; i<ArraySize(aXformType); i++){
- if( aXformType[i].nName==n
- && sqlite3_strnicmp(aXformType[i].zName, z, n)==0
- && r>-aXformType[i].rLimit && r<aXformType[i].rLimit
- ){
- switch( aXformType[i].eType ){
- case 1: { /* Special processing to add months */
- int x;
- computeYMD_HMS(p);
- p->M += (int)r;
- x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
- p->Y += x;
- p->M -= x*12;
- p->validJD = 0;
- r -= (int)r;
- break;
- }
- case 2: { /* Special processing to add years */
- int y = (int)r;
- computeYMD_HMS(p);
- p->Y += y;
- p->validJD = 0;
- r -= (int)r;
- break;
- }
- }
- computeJD(p);
- p->iJD += (sqlite3_int64)(r*aXformType[i].rXform + rRounder);
- rc = 0;
- break;
+ for(i=0; i<ArraySize(aXformType); i++){
+ if( aXformType[i].nName==n
+ && sqlite3_strnicmp(aXformType[i].zName, z, n)==0
+ && r>-aXformType[i].rLimit && r<aXformType[i].rLimit
+ ){
+ switch( aXformType[i].eType ){
+ case 1: { /* Special processing to add months */
+ int x;
+ computeYMD_HMS(p);
+ p->M += (int)r;
+ x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
+ p->Y += x;
+ p->M -= x*12;
+ p->validJD = 0;
+ r -= (int)r;
+ break;
+ }
+ case 2: { /* Special processing to add years */
+ int y = (int)r;
+ computeYMD_HMS(p);
+ p->Y += y;
+ p->validJD = 0;
+ r -= (int)r;
+ break;
+ }
+ }
+ computeJD(p);
+ p->iJD += (sqlite3_int64)(r*aXformType[i].rXform + rRounder);
+ rc = 0;
+ break;
}
}
clearYMD_HMS_TZ(p);
@@ -23570,7 +23570,7 @@ static int isDate(
sqlite3_value **argv,
DateTime *p
){
- int i, n;
+ int i, n;
const unsigned char *z;
int eType;
memset(p, 0, sizeof(*p));
@@ -23580,7 +23580,7 @@ static int isDate(
}
if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
|| eType==SQLITE_INTEGER ){
- setRawDateNumber(p, sqlite3_value_double(argv[0]));
+ setRawDateNumber(p, sqlite3_value_double(argv[0]));
}else{
z = sqlite3_value_text(argv[0]);
if( !z || parseDateOrTime(context, (char*)z, p) ){
@@ -23589,11 +23589,11 @@ static int isDate(
}
for(i=1; i<argc; i++){
z = sqlite3_value_text(argv[i]);
- n = sqlite3_value_bytes(argv[i]);
- if( z==0 || parseModifier(context, (char*)z, n, p) ) return 1;
+ n = sqlite3_value_bytes(argv[i]);
+ if( z==0 || parseModifier(context, (char*)z, n, p) ) return 1;
}
- computeJD(p);
- if( p->isError || !validJulianDay(p->iJD) ) return 1;
+ computeJD(p);
+ if( p->isError || !validJulianDay(p->iJD) ) return 1;
return 0;
}
@@ -23893,23 +23893,23 @@ static void currentTimeFunc(
** external linkage.
*/
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
- static FuncDef aDateTimeFuncs[] = {
+ static FuncDef aDateTimeFuncs[] = {
#ifndef SQLITE_OMIT_DATETIME_FUNCS
- PURE_DATE(julianday, -1, 0, 0, juliandayFunc ),
- PURE_DATE(date, -1, 0, 0, dateFunc ),
- PURE_DATE(time, -1, 0, 0, timeFunc ),
- PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
- PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
- DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
- DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
- DFUNCTION(current_date, 0, 0, 0, cdateFunc ),
+ PURE_DATE(julianday, -1, 0, 0, juliandayFunc ),
+ PURE_DATE(date, -1, 0, 0, dateFunc ),
+ PURE_DATE(time, -1, 0, 0, timeFunc ),
+ PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
+ PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
+ DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
+ DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
+ DFUNCTION(current_date, 0, 0, 0, cdateFunc ),
#else
STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc),
STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc),
STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
#endif
};
- sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs));
+ sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs));
}
/************** End of date.c ************************************************/
@@ -23932,35 +23932,35 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
/* #include "sqliteInt.h" */
/*
-** If we compile with the SQLITE_TEST macro set, then the following block
-** of code will give us the ability to simulate a disk I/O error. This
-** is used for testing the I/O recovery logic.
-*/
-#if defined(SQLITE_TEST)
-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;
-#endif /* defined(SQLITE_TEST) */
-
-/*
-** When testing, also keep a count of the number of open files.
-*/
-#if defined(SQLITE_TEST)
-SQLITE_API int sqlite3_open_file_count = 0;
-#endif /* defined(SQLITE_TEST) */
-
-/*
+** If we compile with the SQLITE_TEST macro set, then the following block
+** of code will give us the ability to simulate a disk I/O error. This
+** is used for testing the I/O recovery logic.
+*/
+#if defined(SQLITE_TEST)
+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;
+#endif /* defined(SQLITE_TEST) */
+
+/*
+** When testing, also keep a count of the number of open files.
+*/
+#if defined(SQLITE_TEST)
+SQLITE_API int sqlite3_open_file_count = 0;
+#endif /* defined(SQLITE_TEST) */
+
+/*
** The default SQLite sqlite3_vfs implementations do not allocate
** memory (actually, os_unix.c allocates a small amount of memory
** from within OsOpen()), but some third-party implementations may.
** So we test the effects of a malloc() failing and the sqlite3OsXXX()
** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
**
-** The following functions are instrumented for malloc() failure
+** The following functions are instrumented for malloc() failure
** testing:
**
** sqlite3OsRead()
@@ -23980,9 +23980,9 @@ SQLITE_API int sqlite3_open_file_count = 0;
#if defined(SQLITE_TEST)
SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1;
#define DO_OS_MALLOC_TEST(x) \
- if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3JournalIsInMemory(x))) { \
+ if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3JournalIsInMemory(x))) { \
void *pTstAlloc = sqlite3Malloc(10); \
- if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT; \
+ if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT; \
sqlite3_free(pTstAlloc); \
}
#else
@@ -23995,9 +23995,9 @@ SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1;
** of this would be completely automatic if SQLite were coded using
** C++ instead of plain old C.
*/
-SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file *pId){
+SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file *pId){
if( pId->pMethods ){
- pId->pMethods->xClose(pId);
+ pId->pMethods->xClose(pId);
pId->pMethods = 0;
}
}
@@ -24014,7 +24014,7 @@ SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){
}
SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){
DO_OS_MALLOC_TEST(id);
- return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK;
+ return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK;
}
SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
DO_OS_MALLOC_TEST(id);
@@ -24049,8 +24049,8 @@ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
&& op!=SQLITE_FCNTL_CKPT_START
){
/* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
- ** is using a regular VFS, it is called after the corresponding
- ** transaction has been committed. Injecting a fault at this point
+ ** is using a regular VFS, it is called after the corresponding
+ ** transaction has been committed. Injecting a fault at this point
** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
** but the transaction is committed anyway.
**
@@ -24080,7 +24080,7 @@ SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
if( NEVER(id->pMethods==0) ) return 0;
return id->pMethods->xDeviceCharacteristics(id);
}
-#ifndef SQLITE_OMIT_WAL
+#ifndef SQLITE_OMIT_WAL
SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
return id->pMethods->xShmLock(id, offset, n, flags);
}
@@ -24100,7 +24100,7 @@ SQLITE_PRIVATE int sqlite3OsShmMap(
DO_OS_MALLOC_TEST(id);
return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
}
-#endif /* SQLITE_OMIT_WAL */
+#endif /* SQLITE_OMIT_WAL */
#if SQLITE_MAX_MMAP_SIZE>0
/* The real implementation of xFetch and xUnfetch */
@@ -24127,10 +24127,10 @@ SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
** VFS methods.
*/
SQLITE_PRIVATE int sqlite3OsOpen(
- sqlite3_vfs *pVfs,
- const char *zPath,
- sqlite3_file *pFile,
- int flags,
+ sqlite3_vfs *pVfs,
+ const char *zPath,
+ sqlite3_file *pFile,
+ int flags,
int *pFlagsOut
){
int rc;
@@ -24149,18 +24149,18 @@ SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dir
return pVfs->xDelete!=0 ? pVfs->xDelete(pVfs, zPath, dirSync) : SQLITE_OK;
}
SQLITE_PRIVATE int sqlite3OsAccess(
- sqlite3_vfs *pVfs,
- const char *zPath,
- int flags,
+ sqlite3_vfs *pVfs,
+ const char *zPath,
+ int flags,
int *pResOut
){
DO_OS_MALLOC_TEST(0);
return pVfs->xAccess(pVfs, zPath, flags, pResOut);
}
SQLITE_PRIVATE int sqlite3OsFullPathname(
- sqlite3_vfs *pVfs,
- const char *zPath,
- int nPathOut,
+ sqlite3_vfs *pVfs,
+ const char *zPath,
+ int nPathOut,
char *zPathOut
){
DO_OS_MALLOC_TEST(0);
@@ -24197,9 +24197,9 @@ SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufO
SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
return pVfs->xSleep(pVfs, nMicro);
}
-SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs *pVfs){
- return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0;
-}
+SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs *pVfs){
+ return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0;
+}
SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
int rc;
/* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
@@ -24219,13 +24219,13 @@ SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p
}
SQLITE_PRIVATE int sqlite3OsOpenMalloc(
- sqlite3_vfs *pVfs,
- const char *zFile,
- sqlite3_file **ppFile,
+ sqlite3_vfs *pVfs,
+ const char *zFile,
+ sqlite3_file **ppFile,
int flags,
int *pOutFlags
){
- int rc;
+ int rc;
sqlite3_file *pFile;
pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
if( pFile ){
@@ -24236,16 +24236,16 @@ SQLITE_PRIVATE int sqlite3OsOpenMalloc(
}else{
*ppFile = pFile;
}
- }else{
+ }else{
*ppFile = 0;
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
assert( *ppFile!=0 || rc!=SQLITE_OK );
return rc;
}
-SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
+SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
assert( pFile );
- sqlite3OsClose(pFile);
+ sqlite3OsClose(pFile);
sqlite3_free(pFile);
}
@@ -24257,7 +24257,7 @@ SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
*/
SQLITE_PRIVATE int sqlite3OsInit(void){
void *p = sqlite3_malloc(10);
- if( p==0 ) return SQLITE_NOMEM_BKPT;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
sqlite3_free(p);
return sqlite3_os_init();
}
@@ -24272,7 +24272,7 @@ static sqlite3_vfs * SQLITE_WSD vfsList = 0;
** Locate a VFS by name. If no name is given, simply return the
** first VFS on the list.
*/
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
+SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
sqlite3_vfs *pVfs = 0;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex;
@@ -24318,7 +24318,7 @@ static void vfsUnlink(sqlite3_vfs *pVfs){
** VFS multiple times. The new VFS becomes the default if makeDflt is
** true.
*/
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
+SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
MUTEX_LOGIC(sqlite3_mutex *mutex;)
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
@@ -24346,7 +24346,7 @@ SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
/*
** Unregister a VFS so that it is no longer accessible.
*/
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
+SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
MUTEX_LOGIC(sqlite3_mutex *mutex;)
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
@@ -24389,7 +24389,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
/* #include "sqliteInt.h" */
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
/*
** Global variables.
@@ -24447,7 +24447,7 @@ SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){
}
}
-#endif /* #ifndef SQLITE_UNTESTABLE */
+#endif /* #ifndef SQLITE_UNTESTABLE */
/************** End of fault.c ***********************************************/
/************** Begin file mem0.c ********************************************/
@@ -24572,9 +24572,9 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
*/
#include <sys/sysctl.h>
#include <malloc/malloc.h>
-#ifdef SQLITE_MIGHT_BE_SINGLE_CORE
+#ifdef SQLITE_MIGHT_BE_SINGLE_CORE
#include <libkern/OSAtomic.h>
-#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */
+#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */
static malloc_zone_t* _sqliteZone_;
#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
@@ -24642,9 +24642,9 @@ static malloc_zone_t* _sqliteZone_;
*/
static void *sqlite3MemMalloc(int nByte){
#ifdef SQLITE_MALLOCSIZE
- void *p;
- testcase( ROUND8(nByte)==nByte );
- p = SQLITE_MALLOC( nByte );
+ void *p;
+ testcase( ROUND8(nByte)==nByte );
+ p = SQLITE_MALLOC( nByte );
if( p==0 ){
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
@@ -24653,7 +24653,7 @@ static void *sqlite3MemMalloc(int nByte){
#else
sqlite3_int64 *p;
assert( nByte>0 );
- testcase( ROUND8(nByte)!=nByte );
+ testcase( ROUND8(nByte)!=nByte );
p = SQLITE_MALLOC( nByte+8 );
if( p ){
p[0] = nByte;
@@ -24691,11 +24691,11 @@ static void sqlite3MemFree(void *pPrior){
*/
static int sqlite3MemSize(void *pPrior){
#ifdef SQLITE_MALLOCSIZE
- assert( pPrior!=0 );
- return (int)SQLITE_MALLOCSIZE(pPrior);
+ assert( pPrior!=0 );
+ return (int)SQLITE_MALLOCSIZE(pPrior);
#else
sqlite3_int64 *p;
- assert( pPrior!=0 );
+ assert( pPrior!=0 );
p = (sqlite3_int64*)pPrior;
p--;
return (int)p[0];
@@ -24767,10 +24767,10 @@ static int sqlite3MemInit(void *NotUsed){
}else{
/* only 1 core, use our own zone to contention over global locks,
** e.g. we have our own dedicated locks */
- _sqliteZone_ = malloc_create_zone(4096, 0);
- malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap");
+ _sqliteZone_ = malloc_create_zone(4096, 0);
+ malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap");
}
-#endif /* defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */
+#endif /* defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */
UNUSED_PARAMETER(NotUsed);
return SQLITE_OK;
}
@@ -25816,7 +25816,7 @@ static void memsys3FreeUnsafe(void *pOld){
*/
static int memsys3Size(void *p){
Mem3Block *pBlock;
- assert( p!=0 );
+ assert( p!=0 );
pBlock = (Mem3Block*)p;
assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
@@ -26055,7 +26055,7 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){
**
** This memory allocator uses the following algorithm:
**
-** 1. All memory allocation sizes are rounded up to a power of 2.
+** 1. All memory allocation sizes are rounded up to a power of 2.
**
** 2. If two adjacent free blocks are the halves of a larger block,
** then the two blocks are coalesced into the single larger block.
@@ -26132,7 +26132,7 @@ static SQLITE_WSD struct Mem5Global {
*/
sqlite3_mutex *mutex;
-#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Performance statistics
*/
@@ -26144,12 +26144,12 @@ static SQLITE_WSD struct Mem5Global {
u32 maxOut; /* Maximum instantaneous currentOut */
u32 maxCount; /* Maximum instantaneous currentCount */
u32 maxRequest; /* Largest allocation (exclusive of internal frag) */
-#endif
+#endif
/*
** Lists of free blocks. aiFreelist[0] is a list of free blocks of
** size mem5.szAtom. aiFreelist[1] holds blocks of size szAtom*2.
- ** aiFreelist[2] holds free blocks of size szAtom*4. And so forth.
+ ** aiFreelist[2] holds free blocks of size szAtom*4. And so forth.
*/
int aiFreelist[LOGMAX+1];
@@ -26215,7 +26215,7 @@ static void memsys5Link(int i, int iLogsize){
}
/*
-** Obtain or release the mutex needed to access global data structures.
+** Obtain or release the mutex needed to access global data structures.
*/
static void memsys5Enter(void){
sqlite3_mutex_enter(mem5.mutex);
@@ -26225,15 +26225,15 @@ static void memsys5Leave(void){
}
/*
-** Return the size of an outstanding allocation, in bytes.
-** This only works for chunks that are currently checked out.
+** Return the size of an outstanding allocation, in bytes.
+** This only works for chunks that are currently checked out.
*/
static int memsys5Size(void *p){
- int iSize, i;
- assert( p!=0 );
- i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom);
- assert( i>=0 && i<mem5.nBlock );
- iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
+ int iSize, i;
+ assert( p!=0 );
+ i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom);
+ assert( i>=0 && i<mem5.nBlock );
+ iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
return iSize;
}
@@ -26256,20 +26256,20 @@ static void *memsys5MallocUnsafe(int nByte){
/* nByte must be a positive */
assert( nByte>0 );
- /* No more than 1GiB per allocation */
- if( nByte > 0x40000000 ) return 0;
-
-#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+ /* No more than 1GiB per allocation */
+ if( nByte > 0x40000000 ) return 0;
+
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/* Keep track of the maximum allocation request. Even unfulfilled
** requests are counted */
if( (u32)nByte>mem5.maxRequest ){
mem5.maxRequest = nByte;
}
-#endif
+#endif
/* Round nByte up to the next valid power of two */
- for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte; iFullSz*=2,iLogsize++){}
+ for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte; iFullSz*=2,iLogsize++){}
/* Make sure mem5.aiFreelist[iLogsize] contains at least one free
** block. If not, then split a block of the next larger power of
@@ -26293,7 +26293,7 @@ static void *memsys5MallocUnsafe(int nByte){
}
mem5.aCtrl[i] = iLogsize;
-#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/* Update allocator performance statistics. */
mem5.nAlloc++;
mem5.totalAlloc += iFullSz;
@@ -26302,7 +26302,7 @@ static void *memsys5MallocUnsafe(int nByte){
mem5.currentOut += iFullSz;
if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
-#endif
+#endif
#ifdef SQLITE_DEBUG
/* Make sure the allocated memory does not assume that it is set to zero
@@ -26337,25 +26337,25 @@ static void memsys5FreeUnsafe(void *pOld){
mem5.aCtrl[iBlock] |= CTRL_FREE;
mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
-
-#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
assert( mem5.currentCount>0 );
assert( mem5.currentOut>=(size*mem5.szAtom) );
mem5.currentCount--;
mem5.currentOut -= size*mem5.szAtom;
assert( mem5.currentOut>0 || mem5.currentCount==0 );
assert( mem5.currentCount>0 || mem5.currentOut==0 );
-#endif
+#endif
mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
while( ALWAYS(iLogsize<LOGMAX) ){
int iBuddy;
if( (iBlock>>iLogsize) & 1 ){
iBuddy = iBlock - size;
- assert( iBuddy>=0 );
+ assert( iBuddy>=0 );
}else{
iBuddy = iBlock + size;
- if( iBuddy>=mem5.nBlock ) break;
+ if( iBuddy>=mem5.nBlock ) break;
}
if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
memsys5Unlink(iBuddy, iLogsize);
@@ -26431,10 +26431,10 @@ static void *memsys5Realloc(void *pPrior, int nBytes){
if( nBytes<=nOld ){
return pPrior;
}
- p = memsys5Malloc(nBytes);
+ p = memsys5Malloc(nBytes);
if( p ){
memcpy(p, pPrior, nOld);
- memsys5Free(pPrior);
+ memsys5Free(pPrior);
}
return p;
}
@@ -26631,198 +26631,198 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){
** allocate a mutex while the system is uninitialized.
*/
static SQLITE_WSD int mutexIsInit = 0;
-#endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */
+#endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */
#ifndef SQLITE_MUTEX_OMIT
-
-#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
+
+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
/*
-** This block (enclosed by SQLITE_ENABLE_MULTITHREADED_CHECKS) contains
-** the implementation of a wrapper around the system default mutex
+** This block (enclosed by SQLITE_ENABLE_MULTITHREADED_CHECKS) contains
+** the implementation of a wrapper around the system default mutex
** implementation (sqlite3DefaultMutex()).
-**
-** Most calls are passed directly through to the underlying default
-** mutex implementation. Except, if a mutex is configured by calling
-** sqlite3MutexWarnOnContention() on it, then if contention is ever
-** encountered within xMutexEnter() a warning is emitted via sqlite3_log().
-**
-** This type of mutex is used as the database handle mutex when testing
-** apps that usually use SQLITE_CONFIG_MULTITHREAD mode.
-*/
-
-/*
-** Type for all mutexes used when SQLITE_ENABLE_MULTITHREADED_CHECKS
-** is defined. Variable CheckMutex.mutex is a pointer to the real mutex
-** allocated by the system mutex implementation. Variable iType is usually set
-** to the type of mutex requested - SQLITE_MUTEX_RECURSIVE, SQLITE_MUTEX_FAST
-** or one of the static mutex identifiers. Or, if this is a recursive mutex
-** that has been configured using sqlite3MutexWarnOnContention(), it is
-** set to SQLITE_MUTEX_WARNONCONTENTION.
-*/
-typedef struct CheckMutex CheckMutex;
-struct CheckMutex {
- int iType;
- sqlite3_mutex *mutex;
-};
-
-#define SQLITE_MUTEX_WARNONCONTENTION (-1)
-
-/*
-** Pointer to real mutex methods object used by the CheckMutex
+**
+** Most calls are passed directly through to the underlying default
+** mutex implementation. Except, if a mutex is configured by calling
+** sqlite3MutexWarnOnContention() on it, then if contention is ever
+** encountered within xMutexEnter() a warning is emitted via sqlite3_log().
+**
+** This type of mutex is used as the database handle mutex when testing
+** apps that usually use SQLITE_CONFIG_MULTITHREAD mode.
+*/
+
+/*
+** Type for all mutexes used when SQLITE_ENABLE_MULTITHREADED_CHECKS
+** is defined. Variable CheckMutex.mutex is a pointer to the real mutex
+** allocated by the system mutex implementation. Variable iType is usually set
+** to the type of mutex requested - SQLITE_MUTEX_RECURSIVE, SQLITE_MUTEX_FAST
+** or one of the static mutex identifiers. Or, if this is a recursive mutex
+** that has been configured using sqlite3MutexWarnOnContention(), it is
+** set to SQLITE_MUTEX_WARNONCONTENTION.
+*/
+typedef struct CheckMutex CheckMutex;
+struct CheckMutex {
+ int iType;
+ sqlite3_mutex *mutex;
+};
+
+#define SQLITE_MUTEX_WARNONCONTENTION (-1)
+
+/*
+** Pointer to real mutex methods object used by the CheckMutex
** implementation. Set by checkMutexInit().
-*/
-static SQLITE_WSD const sqlite3_mutex_methods *pGlobalMutexMethods;
-
-#ifdef SQLITE_DEBUG
-static int checkMutexHeld(sqlite3_mutex *p){
- return pGlobalMutexMethods->xMutexHeld(((CheckMutex*)p)->mutex);
-}
-static int checkMutexNotheld(sqlite3_mutex *p){
- return pGlobalMutexMethods->xMutexNotheld(((CheckMutex*)p)->mutex);
-}
-#endif
-
-/*
-** Initialize and deinitialize the mutex subsystem.
-*/
+*/
+static SQLITE_WSD const sqlite3_mutex_methods *pGlobalMutexMethods;
+
+#ifdef SQLITE_DEBUG
+static int checkMutexHeld(sqlite3_mutex *p){
+ return pGlobalMutexMethods->xMutexHeld(((CheckMutex*)p)->mutex);
+}
+static int checkMutexNotheld(sqlite3_mutex *p){
+ return pGlobalMutexMethods->xMutexNotheld(((CheckMutex*)p)->mutex);
+}
+#endif
+
+/*
+** Initialize and deinitialize the mutex subsystem.
+*/
static int checkMutexInit(void){
- pGlobalMutexMethods = sqlite3DefaultMutex();
+ pGlobalMutexMethods = sqlite3DefaultMutex();
return SQLITE_OK;
-}
+}
static int checkMutexEnd(void){
- pGlobalMutexMethods = 0;
+ pGlobalMutexMethods = 0;
return SQLITE_OK;
-}
-
-/*
-** Allocate a mutex.
-*/
-static sqlite3_mutex *checkMutexAlloc(int iType){
- static CheckMutex staticMutexes[] = {
- {2, 0}, {3, 0}, {4, 0}, {5, 0},
- {6, 0}, {7, 0}, {8, 0}, {9, 0},
- {10, 0}, {11, 0}, {12, 0}, {13, 0}
- };
- CheckMutex *p = 0;
-
- assert( SQLITE_MUTEX_RECURSIVE==1 && SQLITE_MUTEX_FAST==0 );
- if( iType<2 ){
- p = sqlite3MallocZero(sizeof(CheckMutex));
- if( p==0 ) return 0;
- p->iType = iType;
- }else{
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( iType-2>=ArraySize(staticMutexes) ){
- (void)SQLITE_MISUSE_BKPT;
- return 0;
- }
-#endif
- p = &staticMutexes[iType-2];
- }
-
- if( p->mutex==0 ){
- p->mutex = pGlobalMutexMethods->xMutexAlloc(iType);
- if( p->mutex==0 ){
- if( iType<2 ){
- sqlite3_free(p);
- }
- p = 0;
- }
- }
-
- return (sqlite3_mutex*)p;
-}
-
-/*
-** Free a mutex.
-*/
-static void checkMutexFree(sqlite3_mutex *p){
- assert( SQLITE_MUTEX_RECURSIVE<2 );
- assert( SQLITE_MUTEX_FAST<2 );
- assert( SQLITE_MUTEX_WARNONCONTENTION<2 );
-
-#if SQLITE_ENABLE_API_ARMOR
- if( ((CheckMutex*)p)->iType<2 )
-#endif
- {
- CheckMutex *pCheck = (CheckMutex*)p;
- pGlobalMutexMethods->xMutexFree(pCheck->mutex);
- sqlite3_free(pCheck);
- }
-#ifdef SQLITE_ENABLE_API_ARMOR
- else{
- (void)SQLITE_MISUSE_BKPT;
- }
-#endif
-}
-
-/*
-** Enter the mutex.
-*/
-static void checkMutexEnter(sqlite3_mutex *p){
- CheckMutex *pCheck = (CheckMutex*)p;
- if( pCheck->iType==SQLITE_MUTEX_WARNONCONTENTION ){
- if( SQLITE_OK==pGlobalMutexMethods->xMutexTry(pCheck->mutex) ){
- return;
- }
+}
+
+/*
+** Allocate a mutex.
+*/
+static sqlite3_mutex *checkMutexAlloc(int iType){
+ static CheckMutex staticMutexes[] = {
+ {2, 0}, {3, 0}, {4, 0}, {5, 0},
+ {6, 0}, {7, 0}, {8, 0}, {9, 0},
+ {10, 0}, {11, 0}, {12, 0}, {13, 0}
+ };
+ CheckMutex *p = 0;
+
+ assert( SQLITE_MUTEX_RECURSIVE==1 && SQLITE_MUTEX_FAST==0 );
+ if( iType<2 ){
+ p = sqlite3MallocZero(sizeof(CheckMutex));
+ if( p==0 ) return 0;
+ p->iType = iType;
+ }else{
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( iType-2>=ArraySize(staticMutexes) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+ p = &staticMutexes[iType-2];
+ }
+
+ if( p->mutex==0 ){
+ p->mutex = pGlobalMutexMethods->xMutexAlloc(iType);
+ if( p->mutex==0 ){
+ if( iType<2 ){
+ sqlite3_free(p);
+ }
+ p = 0;
+ }
+ }
+
+ return (sqlite3_mutex*)p;
+}
+
+/*
+** Free a mutex.
+*/
+static void checkMutexFree(sqlite3_mutex *p){
+ assert( SQLITE_MUTEX_RECURSIVE<2 );
+ assert( SQLITE_MUTEX_FAST<2 );
+ assert( SQLITE_MUTEX_WARNONCONTENTION<2 );
+
+#if SQLITE_ENABLE_API_ARMOR
+ if( ((CheckMutex*)p)->iType<2 )
+#endif
+ {
+ CheckMutex *pCheck = (CheckMutex*)p;
+ pGlobalMutexMethods->xMutexFree(pCheck->mutex);
+ sqlite3_free(pCheck);
+ }
+#ifdef SQLITE_ENABLE_API_ARMOR
+ else{
+ (void)SQLITE_MISUSE_BKPT;
+ }
+#endif
+}
+
+/*
+** Enter the mutex.
+*/
+static void checkMutexEnter(sqlite3_mutex *p){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ if( pCheck->iType==SQLITE_MUTEX_WARNONCONTENTION ){
+ if( SQLITE_OK==pGlobalMutexMethods->xMutexTry(pCheck->mutex) ){
+ return;
+ }
sqlite3_log(SQLITE_MISUSE,
- "illegal multi-threaded access to database connection"
- );
- }
- pGlobalMutexMethods->xMutexEnter(pCheck->mutex);
-}
-
-/*
-** Enter the mutex (do not block).
-*/
-static int checkMutexTry(sqlite3_mutex *p){
- CheckMutex *pCheck = (CheckMutex*)p;
- return pGlobalMutexMethods->xMutexTry(pCheck->mutex);
-}
-
-/*
-** Leave the mutex.
-*/
-static void checkMutexLeave(sqlite3_mutex *p){
- CheckMutex *pCheck = (CheckMutex*)p;
- pGlobalMutexMethods->xMutexLeave(pCheck->mutex);
-}
-
-sqlite3_mutex_methods const *multiThreadedCheckMutex(void){
- static const sqlite3_mutex_methods sMutex = {
- checkMutexInit,
- checkMutexEnd,
- checkMutexAlloc,
- checkMutexFree,
- checkMutexEnter,
- checkMutexTry,
- checkMutexLeave,
-#ifdef SQLITE_DEBUG
- checkMutexHeld,
- checkMutexNotheld
-#else
- 0,
- 0
-#endif
- };
- return &sMutex;
-}
-
-/*
-** Mark the SQLITE_MUTEX_RECURSIVE mutex passed as the only argument as
-** one on which there should be no contention.
-*/
-SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex *p){
- if( sqlite3GlobalConfig.mutex.xMutexAlloc==checkMutexAlloc ){
- CheckMutex *pCheck = (CheckMutex*)p;
- assert( pCheck->iType==SQLITE_MUTEX_RECURSIVE );
- pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION;
- }
-}
-#endif /* ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS */
-
-/*
+ "illegal multi-threaded access to database connection"
+ );
+ }
+ pGlobalMutexMethods->xMutexEnter(pCheck->mutex);
+}
+
+/*
+** Enter the mutex (do not block).
+*/
+static int checkMutexTry(sqlite3_mutex *p){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ return pGlobalMutexMethods->xMutexTry(pCheck->mutex);
+}
+
+/*
+** Leave the mutex.
+*/
+static void checkMutexLeave(sqlite3_mutex *p){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ pGlobalMutexMethods->xMutexLeave(pCheck->mutex);
+}
+
+sqlite3_mutex_methods const *multiThreadedCheckMutex(void){
+ static const sqlite3_mutex_methods sMutex = {
+ checkMutexInit,
+ checkMutexEnd,
+ checkMutexAlloc,
+ checkMutexFree,
+ checkMutexEnter,
+ checkMutexTry,
+ checkMutexLeave,
+#ifdef SQLITE_DEBUG
+ checkMutexHeld,
+ checkMutexNotheld
+#else
+ 0,
+ 0
+#endif
+ };
+ return &sMutex;
+}
+
+/*
+** Mark the SQLITE_MUTEX_RECURSIVE mutex passed as the only argument as
+** one on which there should be no contention.
+*/
+SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex *p){
+ if( sqlite3GlobalConfig.mutex.xMutexAlloc==checkMutexAlloc ){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ assert( pCheck->iType==SQLITE_MUTEX_RECURSIVE );
+ pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION;
+ }
+}
+#endif /* ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS */
+
+/*
** Initialize the mutex system.
*/
SQLITE_PRIVATE int sqlite3MutexInit(void){
@@ -26837,11 +26837,11 @@ SQLITE_PRIVATE int sqlite3MutexInit(void){
sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
if( sqlite3GlobalConfig.bCoreMutex ){
-#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
- pFrom = multiThreadedCheckMutex();
-#else
+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
+ pFrom = multiThreadedCheckMutex();
+#else
pFrom = sqlite3DefaultMutex();
-#endif
+#endif
}else{
pFrom = sqlite3NoopMutex();
}
@@ -26853,10 +26853,10 @@ SQLITE_PRIVATE int sqlite3MutexInit(void){
pTo->xMutexLeave = pFrom->xMutexLeave;
pTo->xMutexHeld = pFrom->xMutexHeld;
pTo->xMutexNotheld = pFrom->xMutexNotheld;
- sqlite3MemoryBarrier();
+ sqlite3MemoryBarrier();
pTo->xMutexAlloc = pFrom->xMutexAlloc;
}
- assert( sqlite3GlobalConfig.mutex.xMutexInit );
+ assert( sqlite3GlobalConfig.mutex.xMutexInit );
rc = sqlite3GlobalConfig.mutex.xMutexInit();
#ifdef SQLITE_DEBUG
@@ -26887,12 +26887,12 @@ SQLITE_PRIVATE int sqlite3MutexEnd(void){
/*
** Retrieve a pointer to a static mutex or allocate a new dynamic one.
*/
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
+SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
#ifndef SQLITE_OMIT_AUTOINIT
if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
#endif
- assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
+ assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}
@@ -26901,16 +26901,16 @@ SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
return 0;
}
assert( GLOBAL(int, mutexIsInit) );
- assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
+ assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}
/*
** Free a dynamic mutex.
*/
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
+SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
if( p ){
- assert( sqlite3GlobalConfig.mutex.xMutexFree );
+ assert( sqlite3GlobalConfig.mutex.xMutexFree );
sqlite3GlobalConfig.mutex.xMutexFree(p);
}
}
@@ -26919,9 +26919,9 @@ SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
** Obtain the mutex p. If some other thread already has the mutex, block
** until it can be obtained.
*/
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
if( p ){
- assert( sqlite3GlobalConfig.mutex.xMutexEnter );
+ assert( sqlite3GlobalConfig.mutex.xMutexEnter );
sqlite3GlobalConfig.mutex.xMutexEnter(p);
}
}
@@ -26930,10 +26930,10 @@ SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
*/
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
int rc = SQLITE_OK;
if( p ){
- assert( sqlite3GlobalConfig.mutex.xMutexTry );
+ assert( sqlite3GlobalConfig.mutex.xMutexTry );
return sqlite3GlobalConfig.mutex.xMutexTry(p);
}
return rc;
@@ -26945,9 +26945,9 @@ SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
** is not currently entered. If a NULL pointer is passed as an argument
** this function is a no-op.
*/
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
if( p ){
- assert( sqlite3GlobalConfig.mutex.xMutexLeave );
+ assert( sqlite3GlobalConfig.mutex.xMutexLeave );
sqlite3GlobalConfig.mutex.xMutexLeave(p);
}
}
@@ -26957,12 +26957,12 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use inside assert() statements.
*/
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
- assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
+ assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
}
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
- assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
+ assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
}
#endif
@@ -27244,7 +27244,7 @@ struct sqlite3_mutex {
#if SQLITE_MUTEX_NREF
# define SQLITE3_MUTEX_INITIALIZER(id) \
{PTHREAD_MUTEX_INITIALIZER,id,0,(pthread_t)0,0}
-#elif defined(SQLITE_ENABLE_API_ARMOR)
+#elif defined(SQLITE_ENABLE_API_ARMOR)
# define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER, id }
#else
#define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER }
@@ -27276,19 +27276,19 @@ static int pthreadMutexNotheld(sqlite3_mutex *p){
#endif
/*
-** Try to provide a memory barrier operation, needed for initialization
-** and also for the implementation of xShmBarrier in the VFS in cases
-** where SQLite is compiled without mutexes.
-*/
-SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
-#if defined(SQLITE_MEMORY_BARRIER)
- SQLITE_MEMORY_BARRIER;
-#elif defined(__GNUC__) && GCC_VERSION>=4001000
- __sync_synchronize();
-#endif
-}
-
-/*
+** Try to provide a memory barrier operation, needed for initialization
+** and also for the implementation of xShmBarrier in the VFS in cases
+** where SQLite is compiled without mutexes.
+*/
+SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
+#if defined(SQLITE_MEMORY_BARRIER)
+ SQLITE_MEMORY_BARRIER;
+#elif defined(__GNUC__) && GCC_VERSION>=4001000
+ __sync_synchronize();
+#endif
+}
+
+/*
** Initialize and deinitialize the mutex subsystem.
*/
static int pthreadMutexInit(void){ return SQLITE_OK; }
@@ -27627,8 +27627,8 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
**
** This file contains code that is specific to Windows.
*/
-#ifndef SQLITE_OS_WIN_H
-#define SQLITE_OS_WIN_H
+#ifndef SQLITE_OS_WIN_H
+#define SQLITE_OS_WIN_H
/*
** Include the primary Windows SDK header file.
@@ -27700,7 +27700,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
# define SQLITE_OS_WIN_THREADS 0
#endif
-#endif /* SQLITE_OS_WIN_H */
+#endif /* SQLITE_OS_WIN_H */
/************** End of os_win.h **********************************************/
/************** Continuing where we left off in mutex_w32.c ******************/
@@ -27759,23 +27759,23 @@ static int winMutexNotheld(sqlite3_mutex *p){
#endif
/*
-** Try to provide a memory barrier operation, needed for initialization
-** and also for the xShmBarrier method of the VFS in cases when SQLite is
-** compiled without mutexes (SQLITE_THREADSAFE=0).
-*/
-SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
-#if defined(SQLITE_MEMORY_BARRIER)
- SQLITE_MEMORY_BARRIER;
-#elif defined(__GNUC__)
- __sync_synchronize();
-#elif MSVC_VERSION>=1300
- _ReadWriteBarrier();
-#elif defined(MemoryBarrier)
- MemoryBarrier();
-#endif
-}
-
-/*
+** Try to provide a memory barrier operation, needed for initialization
+** and also for the xShmBarrier method of the VFS in cases when SQLite is
+** compiled without mutexes (SQLITE_THREADSAFE=0).
+*/
+SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
+#if defined(SQLITE_MEMORY_BARRIER)
+ SQLITE_MEMORY_BARRIER;
+#elif defined(__GNUC__)
+ __sync_synchronize();
+#elif MSVC_VERSION>=1300
+ _ReadWriteBarrier();
+#elif defined(MemoryBarrier)
+ MemoryBarrier();
+#endif
+}
+
+/*
** Initialize and deinitialize the mutex subsystem.
*/
static sqlite3_mutex winMutex_staticMutexes[] = {
@@ -27802,8 +27802,8 @@ static int winMutex_isNt = -1; /* <0 means "need to query" */
*/
static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0;
-SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */
-SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
+SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */
+SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */
@@ -27979,8 +27979,8 @@ static void winMutexEnter(sqlite3_mutex *p){
p->owner = tid;
p->nRef++;
if( p->trace ){
- OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
- tid, p->id, p, p->trace, p->nRef));
+ OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
+ tid, p->id, p, p->trace, p->nRef));
}
#endif
}
@@ -28022,8 +28022,8 @@ static int winMutexTry(sqlite3_mutex *p){
#endif
#ifdef SQLITE_DEBUG
if( p->trace ){
- OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
- tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
+ OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
+ tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
}
#endif
return rc;
@@ -28051,8 +28051,8 @@ static void winMutexLeave(sqlite3_mutex *p){
LeaveCriticalSection(&p->mutex);
#ifdef SQLITE_DEBUG
if( p->trace ){
- OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
- tid, p->id, p, p->trace, p->nRef));
+ OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
+ tid, p->id, p, p->trace, p->nRef));
}
#endif
}
@@ -28103,7 +28103,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
** held by SQLite. An example of non-essential memory is memory used to
** cache database pages that are not currently in use.
*/
-SQLITE_API int sqlite3_release_memory(int n){
+SQLITE_API int sqlite3_release_memory(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
return sqlite3PcacheReleaseMemory(n);
#else
@@ -28127,7 +28127,7 @@ SQLITE_API int sqlite3_release_memory(int n){
*/
static SQLITE_WSD struct Mem0Global {
sqlite3_mutex *mutex; /* Mutex to serialize access */
- sqlite3_int64 alarmThreshold; /* The soft heap limit */
+ sqlite3_int64 alarmThreshold; /* The soft heap limit */
sqlite3_int64 hardLimit; /* The hard upper bound on memory */
/*
@@ -28146,20 +28146,20 @@ SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){
return mem0.mutex;
}
-#ifndef SQLITE_OMIT_DEPRECATED
+#ifndef SQLITE_OMIT_DEPRECATED
/*
-** Deprecated external interface. It used to set an alarm callback
-** that was invoked when memory usage grew too large. Now it is a
-** no-op.
+** Deprecated external interface. It used to set an alarm callback
+** that was invoked when memory usage grew too large. Now it is a
+** no-op.
*/
-SQLITE_API int sqlite3_memory_alarm(
+SQLITE_API int sqlite3_memory_alarm(
void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
void *pArg,
sqlite3_int64 iThreshold
){
- (void)xCallback;
- (void)pArg;
- (void)iThreshold;
+ (void)xCallback;
+ (void)pArg;
+ (void)iThreshold;
return SQLITE_OK;
}
#endif
@@ -28175,32 +28175,32 @@ SQLITE_API int sqlite3_memory_alarm(
** If the hard heap limit is enabled, then the soft heap limit cannot
** be disabled nor raised above the hard heap limit.
*/
-SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
+SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_int64 priorLimit;
sqlite3_int64 excess;
- sqlite3_int64 nUsed;
+ sqlite3_int64 nUsed;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
if( rc ) return -1;
#endif
sqlite3_mutex_enter(mem0.mutex);
priorLimit = mem0.alarmThreshold;
- if( n<0 ){
- sqlite3_mutex_leave(mem0.mutex);
- return priorLimit;
- }
+ if( n<0 ){
+ sqlite3_mutex_leave(mem0.mutex);
+ return priorLimit;
+ }
if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){
n = mem0.hardLimit;
}
- mem0.alarmThreshold = n;
- nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
+ mem0.alarmThreshold = n;
+ nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
AtomicStore(&mem0.nearlyFull, n>0 && n<=nUsed);
sqlite3_mutex_leave(mem0.mutex);
excess = sqlite3_memory_used() - n;
if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
return priorLimit;
}
-SQLITE_API void sqlite3_soft_heap_limit(int n){
+SQLITE_API void sqlite3_soft_heap_limit(int n){
if( n<0 ) n = 0;
sqlite3_soft_heap_limit64(n);
}
@@ -28244,7 +28244,7 @@ SQLITE_PRIVATE int sqlite3MallocInit(void){
if( sqlite3GlobalConfig.m.xMalloc==0 ){
sqlite3MemSetDefault();
}
- mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
+ mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
|| sqlite3GlobalConfig.nPage<=0 ){
sqlite3GlobalConfig.pPage = 0;
@@ -28277,7 +28277,7 @@ SQLITE_PRIVATE void sqlite3MallocEnd(void){
/*
** Return the amount of memory currently checked out.
*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
+SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
sqlite3_int64 res, mx;
sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0);
return res;
@@ -28288,7 +28288,7 @@ SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
** checked out since either the beginning of this process
** or since the most recent reset.
*/
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
+SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
sqlite3_int64 res, mx;
sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag);
return mx;
@@ -28298,9 +28298,9 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
** Trigger the alarm
*/
static void sqlite3MallocAlarm(int nByte){
- if( mem0.alarmThreshold<=0 ) return;
+ if( mem0.alarmThreshold<=0 ) return;
sqlite3_mutex_leave(mem0.mutex);
- sqlite3_release_memory(nByte);
+ sqlite3_release_memory(nByte);
sqlite3_mutex_enter(mem0.mutex);
}
@@ -28308,21 +28308,21 @@ static void sqlite3MallocAlarm(int nByte){
** Do a memory allocation with statistics and alarms. Assume the
** lock is already held.
*/
-static void mallocWithAlarm(int n, void **pp){
- void *p;
+static void mallocWithAlarm(int n, void **pp){
+ void *p;
int nFull;
assert( sqlite3_mutex_held(mem0.mutex) );
- assert( n>0 );
-
- /* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal
- ** implementation of malloc_good_size(), which must be called in debug
- ** mode and specifically when the DMD "Dark Matter Detector" is enabled
- ** or else a crash results. Hence, do not attempt to optimize out the
- ** following xRoundup() call. */
+ assert( n>0 );
+
+ /* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal
+ ** implementation of malloc_good_size(), which must be called in debug
+ ** mode and specifically when the DMD "Dark Matter Detector" is enabled
+ ** or else a crash results. Hence, do not attempt to optimize out the
+ ** following xRoundup() call. */
nFull = sqlite3GlobalConfig.m.xRoundup(n);
-
- sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
- if( mem0.alarmThreshold>0 ){
+
+ sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
+ if( mem0.alarmThreshold>0 ){
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.alarmThreshold - nFull ){
AtomicStore(&mem0.nearlyFull, 1);
@@ -28340,7 +28340,7 @@ static void mallocWithAlarm(int n, void **pp){
}
p = sqlite3GlobalConfig.m.xMalloc(nFull);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- if( p==0 && mem0.alarmThreshold>0 ){
+ if( p==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm(nFull);
p = sqlite3GlobalConfig.m.xMalloc(nFull);
}
@@ -28382,13 +28382,13 @@ SQLITE_PRIVATE void *sqlite3Malloc(u64 n){
** First make sure the memory subsystem is initialized, then do the
** allocation.
*/
-SQLITE_API void *sqlite3_malloc(int n){
+SQLITE_API void *sqlite3_malloc(int n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return n<=0 ? 0 : sqlite3Malloc(n);
}
-SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){
+SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
@@ -28400,7 +28400,7 @@ SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){
*/
#ifndef SQLITE_OMIT_LOOKASIDE
static int isLookaside(sqlite3 *db, const void *p){
- return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd);
+ return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd);
}
#else
#define isLookaside(A,B) 0
@@ -28422,18 +28422,18 @@ static int lookasideMallocSize(sqlite3 *db, const void *p){
#endif
}
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, const void *p){
- assert( p!=0 );
+ assert( p!=0 );
#ifdef SQLITE_DEBUG
- if( db==0 || !isLookaside(db,p) ){
- if( db==0 ){
- assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
- assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
+ if( db==0 || !isLookaside(db,p) ){
+ if( db==0 ){
+ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
}
}
-#endif
+#endif
if( db ){
if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
@@ -28450,16 +28450,16 @@ SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, const void *p){
}
return sqlite3GlobalConfig.m.xSize((void*)p);
}
-SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
+SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
- return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
+ return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
}
/*
** Free memory previously obtained from sqlite3Malloc().
*/
-SQLITE_API void sqlite3_free(void *p){
+SQLITE_API void sqlite3_free(void *p){
if( p==0 ) return; /* IMP: R-49053-54554 */
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
@@ -28484,12 +28484,12 @@ static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){
/*
** Free memory that might be associated with a particular database
-** connection. Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op.
-** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL.
+** connection. Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op.
+** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL.
*/
-SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){
+SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){
assert( db==0 || sqlite3_mutex_held(db->mutex) );
- assert( p!=0 );
+ assert( p!=0 );
if( db ){
if( db->pnBytesFreed ){
measureAllocationSize(db, p);
@@ -28499,7 +28499,7 @@ SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){
LookasideSlot *pBuf = (LookasideSlot*)p;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */
#endif
pBuf->pNext = db->lookaside.pSmallFree;
@@ -28524,10 +28524,10 @@ SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
sqlite3_free(p);
}
-SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
- assert( db==0 || sqlite3_mutex_held(db->mutex) );
- if( p ) sqlite3DbFreeNN(db, p);
-}
+SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
+ assert( db==0 || sqlite3_mutex_held(db->mutex) );
+ if( p ) sqlite3DbFreeNN(db, p);
+}
/*
** Change the size of an existing memory allocation
@@ -28558,7 +28558,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
}else if( sqlite3GlobalConfig.bMemstat ){
sqlite3_int64 nUsed;
sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
+ sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
nDiff = nNew - nOld;
if( nDiff>0 && (nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)) >=
mem0.alarmThreshold-nDiff ){
@@ -28570,7 +28570,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
}
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- if( pNew==0 && mem0.alarmThreshold>0 ){
+ if( pNew==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm((int)nBytes);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
}
@@ -28591,14 +28591,14 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
** The public interface to sqlite3Realloc. Make sure that the memory
** subsystem is initialized prior to invoking sqliteRealloc.
*/
-SQLITE_API void *sqlite3_realloc(void *pOld, int n){
+SQLITE_API void *sqlite3_realloc(void *pOld, int n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
if( n<0 ) n = 0; /* IMP: R-26507-47431 */
return sqlite3Realloc(pOld, n);
}
-SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
+SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
@@ -28622,31 +28622,31 @@ SQLITE_PRIVATE void *sqlite3MallocZero(u64 n){
** the mallocFailed flag in the connection pointer.
*/
SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, u64 n){
- void *p;
- testcase( db==0 );
- p = sqlite3DbMallocRaw(db, n);
- if( p ) memset(p, 0, (size_t)n);
+ void *p;
+ testcase( db==0 );
+ p = sqlite3DbMallocRaw(db, n);
+ if( p ) memset(p, 0, (size_t)n);
return p;
}
-
-/* Finish the work of sqlite3DbMallocRawNN for the unusual and
-** slower case when the allocation cannot be fulfilled using lookaside.
-*/
-static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){
- void *p;
- assert( db!=0 );
- p = sqlite3Malloc(n);
- if( !p ) sqlite3OomFault(db);
+
+/* Finish the work of sqlite3DbMallocRawNN for the unusual and
+** slower case when the allocation cannot be fulfilled using lookaside.
+*/
+static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){
+ void *p;
+ assert( db!=0 );
+ p = sqlite3Malloc(n);
+ if( !p ) sqlite3OomFault(db);
sqlite3MemdebugSetType(p,
- (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
- return p;
-}
-
+ (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
+ return p;
+}
+
/*
** Allocate memory, either lookaside (if possible) or heap.
-** If the allocation fails, set the mallocFailed flag in
-** the connection pointer.
+** If the allocation fails, set the mallocFailed flag in
+** the connection pointer.
**
** If db!=0 and db->mallocFailed is true (indicating a prior malloc
** failure on the same database connection) then always return 0.
@@ -28661,26 +28661,26 @@ static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){
**
** In other words, if a subsequent malloc (ex: "b") worked, it is assumed
** that all prior mallocs (ex: "a") worked too.
-**
-** The sqlite3MallocRawNN() variant guarantees that the "db" parameter is
-** not a NULL pointer.
+**
+** The sqlite3MallocRawNN() variant guarantees that the "db" parameter is
+** not a NULL pointer.
*/
SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){
void *p;
- if( db ) return sqlite3DbMallocRawNN(db, n);
- p = sqlite3Malloc(n);
- sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
- return p;
-}
-SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){
+ if( db ) return sqlite3DbMallocRawNN(db, n);
+ p = sqlite3Malloc(n);
+ sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
+ return p;
+}
+SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){
#ifndef SQLITE_OMIT_LOOKASIDE
- LookasideSlot *pBuf;
- assert( db!=0 );
- assert( sqlite3_mutex_held(db->mutex) );
- assert( db->pnBytesFreed==0 );
+ LookasideSlot *pBuf;
+ assert( db!=0 );
+ assert( sqlite3_mutex_held(db->mutex) );
+ assert( db->pnBytesFreed==0 );
if( n>db->lookaside.sz ){
if( !db->lookaside.bDisable ){
- db->lookaside.anStat[1]++;
+ db->lookaside.anStat[1]++;
}else if( db->mallocFailed ){
return 0;
}
@@ -28690,12 +28690,12 @@ SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){
if( n<=LOOKASIDE_SMALL ){
if( (pBuf = db->lookaside.pSmallFree)!=0 ){
db->lookaside.pSmallFree = pBuf->pNext;
- db->lookaside.anStat[0]++;
- return (void*)pBuf;
+ db->lookaside.anStat[0]++;
+ return (void*)pBuf;
}else if( (pBuf = db->lookaside.pSmallInit)!=0 ){
db->lookaside.pSmallInit = pBuf->pNext;
- db->lookaside.anStat[0]++;
- return (void*)pBuf;
+ db->lookaside.anStat[0]++;
+ return (void*)pBuf;
}
}
#endif
@@ -28711,27 +28711,27 @@ SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){
db->lookaside.anStat[2]++;
}
#else
- assert( db!=0 );
- assert( sqlite3_mutex_held(db->mutex) );
- assert( db->pnBytesFreed==0 );
- if( db->mallocFailed ){
+ assert( db!=0 );
+ assert( sqlite3_mutex_held(db->mutex) );
+ assert( db->pnBytesFreed==0 );
+ if( db->mallocFailed ){
return 0;
}
#endif
- return dbMallocRawFinish(db, n);
+ return dbMallocRawFinish(db, n);
}
-/* Forward declaration */
-static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n);
-
+/* Forward declaration */
+static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n);
+
/*
** Resize the block of memory pointed to by p to n bytes. If the
** resize fails, set the mallocFailed flag in the connection object.
*/
SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
- assert( db!=0 );
- if( p==0 ) return sqlite3DbMallocRawNN(db, n);
- assert( sqlite3_mutex_held(db->mutex) );
+ assert( db!=0 );
+ if( p==0 ) return sqlite3DbMallocRawNN(db, n);
+ assert( sqlite3_mutex_held(db->mutex) );
if( ((uptr)p)<(uptr)db->lookaside.pEnd ){
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
if( ((uptr)p)>=(uptr)db->lookaside.pMiddle ){
@@ -28742,15 +28742,15 @@ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
if( n<=db->lookaside.szTrue ) return p;
}
}
- return dbReallocFinish(db, p, n);
-}
-static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){
+ return dbReallocFinish(db, p, n);
+}
+static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){
void *pNew = 0;
assert( db!=0 );
- assert( p!=0 );
+ assert( p!=0 );
if( db->mallocFailed==0 ){
if( isLookaside(db, p) ){
- pNew = sqlite3DbMallocRawNN(db, n);
+ pNew = sqlite3DbMallocRawNN(db, n);
if( pNew ){
memcpy(pNew, p, lookasideMallocSize(db, p));
sqlite3DbFree(db, p);
@@ -28761,10 +28761,10 @@ static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
pNew = sqlite3Realloc(p, n);
if( !pNew ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
}
sqlite3MemdebugSetType(pNew,
- (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
+ (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
}
}
return pNew;
@@ -28796,8 +28796,8 @@ SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){
if( z==0 ){
return 0;
}
- n = strlen(z) + 1;
- zNew = sqlite3DbMallocRaw(db, n);
+ n = strlen(z) + 1;
+ zNew = sqlite3DbMallocRaw(db, n);
if( zNew ){
memcpy(zNew, z, n);
}
@@ -28805,7 +28805,7 @@ SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){
}
SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){
char *zNew;
- assert( db!=0 );
+ assert( db!=0 );
assert( z!=0 || n==0 );
assert( (n&0x7fffffff)==n );
zNew = z ? sqlite3DbMallocRawNN(db, n+1) : 0;
@@ -28817,19 +28817,19 @@ SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){
}
/*
-** The text between zStart and zEnd represents a phrase within a larger
-** SQL statement. Make a copy of this phrase in space obtained form
-** sqlite3DbMalloc(). Omit leading and trailing whitespace.
-*/
-SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
- int n;
- while( sqlite3Isspace(zStart[0]) ) zStart++;
- n = (int)(zEnd - zStart);
- while( ALWAYS(n>0) && sqlite3Isspace(zStart[n-1]) ) n--;
- return sqlite3DbStrNDup(db, zStart, n);
-}
-
-/*
+** The text between zStart and zEnd represents a phrase within a larger
+** SQL statement. Make a copy of this phrase in space obtained form
+** sqlite3DbMalloc(). Omit leading and trailing whitespace.
+*/
+SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
+ int n;
+ while( sqlite3Isspace(zStart[0]) ) zStart++;
+ n = (int)(zEnd - zStart);
+ while( ALWAYS(n>0) && sqlite3Isspace(zStart[n-1]) ) n--;
+ return sqlite3DbStrNDup(db, zStart, n);
+}
+
+/*
** Free any prior content in *pz and replace it with a copy of zNew.
*/
SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
@@ -28838,41 +28838,41 @@ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
}
/*
-** Call this routine to record the fact that an OOM (out-of-memory) error
-** has happened. This routine will set db->mallocFailed, and also
-** temporarily disable the lookaside memory allocator and interrupt
-** any running VDBEs.
-*/
-SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){
- if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
- db->mallocFailed = 1;
- if( db->nVdbeExec>0 ){
+** Call this routine to record the fact that an OOM (out-of-memory) error
+** has happened. This routine will set db->mallocFailed, and also
+** temporarily disable the lookaside memory allocator and interrupt
+** any running VDBEs.
+*/
+SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){
+ if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
+ db->mallocFailed = 1;
+ if( db->nVdbeExec>0 ){
AtomicStore(&db->u1.isInterrupted, 1);
- }
+ }
DisableLookaside;
if( db->pParse ){
db->pParse->rc = SQLITE_NOMEM_BKPT;
}
- }
-}
-
-/*
-** This routine reactivates the memory allocator and clears the
-** db->mallocFailed flag as necessary.
-**
-** The memory allocator is not restarted if there are running
-** VDBEs.
-*/
-SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){
- if( db->mallocFailed && db->nVdbeExec==0 ){
- db->mallocFailed = 0;
+ }
+}
+
+/*
+** This routine reactivates the memory allocator and clears the
+** db->mallocFailed flag as necessary.
+**
+** The memory allocator is not restarted if there are running
+** VDBEs.
+*/
+SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){
+ if( db->mallocFailed && db->nVdbeExec==0 ){
+ db->mallocFailed = 0;
AtomicStore(&db->u1.isInterrupted, 0);
- assert( db->lookaside.bDisable>0 );
+ assert( db->lookaside.bDisable>0 );
EnableLookaside;
- }
-}
-
-/*
+ }
+}
+
+/*
** Take actions at the end of an API call to deal with error codes.
*/
static SQLITE_NOINLINE int apiHandleError(sqlite3 *db, int rc){
@@ -28928,27 +28928,27 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
** Conversion types fall into various categories as defined by the
** following enumeration.
*/
-#define etRADIX 0 /* non-decimal integer types. %x %o */
-#define etFLOAT 1 /* Floating point. %f */
-#define etEXP 2 /* Exponentional notation. %e and %E */
-#define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */
-#define etSIZE 4 /* Return number of characters processed so far. %n */
-#define etSTRING 5 /* Strings. %s */
-#define etDYNSTRING 6 /* Dynamically allocated strings. %z */
-#define etPERCENT 7 /* Percent symbol. %% */
-#define etCHARX 8 /* Characters. %c */
+#define etRADIX 0 /* non-decimal integer types. %x %o */
+#define etFLOAT 1 /* Floating point. %f */
+#define etEXP 2 /* Exponentional notation. %e and %E */
+#define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */
+#define etSIZE 4 /* Return number of characters processed so far. %n */
+#define etSTRING 5 /* Strings. %s */
+#define etDYNSTRING 6 /* Dynamically allocated strings. %z */
+#define etPERCENT 7 /* Percent symbol. %% */
+#define etCHARX 8 /* Characters. %c */
/* The rest are extensions, not normally found in printf() */
-#define etSQLESCAPE 9 /* Strings with '\'' doubled. %q */
-#define etSQLESCAPE2 10 /* Strings with '\'' doubled and enclosed in '',
+#define etSQLESCAPE 9 /* Strings with '\'' doubled. %q */
+#define etSQLESCAPE2 10 /* Strings with '\'' doubled and enclosed in '',
NULL pointers replaced by SQL NULL. %Q */
-#define etTOKEN 11 /* a pointer to a Token structure */
+#define etTOKEN 11 /* a pointer to a Token structure */
#define etSRCITEM 12 /* a pointer to a SrcItem */
-#define etPOINTER 13 /* The %p conversion */
-#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */
-#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */
-#define etDECIMAL 16 /* %d or %u, but not %x, %o */
+#define etPOINTER 13 /* The %p conversion */
+#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */
+#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */
+#define etDECIMAL 16 /* %d or %u, but not %x, %o */
-#define etINVALID 17 /* Any unrecognized conversion type */
+#define etINVALID 17 /* Any unrecognized conversion type */
/*
@@ -28972,8 +28972,8 @@ typedef struct et_info { /* Information about each format field */
/*
** Allowed values for et_info.flags
*/
-#define FLAG_SIGNED 1 /* True if the value to convert is signed */
-#define FLAG_STRING 4 /* Allow infinite precision */
+#define FLAG_SIGNED 1 /* True if the value to convert is signed */
+#define FLAG_STRING 4 /* Allow infinite precision */
/*
@@ -28983,7 +28983,7 @@ typedef struct et_info { /* Information about each format field */
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[] = {
- { 'd', 10, 1, etDECIMAL, 0, 0 },
+ { 'd', 10, 1, etDECIMAL, 0, 0 },
{ 's', 0, 4, etSTRING, 0, 0 },
{ 'g', 0, 1, etGENERIC, 30, 0 },
{ 'z', 0, 4, etDYNSTRING, 0, 0 },
@@ -28992,7 +28992,7 @@ static const et_info fmtinfo[] = {
{ 'w', 0, 4, etSQLESCAPE3, 0, 0 },
{ 'c', 0, 0, etCHARX, 0, 0 },
{ 'o', 8, 0, etRADIX, 0, 2 },
- { 'u', 10, 0, etDECIMAL, 0, 0 },
+ { 'u', 10, 0, etDECIMAL, 0, 0 },
{ 'x', 16, 0, etRADIX, 16, 1 },
{ 'X', 16, 0, etRADIX, 0, 4 },
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -29001,15 +29001,15 @@ static const et_info fmtinfo[] = {
{ 'E', 0, 1, etEXP, 14, 0 },
{ 'G', 0, 1, etGENERIC, 14, 0 },
#endif
- { 'i', 10, 1, etDECIMAL, 0, 0 },
+ { 'i', 10, 1, etDECIMAL, 0, 0 },
{ 'n', 0, 0, etSIZE, 0, 0 },
{ '%', 0, 0, etPERCENT, 0, 0 },
{ 'p', 16, 0, etPOINTER, 0, 1 },
- /* All the rest are undocumented and are for internal use only */
- { 'T', 0, 0, etTOKEN, 0, 0 },
+ /* All the rest are undocumented and are for internal use only */
+ { 'T', 0, 0, etTOKEN, 0, 0 },
{ 'S', 0, 0, etSRCITEM, 0, 0 },
- { 'r', 10, 1, etORDINAL, 0, 0 },
+ { 'r', 10, 1, etORDINAL, 0, 0 },
};
/* Notes:
@@ -29135,14 +29135,14 @@ SQLITE_API void sqlite3_str_vappendf(
int idx; /* A general purpose loop counter */
int width; /* Width of the current field */
etByte flag_leftjustify; /* True if "-" flag is present */
- etByte flag_prefix; /* '+' or ' ' or 0 for prefix */
+ etByte flag_prefix; /* '+' or ' ' or 0 for prefix */
etByte flag_alternateform; /* True if "#" flag is present */
etByte flag_altform2; /* True if "!" flag is present */
etByte flag_zeropad; /* True if field width constant starts with zero */
- etByte flag_long; /* 1 for the "l" flag, 2 for "ll", 0 by default */
+ etByte flag_long; /* 1 for the "l" flag, 2 for "ll", 0 by default */
etByte done; /* Loop termination flag */
- etByte cThousand; /* Thousands separator for %d and %u */
- etByte xtype = etINVALID; /* Conversion paradigm */
+ etByte cThousand; /* Thousands separator for %d and %u */
+ etByte xtype = etINVALID; /* Conversion paradigm */
u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
sqlite_uint64 longvalue; /* Value for integer types */
@@ -29167,11 +29167,11 @@ SQLITE_API void sqlite3_str_vappendf(
assert( pAccum->nChar>0 || (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
bufpt = 0;
- if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
- pArgList = va_arg(ap, PrintfArguments*);
- bArgList = 1;
+ if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
+ pArgList = va_arg(ap, PrintfArguments*);
+ bArgList = 1;
}else{
- bArgList = 0;
+ bArgList = 0;
}
for(; (c=(*fmt))!=0; ++fmt){
if( c!='%' ){
@@ -29189,7 +29189,7 @@ SQLITE_API void sqlite3_str_vappendf(
break;
}
/* Find out what flags are present */
- flag_leftjustify = flag_prefix = cThousand =
+ flag_leftjustify = flag_prefix = cThousand =
flag_alternateform = flag_altform2 = flag_zeropad = 0;
done = 0;
width = 0;
@@ -29198,12 +29198,12 @@ SQLITE_API void sqlite3_str_vappendf(
do{
switch( c ){
case '-': flag_leftjustify = 1; break;
- case '+': flag_prefix = '+'; break;
- case ' ': flag_prefix = ' '; break;
+ case '+': flag_prefix = '+'; break;
+ case ' ': flag_prefix = ' '; break;
case '#': flag_alternateform = 1; break;
case '!': flag_altform2 = 1; break;
case '0': flag_zeropad = 1; break;
- case ',': cThousand = ','; break;
+ case ',': cThousand = ','; break;
default: done = 1; break;
case 'l': {
flag_long = 1;
@@ -29223,11 +29223,11 @@ SQLITE_API void sqlite3_str_vappendf(
}
testcase( wx>0x7fffffff );
width = wx & 0x7fffffff;
-#ifdef SQLITE_PRINTF_PRECISION_LIMIT
+#ifdef SQLITE_PRINTF_PRECISION_LIMIT
if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
width = SQLITE_PRINTF_PRECISION_LIMIT;
}
-#endif
+#endif
if( c!='.' && c!='l' ){
done = 1;
}else{
@@ -29291,14 +29291,14 @@ SQLITE_API void sqlite3_str_vappendf(
}
}
}while( !done && (c=(*++fmt))!=0 );
-
+
/* Fetch the info entry for the field */
infop = &fmtinfo[0];
xtype = etINVALID;
for(idx=0; idx<ArraySize(fmtinfo); idx++){
if( c==fmtinfo[idx].fmttype ){
infop = &fmtinfo[idx];
- xtype = infop->type;
+ xtype = infop->type;
break;
}
}
@@ -29308,11 +29308,11 @@ SQLITE_API void sqlite3_str_vappendf(
**
** flag_alternateform TRUE if a '#' is present.
** flag_altform2 TRUE if a '!' is present.
- ** flag_prefix '+' or ' ' or zero
+ ** flag_prefix '+' or ' ' or zero
** flag_leftjustify TRUE if a '-' is present or if the
** field width was negative.
** flag_zeropad TRUE if the width began with 0.
- ** flag_long 1 for "l", 2 for "ll"
+ ** flag_long 1 for "l", 2 for "ll"
** width The specified field width. This is
** always non-negative. Zero is the default.
** precision The specified precision. The default
@@ -29324,24 +29324,24 @@ SQLITE_API void sqlite3_str_vappendf(
assert( precision>=(-1) );
switch( xtype ){
case etPOINTER:
- flag_long = sizeof(char*)==sizeof(i64) ? 2 :
- sizeof(char*)==sizeof(long int) ? 1 : 0;
+ flag_long = sizeof(char*)==sizeof(i64) ? 2 :
+ sizeof(char*)==sizeof(long int) ? 1 : 0;
/* no break */ deliberate_fall_through
case etORDINAL:
case etRADIX:
- cThousand = 0;
+ cThousand = 0;
/* no break */ deliberate_fall_through
- case etDECIMAL:
+ case etDECIMAL:
if( infop->flags & FLAG_SIGNED ){
i64 v;
if( bArgList ){
v = getIntArg(pArgList);
}else if( flag_long ){
- if( flag_long==2 ){
- v = va_arg(ap,i64) ;
- }else{
- v = va_arg(ap,long int);
- }
+ if( flag_long==2 ){
+ v = va_arg(ap,i64) ;
+ }else{
+ v = va_arg(ap,long int);
+ }
}else{
v = va_arg(ap,int);
}
@@ -29353,17 +29353,17 @@ SQLITE_API void sqlite3_str_vappendf(
prefix = '-';
}else{
longvalue = v;
- prefix = flag_prefix;
+ prefix = flag_prefix;
}
}else{
if( bArgList ){
longvalue = (u64)getIntArg(pArgList);
}else if( flag_long ){
- if( flag_long==2 ){
- longvalue = va_arg(ap,u64);
- }else{
- longvalue = va_arg(ap,unsigned long int);
- }
+ if( flag_long==2 ){
+ longvalue = va_arg(ap,u64);
+ }else{
+ longvalue = va_arg(ap,unsigned long int);
+ }
}else{
longvalue = va_arg(ap,unsigned int);
}
@@ -29373,7 +29373,7 @@ SQLITE_API void sqlite3_str_vappendf(
if( flag_zeropad && precision<width-(prefix!=0) ){
precision = width-(prefix!=0);
}
- if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
+ if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
nOut = etBUFSIZE;
zOut = buf;
}else{
@@ -29382,7 +29382,7 @@ SQLITE_API void sqlite3_str_vappendf(
if( cThousand ) n += precision/3;
zOut = zExtra = printfTempBuf(pAccum, n);
if( zOut==0 ) return;
- nOut = (int)n;
+ nOut = (int)n;
}
bufpt = &zOut[nOut-1];
if( xtype==etORDINAL ){
@@ -29403,24 +29403,24 @@ SQLITE_API void sqlite3_str_vappendf(
}while( longvalue>0 );
}
length = (int)(&zOut[nOut-1]-bufpt);
- while( precision>length ){
+ while( precision>length ){
*(--bufpt) = '0'; /* Zero pad */
- length++;
- }
- if( cThousand ){
- int nn = (length - 1)/3; /* Number of "," to insert */
- int ix = (length - 1)%3 + 1;
- bufpt -= nn;
- for(idx=0; nn>0; idx++){
- bufpt[idx] = bufpt[idx+nn];
- ix--;
- if( ix==0 ){
- bufpt[++idx] = cThousand;
- nn--;
- ix = 3;
- }
- }
- }
+ length++;
+ }
+ if( cThousand ){
+ int nn = (length - 1)/3; /* Number of "," to insert */
+ int ix = (length - 1)%3 + 1;
+ bufpt -= nn;
+ for(idx=0; nn>0; idx++){
+ bufpt[idx] = bufpt[idx+nn];
+ ix--;
+ if( ix==0 ){
+ bufpt[++idx] = cThousand;
+ nn--;
+ ix = 3;
+ }
+ }
+ }
if( prefix ) *(--bufpt) = prefix; /* Add sign */
if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
const char *pre;
@@ -29451,7 +29451,7 @@ SQLITE_API void sqlite3_str_vappendf(
realvalue = -realvalue;
prefix = '-';
}else{
- prefix = flag_prefix;
+ prefix = flag_prefix;
}
if( xtype==etGENERIC && precision>0 ) precision--;
testcase( precision>0xfff );
@@ -29477,16 +29477,16 @@ SQLITE_API void sqlite3_str_vappendf(
if( realvalue>0.0 ){
LONGDOUBLE_TYPE scale = 1.0;
while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
- while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; }
+ while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; }
while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
realvalue /= scale;
while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
if( exp>350 ){
- bufpt = buf;
- buf[0] = prefix;
- memcpy(buf+(prefix!=0),"Inf",4);
- length = 3+(prefix!=0);
+ bufpt = buf;
+ buf[0] = prefix;
+ memcpy(buf+(prefix!=0),"Inf",4);
+ length = 3+(prefix!=0);
break;
}
}
@@ -29665,13 +29665,13 @@ SQLITE_API void sqlite3_str_vappendf(
case etDYNSTRING:
if( bArgList ){
bufpt = getTextArg(pArgList);
- xtype = etSTRING;
+ xtype = etSTRING;
}else{
bufpt = va_arg(ap,char*);
}
if( bufpt==0 ){
bufpt = "";
- }else if( xtype==etDYNSTRING ){
+ }else if( xtype==etDYNSTRING ){
if( pAccum->nChar==0
&& pAccum->mxAlloc
&& width==0
@@ -29704,7 +29704,7 @@ SQLITE_API void sqlite3_str_vappendf(
for(length=0; length<precision && bufpt[length]; length++){}
}
}else{
- length = 0x7fffffff & (int)strlen(bufpt);
+ length = 0x7fffffff & (int)strlen(bufpt);
}
adjust_width_for_utf8:
if( flag_altform2 && width>0 ){
@@ -29742,7 +29742,7 @@ SQLITE_API void sqlite3_str_vappendf(
}
}
needQuote = !isnull && xtype==etSQLESCAPE2;
- n += i + 3;
+ n += i + 3;
if( n>etBUFSIZE ){
bufpt = zExtra = printfTempBuf(pAccum, n);
if( bufpt==0 ) return;
@@ -29762,9 +29762,9 @@ SQLITE_API void sqlite3_str_vappendf(
goto adjust_width_for_utf8;
}
case etTOKEN: {
- Token *pToken;
- if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
- pToken = va_arg(ap, Token*);
+ Token *pToken;
+ if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
+ pToken = va_arg(ap, Token*);
assert( bArgList==0 );
if( pToken && pToken->n ){
sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
@@ -29774,7 +29774,7 @@ SQLITE_API void sqlite3_str_vappendf(
}
case etSRCITEM: {
SrcItem *pItem;
- if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
+ if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
pItem = va_arg(ap, SrcItem*);
assert( bArgList==0 );
if( pItem->zAlias && !flag_altform2 ){
@@ -29807,16 +29807,16 @@ SQLITE_API void sqlite3_str_vappendf(
** then the values have been translated prior to reaching this point.
*/
width -= length;
- if( width>0 ){
+ if( width>0 ){
if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
sqlite3_str_append(pAccum, bufpt, length);
if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
- }else{
+ }else{
sqlite3_str_append(pAccum, bufpt, length);
- }
+ }
if( zExtra ){
- sqlite3DbFree(pAccum->db, zExtra);
+ sqlite3DbFree(pAccum->db, zExtra);
zExtra = 0;
}
}/* End for loop over the format string */
@@ -29841,7 +29841,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
sqlite3StrAccumSetError(p, SQLITE_TOOBIG);
return p->nAlloc - p->nChar - 1;
}else{
- char *zOld = isMalloced(p) ? p->zText : 0;
+ char *zOld = isMalloced(p) ? p->zText : 0;
i64 szNew = p->nChar;
szNew += (sqlite3_int64)N + 1;
if( szNew+p->nChar<=p->mxAlloc ){
@@ -29863,10 +29863,10 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
}
if( zNew ){
assert( p->zText!=0 || p->nChar==0 );
- if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
+ if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
- p->printfFlags |= SQLITE_PRINTF_MALLOCED;
+ p->printfFlags |= SQLITE_PRINTF_MALLOCED;
}else{
sqlite3_str_reset(p);
sqlite3StrAccumSetError(p, SQLITE_NOMEM);
@@ -29914,7 +29914,7 @@ SQLITE_API void sqlite3_str_append(sqlite3_str *p, const char *z, int N){
assert( p->accError==0 || p->nAlloc==0 || p->mxAlloc==0 );
if( p->nChar+N >= p->nAlloc ){
enlargeAndAppend(p,z,N);
- }else if( N ){
+ }else if( N ){
assert( p->zText );
p->nChar += N;
memcpy(&p->zText[p->nChar-N], z, N);
@@ -29934,24 +29934,24 @@ SQLITE_API void sqlite3_str_appendall(sqlite3_str *p, const char *z){
** Return a pointer to the resulting string. Return a NULL
** pointer if any kind of error was encountered.
*/
-static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){
- char *zText;
- assert( p->mxAlloc>0 && !isMalloced(p) );
- zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
- if( zText ){
- memcpy(zText, p->zText, p->nChar+1);
- p->printfFlags |= SQLITE_PRINTF_MALLOCED;
- }else{
+static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){
+ char *zText;
+ assert( p->mxAlloc>0 && !isMalloced(p) );
+ zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
+ if( zText ){
+ memcpy(zText, p->zText, p->nChar+1);
+ p->printfFlags |= SQLITE_PRINTF_MALLOCED;
+ }else{
sqlite3StrAccumSetError(p, SQLITE_NOMEM);
- }
- p->zText = zText;
- return zText;
-}
+ }
+ p->zText = zText;
+ return zText;
+}
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
if( p->zText ){
p->zText[p->nChar] = 0;
- if( p->mxAlloc>0 && !isMalloced(p) ){
- return strAccumFinishRealloc(p);
+ if( p->mxAlloc>0 && !isMalloced(p) ){
+ return strAccumFinishRealloc(p);
}
}
return p->zText;
@@ -30017,9 +30017,9 @@ SQLITE_API char *sqlite3_str_value(sqlite3_str *p){
** Reset an StrAccum string. Reclaim all malloced memory.
*/
SQLITE_API void sqlite3_str_reset(StrAccum *p){
- if( isMalloced(p) ){
+ if( isMalloced(p) ){
sqlite3DbFree(p->db, p->zText);
- p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
+ p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
}
p->nAlloc = 0;
p->nChar = 0;
@@ -30041,13 +30041,13 @@ SQLITE_API void sqlite3_str_reset(StrAccum *p){
** allocations will ever occur.
*/
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
- p->zText = zBase;
+ p->zText = zBase;
p->db = db;
p->nAlloc = n;
p->mxAlloc = mx;
- p->nChar = 0;
+ p->nChar = 0;
p->accError = 0;
- p->printfFlags = 0;
+ p->printfFlags = 0;
}
/* Allocate and initialize a new dynamic string object */
@@ -30073,11 +30073,11 @@ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list a
assert( db!=0 );
sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
- acc.printfFlags = SQLITE_PRINTF_INTERNAL;
+ acc.printfFlags = SQLITE_PRINTF_INTERNAL;
sqlite3_str_vappendf(&acc, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
if( acc.accError==SQLITE_NOMEM ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
}
return z;
}
@@ -30099,7 +30099,7 @@ SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){
** Print into memory obtained from sqlite3_malloc(). Omit the internal
** %-conversion extensions.
*/
-SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
+SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
char *z;
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
@@ -30123,7 +30123,7 @@ SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
** Print into memory obtained from sqlite3_malloc()(). Omit the internal
** %-conversion extensions.
*/
-SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
+SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
va_list ap;
char *z;
#ifndef SQLITE_OMIT_AUTOINIT
@@ -30148,7 +30148,7 @@ SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
**
** sqlite3_vsnprintf() is the varargs version.
*/
-SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
+SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
StrAccum acc;
if( n<=0 ) return zBuf;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -30160,10 +30160,10 @@ SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_li
#endif
sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
sqlite3_str_vappendf(&acc, zFormat, ap);
- zBuf[acc.nChar] = 0;
- return zBuf;
+ zBuf[acc.nChar] = 0;
+ return zBuf;
}
-SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
+SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
char *z;
va_list ap;
va_start(ap,zFormat);
@@ -30199,7 +30199,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
/*
** Format and write a message to the log if logging is enabled.
*/
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
+SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
va_list ap; /* Vararg list */
if( sqlite3GlobalConfig.xLog ){
va_start(ap, zFormat);
@@ -30223,22 +30223,22 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
sqlite3_str_vappendf(&acc, zFormat, ap);
va_end(ap);
sqlite3StrAccumFinish(&acc);
-#ifdef SQLITE_OS_TRACE_PROC
- {
- extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf);
- SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf));
- }
-#else
+#ifdef SQLITE_OS_TRACE_PROC
+ {
+ extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf);
+ SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf));
+ }
+#else
fprintf(stdout,"%s", zBuf);
fflush(stdout);
-#endif
+#endif
}
#endif
/*
** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument
-** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
+** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
*/
SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){
va_list ap;
@@ -30334,32 +30334,32 @@ static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){
}
/*
-** Generate a human-readable description of a WITH clause.
+** Generate a human-readable description of a WITH clause.
*/
-SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
- int i;
- if( pWith==0 ) return;
- if( pWith->nCte==0 ) return;
- if( pWith->pOuter ){
- sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter);
- }else{
- sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith);
- }
- if( pWith->nCte>0 ){
- pView = sqlite3TreeViewPush(pView, 1);
- for(i=0; i<pWith->nCte; i++){
+SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
+ int i;
+ if( pWith==0 ) return;
+ if( pWith->nCte==0 ) return;
+ if( pWith->pOuter ){
+ sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter);
+ }else{
+ sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith);
+ }
+ if( pWith->nCte>0 ){
+ pView = sqlite3TreeViewPush(pView, 1);
+ for(i=0; i<pWith->nCte; i++){
StrAccum x;
- char zLine[1000];
- const struct Cte *pCte = &pWith->a[i];
+ char zLine[1000];
+ const struct Cte *pCte = &pWith->a[i];
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
sqlite3_str_appendf(&x, "%s", pCte->zName);
- if( pCte->pCols && pCte->pCols->nExpr>0 ){
- char cSep = '(';
- int j;
- for(j=0; j<pCte->pCols->nExpr; j++){
+ if( pCte->pCols && pCte->pCols->nExpr>0 ){
+ char cSep = '(';
+ int j;
+ for(j=0; j<pCte->pCols->nExpr; j++){
sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zEName);
- cSep = ',';
- }
+ cSep = ',';
+ }
sqlite3_str_appendf(&x, ")");
}
if( pCte->pUse ){
@@ -30367,14 +30367,14 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m
pCte->pUse->nUse);
}
sqlite3StrAccumFinish(&x);
- sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
- sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
+ sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
+ sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
sqlite3TreeViewPop(pView);
}
sqlite3TreeViewPop(pView);
}
-}
-
+}
+
/*
** Generate a human-readable description of a SrcList object.
*/
@@ -30413,24 +30413,24 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc)
sqlite3TreeViewPop(pView);
}
}
-
-/*
-** Generate a human-readable description of a Select object.
-*/
-SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
- int n = 0;
- int cnt = 0;
- if( p==0 ){
- sqlite3TreeViewLine(pView, "nil-SELECT");
- return;
- }
- pView = sqlite3TreeViewPush(pView, moreToFollow);
- if( p->pWith ){
- sqlite3TreeViewWith(pView, p->pWith, 1);
- cnt = 1;
- sqlite3TreeViewPush(pView, 1);
- }
- do{
+
+/*
+** Generate a human-readable description of a Select object.
+*/
+SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
+ int n = 0;
+ int cnt = 0;
+ if( p==0 ){
+ sqlite3TreeViewLine(pView, "nil-SELECT");
+ return;
+ }
+ pView = sqlite3TreeViewPush(pView, moreToFollow);
+ if( p->pWith ){
+ sqlite3TreeViewWith(pView, p->pWith, 1);
+ cnt = 1;
+ sqlite3TreeViewPush(pView, 1);
+ }
+ do{
if( p->selFlags & SF_WhereBegin ){
sqlite3TreeViewLine(pView, "sqlite3WhereBegin()");
}else{
@@ -30442,17 +30442,17 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
(int)p->nSelectRow
);
}
- if( cnt++ ) sqlite3TreeViewPop(pView);
- if( p->pPrior ){
- n = 1000;
- }else{
- n = 0;
- if( p->pSrc && p->pSrc->nSrc ) n++;
- if( p->pWhere ) n++;
- if( p->pGroupBy ) n++;
- if( p->pHaving ) n++;
- if( p->pOrderBy ) n++;
- if( p->pLimit ) n++;
+ if( cnt++ ) sqlite3TreeViewPop(pView);
+ if( p->pPrior ){
+ n = 1000;
+ }else{
+ n = 0;
+ if( p->pSrc && p->pSrc->nSrc ) n++;
+ if( p->pWhere ) n++;
+ if( p->pGroupBy ) n++;
+ if( p->pHaving ) n++;
+ if( p->pOrderBy ) n++;
+ if( p->pLimit ) n++;
#ifndef SQLITE_OMIT_WINDOWFUNC
if( p->pWin ) n++;
if( p->pWinDefn ) n++;
@@ -30473,25 +30473,25 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
sqlite3TreeViewPop(pView);
}
#endif
- if( p->pSrc && p->pSrc->nSrc ){
- pView = sqlite3TreeViewPush(pView, (n--)>0);
- sqlite3TreeViewLine(pView, "FROM");
+ if( p->pSrc && p->pSrc->nSrc ){
+ pView = sqlite3TreeViewPush(pView, (n--)>0);
+ sqlite3TreeViewLine(pView, "FROM");
sqlite3TreeViewSrcList(pView, p->pSrc);
- sqlite3TreeViewPop(pView);
- }
- if( p->pWhere ){
- sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pWhere, 0);
- sqlite3TreeViewPop(pView);
- }
- if( p->pGroupBy ){
- sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
- }
- if( p->pHaving ){
- sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pHaving, 0);
- sqlite3TreeViewPop(pView);
- }
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pWhere ){
+ sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pWhere, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pGroupBy ){
+ sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
+ }
+ if( p->pHaving ){
+ sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pHaving, 0);
+ sqlite3TreeViewPop(pView);
+ }
#ifndef SQLITE_OMIT_WINDOWFUNC
if( p->pWinDefn ){
Window *pX;
@@ -30502,30 +30502,30 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
sqlite3TreeViewPop(pView);
}
#endif
- if( p->pOrderBy ){
- sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
- }
- if( p->pLimit ){
- sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0);
- if( p->pLimit->pRight ){
- sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
- sqlite3TreeViewPop(pView);
- }
- sqlite3TreeViewPop(pView);
- }
- if( p->pPrior ){
- const char *zOp = "UNION";
- switch( p->op ){
- case TK_ALL: zOp = "UNION ALL"; break;
- case TK_INTERSECT: zOp = "INTERSECT"; break;
- case TK_EXCEPT: zOp = "EXCEPT"; break;
- }
- sqlite3TreeViewItem(pView, zOp, 1);
- }
- p = p->pPrior;
- }while( p!=0 );
+ if( p->pOrderBy ){
+ sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
+ }
+ if( p->pLimit ){
+ sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0);
+ if( p->pLimit->pRight ){
+ sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pPrior ){
+ const char *zOp = "UNION";
+ switch( p->op ){
+ case TK_ALL: zOp = "UNION ALL"; break;
+ case TK_INTERSECT: zOp = "INTERSECT"; break;
+ case TK_EXCEPT: zOp = "EXCEPT"; break;
+ }
+ sqlite3TreeViewItem(pView, zOp, 1);
+ }
+ p = p->pPrior;
+ }while( p!=0 );
sqlite3TreeViewPop(pView);
}
@@ -30662,9 +30662,9 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
sqlite3_str_appendf(&x, " fg.af=%x.%c",
pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
- if( ExprHasProperty(pExpr, EP_FromJoin) ){
+ if( ExprHasProperty(pExpr, EP_FromJoin) ){
sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable);
- }
+ }
if( ExprHasProperty(pExpr, EP_FromDDL) ){
sqlite3_str_appendf(&x, " DDL");
}
@@ -30806,13 +30806,13 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
break;
}
- case TK_SPAN: {
+ case TK_SPAN: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
- sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
- break;
- }
-
+ sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+ break;
+ }
+
case TK_COLLATE: {
/* COLLATE operators without the EP_Collate flag are intended to
** emulate collation associated with a table column. These show
@@ -30876,7 +30876,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
#ifndef SQLITE_OMIT_SUBQUERY
case TK_EXISTS: {
assert( ExprUseXSelect(pExpr) );
- sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags);
+ sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags);
sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
break;
}
@@ -30887,7 +30887,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
break;
}
case TK_IN: {
- sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags);
+ sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
if( ExprUseXSelect(pExpr) ){
sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
@@ -30955,32 +30955,32 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
break;
}
#endif
- case TK_MATCH: {
- sqlite3TreeViewLine(pView, "MATCH {%d:%d}%s",
- pExpr->iTable, pExpr->iColumn, zFlgs);
- sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
- break;
- }
- case TK_VECTOR: {
+ case TK_MATCH: {
+ sqlite3TreeViewLine(pView, "MATCH {%d:%d}%s",
+ pExpr->iTable, pExpr->iColumn, zFlgs);
+ sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
+ break;
+ }
+ case TK_VECTOR: {
char *z = sqlite3_mprintf("VECTOR%s",zFlgs);
assert( ExprUseXList(pExpr) );
sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z);
sqlite3_free(z);
- break;
- }
- case TK_SELECT_COLUMN: {
+ break;
+ }
+ case TK_SELECT_COLUMN: {
sqlite3TreeViewLine(pView, "SELECT-COLUMN %d of [0..%d]%s",
pExpr->iColumn, pExpr->iTable-1,
pExpr->pRight==pExpr->pLeft ? " (SELECT-owner)" : "");
assert( ExprUseXSelect(pExpr->pLeft) );
- sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
- break;
- }
- case TK_IF_NULL_ROW: {
- sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable);
- sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
- break;
- }
+ sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
+ break;
+ }
+ case TK_IF_NULL_ROW: {
+ sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable);
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+ break;
+ }
case TK_ERROR: {
Expr tmp;
sqlite3TreeViewLine(pView, "ERROR");
@@ -31014,11 +31014,11 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
sqlite3TreeViewPop(pView);
}
-
+
/*
** Generate a human-readable explanation of an expression list.
*/
-SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
+SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
TreeView *pView,
const ExprList *pList,
const char *zLabel
@@ -31027,14 +31027,14 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
if( pList==0 ){
sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
}else{
- int i;
+ int i;
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; i<pList->nExpr; i++){
- int j = pList->a[i].u.x.iOrderByCol;
+ int j = pList->a[i].u.x.iOrderByCol;
char *zName = pList->a[i].zEName;
int moreToFollow = i<pList->nExpr - 1;
if( pList->a[i].eEName!=ENAME_NAME ) zName = 0;
- if( j || zName ){
+ if( j || zName ){
sqlite3TreeViewPush(pView, moreToFollow);
moreToFollow = 0;
sqlite3TreeViewLine(pView, 0);
@@ -31046,22 +31046,22 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
}
fprintf(stdout, "\n");
fflush(stdout);
- }
+ }
sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
- if( j || zName ){
- sqlite3TreeViewPop(pView);
- }
- }
- }
-}
-SQLITE_PRIVATE void sqlite3TreeViewExprList(
- TreeView *pView,
- const ExprList *pList,
- u8 moreToFollow,
- const char *zLabel
-){
- pView = sqlite3TreeViewPush(pView, moreToFollow);
- sqlite3TreeViewBareExprList(pView, pList, zLabel);
+ if( j || zName ){
+ sqlite3TreeViewPop(pView);
+ }
+ }
+ }
+}
+SQLITE_PRIVATE void sqlite3TreeViewExprList(
+ TreeView *pView,
+ const ExprList *pList,
+ u8 moreToFollow,
+ const char *zLabel
+){
+ pView = sqlite3TreeViewPush(pView, moreToFollow);
+ sqlite3TreeViewBareExprList(pView, pList, zLabel);
sqlite3TreeViewPop(pView);
}
@@ -31101,7 +31101,7 @@ static SQLITE_WSD struct sqlite3PrngType {
/*
** Return N random bytes.
*/
-SQLITE_API void sqlite3_randomness(int N, void *pBuf){
+SQLITE_API void sqlite3_randomness(int N, void *pBuf){
unsigned char t;
unsigned char *zBuf = pBuf;
@@ -31182,7 +31182,7 @@ SQLITE_API void sqlite3_randomness(int N, void *pBuf){
sqlite3_mutex_leave(mutex);
}
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
/*
** For testing purposes, we sometimes want to preserve the state of
** PRNG and restore the PRNG to its saved state at a later time, or
@@ -31207,7 +31207,7 @@ SQLITE_PRIVATE void sqlite3PrngRestoreState(void){
sizeof(sqlite3Prng)
);
}
-#endif /* SQLITE_UNTESTABLE */
+#endif /* SQLITE_UNTESTABLE */
/************** End of random.c **********************************************/
/************** Begin file threads.c *****************************************/
@@ -31276,14 +31276,14 @@ SQLITE_PRIVATE int sqlite3ThreadCreate(
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
- if( p==0 ) return SQLITE_NOMEM_BKPT;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
memset(p, 0, sizeof(*p));
p->xTask = xTask;
p->pIn = pIn;
/* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a
- ** function that returns SQLITE_ERROR when passed the argument 200, that
+ ** function that returns SQLITE_ERROR when passed the argument 200, that
** forces worker threads to run sequentially and deterministically
- ** for testing purposes. */
+ ** for testing purposes. */
if( sqlite3FaultSim(200) ){
rc = 1;
}else{
@@ -31302,7 +31302,7 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
int rc;
assert( ppOut!=0 );
- if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
+ if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
if( p->done ){
*ppOut = p->pOut;
rc = SQLITE_OK;
@@ -31367,13 +31367,13 @@ SQLITE_PRIVATE int sqlite3ThreadCreate(
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
- if( p==0 ) return SQLITE_NOMEM_BKPT;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
/* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a
- ** function that returns SQLITE_ERROR when passed the argument 200, that
+ ** function that returns SQLITE_ERROR when passed the argument 200, that
** forces worker threads to run sequentially and deterministically
- ** (via the sqlite3FaultSim() term of the conditional) for testing
- ** purposes. */
- if( sqlite3GlobalConfig.bCoreMutex==0 || sqlite3FaultSim(200) ){
+ ** (via the sqlite3FaultSim() term of the conditional) for testing
+ ** purposes. */
+ if( sqlite3GlobalConfig.bCoreMutex==0 || sqlite3FaultSim(200) ){
memset(p, 0, sizeof(*p));
}else{
p->xTask = xTask;
@@ -31399,9 +31399,9 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
BOOL bRc;
assert( ppOut!=0 );
- if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
+ if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
if( p->xTask==0 ){
- /* assert( p->id==GetCurrentThreadId() ); */
+ /* assert( p->id==GetCurrentThreadId() ); */
rc = WAIT_OBJECT_0;
assert( p->tid==0 );
}else{
@@ -31447,7 +31447,7 @@ SQLITE_PRIVATE int sqlite3ThreadCreate(
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
- if( p==0 ) return SQLITE_NOMEM_BKPT;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
if( (SQLITE_PTR_TO_INT(p)/17)&1 ){
p->xTask = xTask;
p->pIn = pIn;
@@ -31463,7 +31463,7 @@ SQLITE_PRIVATE int sqlite3ThreadCreate(
SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
assert( ppOut!=0 );
- if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
+ if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
if( p->xTask ){
*ppOut = p->xTask(p->pIn);
}else{
@@ -31474,7 +31474,7 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
#if defined(SQLITE_TEST)
{
void *pTstAlloc = sqlite3Malloc(10);
- if (!pTstAlloc) return SQLITE_NOMEM_BKPT;
+ if (!pTstAlloc) return SQLITE_NOMEM_BKPT;
sqlite3_free(pTstAlloc);
}
#endif
@@ -31527,13 +31527,13 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
/* #include <assert.h> */
/* #include "vdbeInt.h" */
-#if !defined(SQLITE_AMALGAMATION) && SQLITE_BYTEORDER==0
+#if !defined(SQLITE_AMALGAMATION) && SQLITE_BYTEORDER==0
/*
** The following constant value is used by the SQLITE_BIGENDIAN and
** SQLITE_LITTLEENDIAN macros.
*/
SQLITE_PRIVATE const int sqlite3one = 1;
-#endif /* SQLITE_AMALGAMATION && SQLITE_BYTEORDER==0 */
+#endif /* SQLITE_AMALGAMATION && SQLITE_BYTEORDER==0 */
/*
** This lookup table is used to help decode the first byte of
@@ -31703,7 +31703,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desired
rc = sqlite3VdbeMemMakeWriteable(pMem);
if( rc!=SQLITE_OK ){
assert( rc==SQLITE_NOMEM );
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
zIn = (u8*)pMem->z;
zTerm = &zIn[pMem->n&~1];
@@ -31745,7 +31745,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desired
zTerm = &zIn[pMem->n];
zOut = sqlite3DbMallocRaw(pMem->db, len);
if( !zOut ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
z = zOut;
@@ -31852,9 +31852,9 @@ translate_out:
#endif
return SQLITE_OK;
}
-#endif /* SQLITE_OMIT_UTF16 */
+#endif /* SQLITE_OMIT_UTF16 */
-#ifndef SQLITE_OMIT_UTF16
+#ifndef SQLITE_OMIT_UTF16
/*
** This routine checks for a byte-order mark at the beginning of the
** UTF-16 string stored in *pMem. If one is present, it is removed and
@@ -32068,7 +32068,7 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
** should have a unique code. To prevent legacy testing applications from
** breaking, the codes should not be changed or reused.
*/
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE int sqlite3FaultSim(int iTest){
int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback;
return xCallback ? xCallback(iTest) : SQLITE_OK;
@@ -32111,12 +32111,12 @@ SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
/*
** Return the declared type of a column. Or return zDflt if the column
-** has no declared type.
-**
-** The column type is an extra string stored after the zero-terminator on
-** the column name if and only if the COLFLAG_HASTYPE flag is set.
-*/
-SQLITE_PRIVATE char *sqlite3ColumnType(Column *pCol, char *zDflt){
+** has no declared type.
+**
+** The column type is an extra string stored after the zero-terminator on
+** the column name if and only if the COLFLAG_HASTYPE flag is set.
+*/
+SQLITE_PRIVATE char *sqlite3ColumnType(Column *pCol, char *zDflt){
if( pCol->colFlags & COLFLAG_HASTYPE ){
return pCol->zCnName + strlen(pCol->zCnName) + 1;
}else if( pCol->eCType ){
@@ -32125,27 +32125,27 @@ SQLITE_PRIVATE char *sqlite3ColumnType(Column *pCol, char *zDflt){
}else{
return zDflt;
}
-}
-
-/*
-** Helper function for sqlite3Error() - called rarely. Broken out into
-** a separate routine to avoid unnecessary register saves on entry to
-** sqlite3Error().
-*/
-static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){
- if( db->pErr ) sqlite3ValueSetNull(db->pErr);
- sqlite3SystemError(db, err_code);
-}
-
-/*
+}
+
+/*
+** Helper function for sqlite3Error() - called rarely. Broken out into
+** a separate routine to avoid unnecessary register saves on entry to
+** sqlite3Error().
+*/
+static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){
+ if( db->pErr ) sqlite3ValueSetNull(db->pErr);
+ sqlite3SystemError(db, err_code);
+}
+
+/*
** Set the current error code to err_code and clear any prior error message.
-** Also set iSysErrno (by calling sqlite3System) if the err_code indicates
-** that would be appropriate.
+** Also set iSysErrno (by calling sqlite3System) if the err_code indicates
+** that would be appropriate.
*/
SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){
assert( db!=0 );
db->errCode = err_code;
- if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code);
+ if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code);
}
/*
@@ -32159,18 +32159,18 @@ SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3 *db){
}
/*
-** Load the sqlite3.iSysErrno field if that is an appropriate thing
-** to do based on the SQLite error code in rc.
-*/
-SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){
- if( rc==SQLITE_IOERR_NOMEM ) return;
- rc &= 0xff;
- if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){
- db->iSysErrno = sqlite3OsGetLastError(db->pVfs);
- }
-}
-
-/*
+** Load the sqlite3.iSysErrno field if that is an appropriate thing
+** to do based on the SQLite error code in rc.
+*/
+SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){
+ if( rc==SQLITE_IOERR_NOMEM ) return;
+ rc &= 0xff;
+ if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){
+ db->iSysErrno = sqlite3OsGetLastError(db->pVfs);
+ }
+}
+
+/*
** Set the most recent error code and error string for the sqlite
** handle "db". The error code is set to "err_code".
**
@@ -32194,7 +32194,7 @@ SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){
SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){
assert( db!=0 );
db->errCode = err_code;
- sqlite3SystemError(db, err_code);
+ sqlite3SystemError(db, err_code);
if( zFormat==0 ){
sqlite3Error(db, err_code);
}else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){
@@ -32272,13 +32272,13 @@ SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3 *db, int errCode){
** brackets from around identifiers. For example: "[a-b-c]" becomes
** "a-b-c".
*/
-SQLITE_PRIVATE void sqlite3Dequote(char *z){
+SQLITE_PRIVATE void sqlite3Dequote(char *z){
char quote;
int i, j;
- if( z==0 ) return;
+ if( z==0 ) return;
quote = z[0];
- if( !sqlite3Isquote(quote) ) return;
- if( quote=='[' ) quote = ']';
+ if( !sqlite3Isquote(quote) ) return;
+ if( quote=='[' ) quote = ']';
for(i=1, j=0;; i++){
assert( z[i] );
if( z[i]==quote ){
@@ -32301,7 +32301,7 @@ SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){
sqlite3Dequote(p->u.zToken);
}
-/*
+/*
** If the input token p is quoted, try to adjust the token to remove
** the quotes. This is not always possible:
**
@@ -32324,13 +32324,13 @@ SQLITE_PRIVATE void sqlite3DequoteToken(Token *p){
}
/*
-** Generate a Token object from a string
-*/
-SQLITE_PRIVATE void sqlite3TokenInit(Token *p, char *z){
- p->z = z;
- p->n = sqlite3Strlen30(z);
-}
-
+** Generate a Token object from a string
+*/
+SQLITE_PRIVATE void sqlite3TokenInit(Token *p, char *z){
+ p->z = z;
+ p->n = sqlite3Strlen30(z);
+}
+
/* Convenient short-hand */
#define UpperToLower sqlite3UpperToLower
@@ -32344,20 +32344,20 @@ SQLITE_PRIVATE void sqlite3TokenInit(Token *p, char *z){
** case-independent fashion, using the same definition of "case
** independence" that SQLite uses internally when comparing identifiers.
*/
-SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
+SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
if( zLeft==0 ){
return zRight ? -1 : 0;
}else if( zRight==0 ){
return 1;
}
- return sqlite3StrICmp(zLeft, zRight);
-}
-SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
- unsigned char *a, *b;
+ return sqlite3StrICmp(zLeft, zRight);
+}
+SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
+ unsigned char *a, *b;
int c, x;
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
- for(;;){
+ for(;;){
c = *a;
x = *b;
if( c==x ){
@@ -32366,12 +32366,12 @@ SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
c = (int)UpperToLower[c] - (int)UpperToLower[x];
if( c ) break;
}
- a++;
- b++;
- }
- return c;
+ a++;
+ b++;
+ }
+ return c;
}
-SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
+SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
register unsigned char *a, *b;
if( zLeft==0 ){
return zRight ? -1 : 0;
@@ -32398,14 +32398,14 @@ SQLITE_PRIVATE u8 sqlite3StrIHash(const char *z){
}
/*
-** Compute 10 to the E-th power. Examples: E==1 results in 10.
-** E==2 results in 100. E==50 results in 1.0e50.
-**
-** This routine only works for values of E between 1 and 341.
-*/
-static LONGDOUBLE_TYPE sqlite3Pow10(int E){
-#if defined(_MSC_VER)
- static const LONGDOUBLE_TYPE x[] = {
+** Compute 10 to the E-th power. Examples: E==1 results in 10.
+** E==2 results in 100. E==50 results in 1.0e50.
+**
+** This routine only works for values of E between 1 and 341.
+*/
+static LONGDOUBLE_TYPE sqlite3Pow10(int E){
+#if defined(_MSC_VER)
+ static const LONGDOUBLE_TYPE x[] = {
1.0e+001L,
1.0e+002L,
1.0e+004L,
@@ -32415,28 +32415,28 @@ static LONGDOUBLE_TYPE sqlite3Pow10(int E){
1.0e+064L,
1.0e+128L,
1.0e+256L
- };
- LONGDOUBLE_TYPE r = 1.0;
- int i;
- assert( E>=0 && E<=307 );
- for(i=0; E!=0; i++, E >>=1){
- if( E & 1 ) r *= x[i];
- }
- return r;
-#else
- LONGDOUBLE_TYPE x = 10.0;
- LONGDOUBLE_TYPE r = 1.0;
- while(1){
- if( E & 1 ) r *= x;
- E >>= 1;
- if( E==0 ) break;
- x *= x;
- }
+ };
+ LONGDOUBLE_TYPE r = 1.0;
+ int i;
+ assert( E>=0 && E<=307 );
+ for(i=0; E!=0; i++, E >>=1){
+ if( E & 1 ) r *= x[i];
+ }
+ return r;
+#else
+ LONGDOUBLE_TYPE x = 10.0;
+ LONGDOUBLE_TYPE r = 1.0;
+ while(1){
+ if( E & 1 ) r *= x;
+ E >>= 1;
+ if( E==0 ) break;
+ x *= x;
+ }
return r;
-#endif
-}
-
-/*
+#endif
+}
+
+/*
** The string z[] is an text representation of a real number.
** Convert this string to a double and write it into *pResult.
**
@@ -32499,7 +32499,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
testcase( enc==SQLITE_UTF16BE );
for(i=3-enc; i<length && z[i]==0; i+=2){}
if( i<length ) eType = -100;
- zEnd = &z[i^1];
+ zEnd = &z[i^1];
z += (enc&1);
}
@@ -32533,12 +32533,12 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
eType++;
/* copy digits from after decimal to significand
** (decrease exponent by d to shift decimal right) */
- while( z<zEnd && sqlite3Isdigit(*z) ){
- if( s<((LARGEST_INT64-9)/10) ){
- s = s*10 + (*z - '0');
- d--;
+ while( z<zEnd && sqlite3Isdigit(*z) ){
+ if( s<((LARGEST_INT64-9)/10) ){
+ s = s*10 + (*z - '0');
+ d--;
nDigit++;
- }
+ }
z+=incr;
}
}
@@ -32549,12 +32549,12 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
z+=incr;
eValid = 0;
eType++;
-
+
/* This branch is needed to avoid a (harmless) buffer overread. The
- ** special comment alerts the mutation tester that the correct answer
- ** is obtained even if the branch is omitted */
- if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/
-
+ ** special comment alerts the mutation tester that the correct answer
+ ** is obtained even if the branch is omitted */
+ if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/
+
/* get sign of exponent */
if( *z=='-' ){
esign = -1;
@@ -32571,7 +32571,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
}
/* skip trailing spaces */
- while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
+ while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
do_atof_calc:
/* adjust exponent by d, and update sign */
@@ -32583,57 +32583,57 @@ do_atof_calc:
esign = 1;
}
- if( s==0 ) {
- /* In the IEEE 754 standard, zero is signed. */
- result = sign<0 ? -(double)0 : (double)0;
+ if( s==0 ) {
+ /* In the IEEE 754 standard, zero is signed. */
+ result = sign<0 ? -(double)0 : (double)0;
} else {
- /* Attempt to reduce exponent.
- **
- ** Branches that are not required for the correct answer but which only
- ** help to obtain the correct answer faster are marked with special
- ** comments, as a hint to the mutation tester.
- */
- while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/
- if( esign>0 ){
- if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/
- s *= 10;
- }else{
- if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/
- s /= 10;
- }
- e--;
+ /* Attempt to reduce exponent.
+ **
+ ** Branches that are not required for the correct answer but which only
+ ** help to obtain the correct answer faster are marked with special
+ ** comments, as a hint to the mutation tester.
+ */
+ while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/
+ if( esign>0 ){
+ if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/
+ s *= 10;
+ }else{
+ if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/
+ s /= 10;
+ }
+ e--;
}
/* adjust the sign of significand */
s = sign<0 ? -s : s;
- if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/
- result = (double)s;
- }else{
+ if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/
+ result = (double)s;
+ }else{
/* attempt to handle extremely small/large numbers better */
- if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/
- if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/
- LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308);
- if( esign<0 ){
- result = s / scale;
- result /= 1.0e+308;
- }else{
- result = s * scale;
- result *= 1.0e+308;
- }
- }else{ assert( e>=342 );
- if( esign<0 ){
- result = 0.0*s;
- }else{
-#ifdef INFINITY
- result = INFINITY*s;
-#else
- result = 1e308*1e308*s; /* Infinity */
-#endif
- }
+ if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/
+ if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/
+ LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308);
+ if( esign<0 ){
+ result = s / scale;
+ result /= 1.0e+308;
+ }else{
+ result = s * scale;
+ result *= 1.0e+308;
+ }
+ }else{ assert( e>=342 );
+ if( esign<0 ){
+ result = 0.0*s;
+ }else{
+#ifdef INFINITY
+ result = INFINITY*s;
+#else
+ result = 1e308*1e308*s; /* Infinity */
+#endif
+ }
}
}else{
- LONGDOUBLE_TYPE scale = sqlite3Pow10(e);
+ LONGDOUBLE_TYPE scale = sqlite3Pow10(e);
if( esign<0 ){
result = s / scale;
}else{
@@ -32721,13 +32721,13 @@ static int compare2pow63(const char *zNum, int incr){
** Convert zNum to a 64-bit signed integer. zNum must be decimal. This
** routine does *not* accept hexadecimal notation.
**
-** Returns:
+** Returns:
**
** -1 Not even a prefix of the input text looks like an integer
-** 0 Successful transformation. Fits in a 64-bit signed integer.
+** 0 Successful transformation. Fits in a 64-bit signed integer.
** 1 Excess non-space text after the integer value
-** 2 Integer too large for a 64-bit signed integer or is malformed
-** 3 Special case of 9223372036854775808
+** 2 Integer too large for a 64-bit signed integer or is malformed
+** 3 Special case of 9223372036854775808
**
** length is the number of bytes in the string (bytes, not characters).
** The string is not necessarily zero-terminated. The encoding is
@@ -32739,8 +32739,8 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
int neg = 0; /* assume positive */
int i;
int c = 0;
- int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
- int rc; /* Baseline return code */
+ int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
+ int rc; /* Baseline return code */
const char *zStart;
const char *zEnd = zNum + length;
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
@@ -32752,7 +32752,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
for(i=3-enc; i<length && zNum[i]==0; i+=2){}
nonNum = i<length;
- zEnd = &zNum[i^1];
+ zEnd = &zNum[i^1];
zNum += (enc&1);
}
while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
@@ -32787,7 +32787,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
if( i==0 && zStart==zNum ){ /* No digits */
rc = -1;
}else if( nonNum ){ /* UTF16 with high-order bytes non-zero */
- rc = 1;
+ rc = 1;
}else if( &zNum[i]<zEnd ){ /* Extra bytes at the end */
int jj = i;
do{
@@ -32797,18 +32797,18 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
}
jj += incr;
}while( &zNum[jj]<zEnd );
- }
+ }
if( i<19*incr ){
/* Less than 19 digits, so we know that it fits in 64 bits */
assert( u<=LARGEST_INT64 );
- return rc;
+ return rc;
}else{
/* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */
c = i>19*incr ? 1 : compare2pow63(zNum, incr);
if( c<0 ){
/* zNum is less than 9223372036854775808 so it fits */
assert( u<=LARGEST_INT64 );
- return rc;
+ return rc;
}else{
*pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
if( c>0 ){
@@ -32832,9 +32832,9 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
** Returns:
**
** 0 Successful transformation. Fits in a 64-bit signed integer.
-** 1 Excess text after the integer value
-** 2 Integer too large for a 64-bit signed integer or is malformed
-** 3 Special case of 9223372036854775808
+** 1 Excess text after the integer value
+** 2 Integer too large for a 64-bit signed integer or is malformed
+** 3 Special case of 9223372036854775808
*/
SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
#ifndef SQLITE_OMIT_HEX_INTEGER
@@ -32848,7 +32848,7 @@ SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
u = u*16 + sqlite3HexToInt(z[k]);
}
memcpy(pOut, &u, 8);
- return (z[k]==0 && k-i<=16) ? 0 : 2;
+ return (z[k]==0 && k-i<=16) ? 0 : 2;
}else
#endif /* SQLITE_OMIT_HEX_INTEGER */
{
@@ -32895,7 +32895,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){
}
}
#endif
- if( !sqlite3Isdigit(zNum[0]) ) return 0;
+ if( !sqlite3Isdigit(zNum[0]) ) return 0;
while( zNum[0]=='0' ) zNum++;
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
v = v*10 + c;
@@ -33095,8 +33095,8 @@ SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
/* a: p0<<28 | p2<<14 | p4 (unmasked) */
if (!(a&0x80))
{
- /* we can skip these cause they were (effectively) done above
- ** while calculating s */
+ /* we can skip these cause they were (effectively) done above
+ ** while calculating s */
/* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
/* b &= (0x7f<<14)|(0x7f); */
b = b<<7;
@@ -33316,8 +33316,8 @@ SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
** 64-bit integer.
*/
SQLITE_PRIVATE int sqlite3VarintLen(u64 v){
- int i;
- for(i=1; (v >>= 7)!=0; i++){ assert( i<10 ); }
+ int i;
+ for(i=1; (v >>= 7)!=0; i++){ assert( i<10 ); }
return i;
}
@@ -33330,11 +33330,11 @@ SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
u32 x;
memcpy(&x,p,4);
return x;
-#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
u32 x;
memcpy(&x,p,4);
return __builtin_bswap32(x);
-#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
u32 x;
memcpy(&x,p,4);
return _byteswap_ulong(x);
@@ -33346,10 +33346,10 @@ SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){
#if SQLITE_BYTEORDER==4321
memcpy(p,&v,4);
-#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
u32 x = __builtin_bswap32(v);
memcpy(p,&x,4);
-#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
u32 x = _byteswap_ulong(v);
memcpy(p,&x,4);
#else
@@ -33389,7 +33389,7 @@ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
char *zBlob;
int i;
- zBlob = (char *)sqlite3DbMallocRawNN(db, n/2 + 1);
+ zBlob = (char *)sqlite3DbMallocRawNN(db, n/2 + 1);
n--;
if( zBlob ){
for(i=0; i<n; i+=2){
@@ -33465,9 +33465,9 @@ SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
** overflow, leave *pA unchanged and return 1.
*/
SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
-#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
- return __builtin_add_overflow(*pA, iB, pA);
-#else
+#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
+ return __builtin_add_overflow(*pA, iB, pA);
+#else
i64 iA = *pA;
testcase( iA==0 ); testcase( iA==1 );
testcase( iB==-1 ); testcase( iB==0 );
@@ -33482,12 +33482,12 @@ SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
}
*pA += iB;
return 0;
-#endif
+#endif
}
SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
-#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
- return __builtin_sub_overflow(*pA, iB, pA);
-#else
+#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
+ return __builtin_sub_overflow(*pA, iB, pA);
+#else
testcase( iB==SMALLEST_INT64+1 );
if( iB==SMALLEST_INT64 ){
testcase( (*pA)==(-1) ); testcase( (*pA)==0 );
@@ -33497,28 +33497,28 @@ SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
}else{
return sqlite3AddInt64(pA, -iB);
}
-#endif
+#endif
}
SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){
-#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
- return __builtin_mul_overflow(*pA, iB, pA);
-#else
+#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
+ return __builtin_mul_overflow(*pA, iB, pA);
+#else
i64 iA = *pA;
- if( iB>0 ){
- if( iA>LARGEST_INT64/iB ) return 1;
- if( iA<SMALLEST_INT64/iB ) return 1;
- }else if( iB<0 ){
- if( iA>0 ){
- if( iB<SMALLEST_INT64/iA ) return 1;
- }else if( iA<0 ){
- if( iB==SMALLEST_INT64 ) return 1;
- if( iA==SMALLEST_INT64 ) return 1;
- if( -iA>LARGEST_INT64/-iB ) return 1;
- }
- }
- *pA = iA*iB;
+ if( iB>0 ){
+ if( iA>LARGEST_INT64/iB ) return 1;
+ if( iA<SMALLEST_INT64/iB ) return 1;
+ }else if( iB<0 ){
+ if( iA>0 ){
+ if( iB<SMALLEST_INT64/iA ) return 1;
+ }else if( iA<0 ){
+ if( iB==SMALLEST_INT64 ) return 1;
+ if( iA==SMALLEST_INT64 ) return 1;
+ if( -iA>LARGEST_INT64/-iB ) return 1;
+ }
+ }
+ *pA = iA*iB;
return 0;
-#endif
+#endif
}
/*
@@ -33602,14 +33602,14 @@ SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){
if( x<2 ) return 0;
while( x<8 ){ y -= 10; x <<= 1; }
}else{
-#if GCC_VERSION>=5004000
- int i = 60 - __builtin_clzll(x);
- y += i*10;
- x >>= i;
-#else
- while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/
+#if GCC_VERSION>=5004000
+ int i = 60 - __builtin_clzll(x);
+ y += i*10;
+ x >>= i;
+#else
+ while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/
while( x>15 ){ y += 10; x >>= 1; }
-#endif
+#endif
}
return a[x&7] + y - 10;
}
@@ -33631,14 +33631,14 @@ SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
-#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
+#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
defined(SQLITE_ENABLE_STAT4) || \
- defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
+ defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
/*
** Convert a LogEst into an integer.
-**
-** Note that this routine is only used when one or more of various
-** non-standard compile-time options is enabled.
+**
+** Note that this routine is only used when one or more of various
+** non-standard compile-time options is enabled.
*/
SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){
u64 n;
@@ -33646,121 +33646,121 @@ SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){
x /= 10;
if( n>=5 ) n -= 2;
else if( n>=1 ) n -= 1;
-#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
- defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
- if( x>60 ) return (u64)LARGEST_INT64;
-#else
+#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
+ defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
+ if( x>60 ) return (u64)LARGEST_INT64;
+#else
/* If only SQLITE_ENABLE_STAT4 is on, then the largest input
- ** possible to this routine is 310, resulting in a maximum x of 31 */
- assert( x<=60 );
-#endif
- return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
-}
-#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
-
-/*
-** Add a new name/number pair to a VList. This might require that the
-** VList object be reallocated, so return the new VList. If an OOM
-** error occurs, the original VList returned and the
-** db->mallocFailed flag is set.
-**
-** A VList is really just an array of integers. To destroy a VList,
-** simply pass it to sqlite3DbFree().
-**
-** The first integer is the number of integers allocated for the whole
-** VList. The second integer is the number of integers actually used.
-** Each name/number pair is encoded by subsequent groups of 3 or more
-** integers.
-**
-** Each name/number pair starts with two integers which are the numeric
-** value for the pair and the size of the name/number pair, respectively.
-** The text name overlays one or more following integers. The text name
-** is always zero-terminated.
-**
-** Conceptually:
-**
-** struct VList {
+ ** possible to this routine is 310, resulting in a maximum x of 31 */
+ assert( x<=60 );
+#endif
+ return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
+}
+#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
+
+/*
+** Add a new name/number pair to a VList. This might require that the
+** VList object be reallocated, so return the new VList. If an OOM
+** error occurs, the original VList returned and the
+** db->mallocFailed flag is set.
+**
+** A VList is really just an array of integers. To destroy a VList,
+** simply pass it to sqlite3DbFree().
+**
+** The first integer is the number of integers allocated for the whole
+** VList. The second integer is the number of integers actually used.
+** Each name/number pair is encoded by subsequent groups of 3 or more
+** integers.
+**
+** Each name/number pair starts with two integers which are the numeric
+** value for the pair and the size of the name/number pair, respectively.
+** The text name overlays one or more following integers. The text name
+** is always zero-terminated.
+**
+** Conceptually:
+**
+** struct VList {
** int nAlloc; // Number of allocated slots
** int nUsed; // Number of used slots
-** struct VListEntry {
-** int iValue; // Value for this entry
-** int nSlot; // Slots used by this entry
-** // ... variable name goes here
-** } a[0];
-** }
-**
-** During code generation, pointers to the variable names within the
+** struct VListEntry {
+** int iValue; // Value for this entry
+** int nSlot; // Slots used by this entry
+** // ... variable name goes here
+** } a[0];
+** }
+**
+** During code generation, pointers to the variable names within the
** VList are taken. When that happens, nAlloc is set to zero as an
-** indication that the VList may never again be enlarged, since the
-** accompanying realloc() would invalidate the pointers.
-*/
-SQLITE_PRIVATE VList *sqlite3VListAdd(
- sqlite3 *db, /* The database connection used for malloc() */
- VList *pIn, /* The input VList. Might be NULL */
- const char *zName, /* Name of symbol to add */
- int nName, /* Bytes of text in zName */
- int iVal /* Value to associate with zName */
-){
- int nInt; /* number of sizeof(int) objects needed for zName */
- char *z; /* Pointer to where zName will be stored */
- int i; /* Index in pIn[] where zName is stored */
-
- nInt = nName/4 + 3;
- assert( pIn==0 || pIn[0]>=3 ); /* Verify ok to add new elements */
- if( pIn==0 || pIn[1]+nInt > pIn[0] ){
- /* Enlarge the allocation */
+** indication that the VList may never again be enlarged, since the
+** accompanying realloc() would invalidate the pointers.
+*/
+SQLITE_PRIVATE VList *sqlite3VListAdd(
+ sqlite3 *db, /* The database connection used for malloc() */
+ VList *pIn, /* The input VList. Might be NULL */
+ const char *zName, /* Name of symbol to add */
+ int nName, /* Bytes of text in zName */
+ int iVal /* Value to associate with zName */
+){
+ int nInt; /* number of sizeof(int) objects needed for zName */
+ char *z; /* Pointer to where zName will be stored */
+ int i; /* Index in pIn[] where zName is stored */
+
+ nInt = nName/4 + 3;
+ assert( pIn==0 || pIn[0]>=3 ); /* Verify ok to add new elements */
+ if( pIn==0 || pIn[1]+nInt > pIn[0] ){
+ /* Enlarge the allocation */
sqlite3_int64 nAlloc = (pIn ? 2*(sqlite3_int64)pIn[0] : 10) + nInt;
- VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int));
- if( pOut==0 ) return pIn;
- if( pIn==0 ) pOut[1] = 2;
- pIn = pOut;
- pIn[0] = nAlloc;
- }
- i = pIn[1];
- pIn[i] = iVal;
- pIn[i+1] = nInt;
- z = (char*)&pIn[i+2];
- pIn[1] = i+nInt;
- assert( pIn[1]<=pIn[0] );
- memcpy(z, zName, nName);
- z[nName] = 0;
- return pIn;
-}
-
-/*
-** Return a pointer to the name of a variable in the given VList that
-** has the value iVal. Or return a NULL if there is no such variable in
-** the list
-*/
-SQLITE_PRIVATE const char *sqlite3VListNumToName(VList *pIn, int iVal){
- int i, mx;
- if( pIn==0 ) return 0;
- mx = pIn[1];
- i = 2;
- do{
- if( pIn[i]==iVal ) return (char*)&pIn[i+2];
- i += pIn[i+1];
- }while( i<mx );
- return 0;
-}
-
-/*
-** Return the number of the variable named zName, if it is in VList.
-** or return 0 if there is no such variable.
-*/
-SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nName){
- int i, mx;
- if( pIn==0 ) return 0;
- mx = pIn[1];
- i = 2;
- do{
- const char *z = (const char*)&pIn[i+2];
- if( strncmp(z,zName,nName)==0 && z[nName]==0 ) return pIn[i];
- i += pIn[i+1];
- }while( i<mx );
- return 0;
-}
-
+ VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int));
+ if( pOut==0 ) return pIn;
+ if( pIn==0 ) pOut[1] = 2;
+ pIn = pOut;
+ pIn[0] = nAlloc;
+ }
+ i = pIn[1];
+ pIn[i] = iVal;
+ pIn[i+1] = nInt;
+ z = (char*)&pIn[i+2];
+ pIn[1] = i+nInt;
+ assert( pIn[1]<=pIn[0] );
+ memcpy(z, zName, nName);
+ z[nName] = 0;
+ return pIn;
+}
+
+/*
+** Return a pointer to the name of a variable in the given VList that
+** has the value iVal. Or return a NULL if there is no such variable in
+** the list
+*/
+SQLITE_PRIVATE const char *sqlite3VListNumToName(VList *pIn, int iVal){
+ int i, mx;
+ if( pIn==0 ) return 0;
+ mx = pIn[1];
+ i = 2;
+ do{
+ if( pIn[i]==iVal ) return (char*)&pIn[i+2];
+ i += pIn[i+1];
+ }while( i<mx );
+ return 0;
+}
+
+/*
+** Return the number of the variable named zName, if it is in VList.
+** or return 0 if there is no such variable.
+*/
+SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nName){
+ int i, mx;
+ if( pIn==0 ) return 0;
+ mx = pIn[1];
+ i = 2;
+ do{
+ const char *z = (const char*)&pIn[i+2];
+ if( strncmp(z,zName,nName)==0 && z[nName]==0 ) return pIn[i];
+ i += pIn[i+1];
+ }while( i<mx );
+ return 0;
+}
+
/************** End of util.c ************************************************/
/************** Begin file hash.c ********************************************/
/*
@@ -33820,12 +33820,12 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){
static unsigned int strHash(const char *z){
unsigned int h = 0;
unsigned char c;
- while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/
- /* Knuth multiplicative hashing. (Sorting & Searching, p. 510).
- ** 0x9e3779b1 is 2654435761 which is the closest prime number to
- ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
- h += sqlite3UpperToLower[c];
- h *= 0x9e3779b1;
+ while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/
+ /* Knuth multiplicative hashing. (Sorting & Searching, p. 510).
+ ** 0x9e3779b1 is 2654435761 which is the closest prime number to
+ ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
+ h += sqlite3UpperToLower[c];
+ h *= 0x9e3779b1;
}
return h;
}
@@ -33905,9 +33905,9 @@ static int rehash(Hash *pH, unsigned int new_size){
}
/* This function (for internal use only) locates an element in an
-** hash table that matches the given key. If no element is found,
-** a pointer to a static null element with HashElem.data==0 is returned.
-** If pH is not NULL, then the hash for this key is written to *pH.
+** hash table that matches the given key. If no element is found,
+** a pointer to a static null element with HashElem.data==0 is returned.
+** If pH is not NULL, then the hash for this key is written to *pH.
*/
static HashElem *findElementWithHash(
const Hash *pH, /* The pH to be searched */
@@ -33917,9 +33917,9 @@ static HashElem *findElementWithHash(
HashElem *elem; /* Used to loop thru the element list */
unsigned int count; /* Number of elements left to test */
unsigned int h; /* The computed hash */
- static HashElem nullElement = { 0, 0, 0, 0 };
+ static HashElem nullElement = { 0, 0, 0, 0 };
- if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
+ if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
struct _ht *pEntry;
h = strHash(pKey) % pH->htsize;
pEntry = &pH->ht[h];
@@ -33930,7 +33930,7 @@ static HashElem *findElementWithHash(
elem = pH->first;
count = pH->count;
}
- if( pHash ) *pHash = h;
+ if( pHash ) *pHash = h;
while( count-- ){
assert( elem!=0 );
if( sqlite3StrICmp(elem->pKey,pKey)==0 ){
@@ -33938,7 +33938,7 @@ static HashElem *findElementWithHash(
}
elem = elem->next;
}
- return &nullElement;
+ return &nullElement;
}
/* Remove a single entry from the hash table given a pointer to that
@@ -33982,7 +33982,7 @@ static void removeElementGivenHash(
SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){
assert( pH!=0 );
assert( pKey!=0 );
- return findElementWithHash(pH, pKey, 0)->data;
+ return findElementWithHash(pH, pKey, 0)->data;
}
/* Insert an element into the hash table pH. The key is pKey
@@ -34007,7 +34007,7 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){
assert( pH!=0 );
assert( pKey!=0 );
elem = findElementWithHash(pH,pKey,&h);
- if( elem->data ){
+ if( elem->data ){
void *old_data = elem->data;
if( data==0 ){
removeElementGivenHash(pH,elem,h);
@@ -34036,21 +34036,21 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){
/************** End of hash.c ************************************************/
/************** Begin file opcodes.c *****************************************/
/* Automatically generated. Do not edit */
-/* See the tool/mkopcodec.tcl script for details. */
-#if !defined(SQLITE_OMIT_EXPLAIN) \
- || defined(VDBE_PROFILE) \
- || defined(SQLITE_DEBUG)
+/* See the tool/mkopcodec.tcl script for details. */
+#if !defined(SQLITE_OMIT_EXPLAIN) \
+ || defined(VDBE_PROFILE) \
+ || defined(SQLITE_DEBUG)
#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG)
# define OpHelp(X) "\0" X
#else
# define OpHelp(X)
#endif
SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
- static const char *const azName[] = {
- /* 0 */ "Savepoint" OpHelp(""),
- /* 1 */ "AutoCommit" OpHelp(""),
- /* 2 */ "Transaction" OpHelp(""),
- /* 3 */ "SorterNext" OpHelp(""),
+ static const char *const azName[] = {
+ /* 0 */ "Savepoint" OpHelp(""),
+ /* 1 */ "AutoCommit" OpHelp(""),
+ /* 2 */ "Transaction" OpHelp(""),
+ /* 3 */ "SorterNext" OpHelp(""),
/* 4 */ "Prev" OpHelp(""),
/* 5 */ "Next" OpHelp(""),
/* 6 */ "Checkpoint" OpHelp(""),
@@ -34066,7 +34066,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 16 */ "Jump" OpHelp(""),
/* 17 */ "Once" OpHelp(""),
/* 18 */ "If" OpHelp(""),
- /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
+ /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
/* 20 */ "IfNot" OpHelp(""),
/* 21 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"),
/* 22 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
@@ -34090,21 +34090,21 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"),
/* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"),
/* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"),
- /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
- /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
+ /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
+ /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
/* 45 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
/* 46 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
/* 47 */ "Program" OpHelp(""),
/* 48 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
/* 49 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
- /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
- /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
- /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
- /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
- /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
- /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
- /* 56 */ "Lt" OpHelp("IF r[P3]<r[P1]"),
- /* 57 */ "Ge" OpHelp("IF r[P3]>=r[P1]"),
+ /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
+ /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
+ /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
+ /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
+ /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
+ /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
+ /* 56 */ "Lt" OpHelp("IF r[P3]<r[P1]"),
+ /* 57 */ "Ge" OpHelp("IF r[P3]>=r[P1]"),
/* 58 */ "ElseEq" OpHelp(""),
/* 59 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
/* 60 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
@@ -34309,26 +34309,26 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
# endif
#endif
-/* Use pread() and pwrite() if they are available */
-#if defined(__APPLE__)
-# define HAVE_PREAD 1
-# define HAVE_PWRITE 1
-#endif
-#if defined(HAVE_PREAD64) && defined(HAVE_PWRITE64)
-# undef USE_PREAD
-# define USE_PREAD64 1
-#elif defined(HAVE_PREAD) && defined(HAVE_PWRITE)
-# undef USE_PREAD64
-# define USE_PREAD 1
-#endif
-
+/* Use pread() and pwrite() if they are available */
+#if defined(__APPLE__)
+# define HAVE_PREAD 1
+# define HAVE_PWRITE 1
+#endif
+#if defined(HAVE_PREAD64) && defined(HAVE_PWRITE64)
+# undef USE_PREAD
+# define USE_PREAD64 1
+#elif defined(HAVE_PREAD) && defined(HAVE_PWRITE)
+# undef USE_PREAD64
+# define USE_PREAD 1
+#endif
+
/*
** standard include files.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <sys/ioctl.h>
+#include <sys/ioctl.h>
#include <unistd.h>
/* #include <time.h> */
#include <sys/time.h>
@@ -34338,7 +34338,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
#endif
#if SQLITE_ENABLE_LOCKING_STYLE
-/* # include <sys/ioctl.h> */
+/* # include <sys/ioctl.h> */
# include <sys/file.h>
# include <sys/param.h>
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
@@ -34416,11 +34416,11 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
*/
#define MAX_PATHNAME 512
-/*
-** Maximum supported symbolic links
-*/
-#define SQLITE_MAX_SYMLINKS 100
-
+/*
+** Maximum supported symbolic links
+*/
+#define SQLITE_MAX_SYMLINKS 100
+
/* Always cast the getpid() return type for compatibility with
** kernel modules in VxWorks. */
#define osGetpid(X) (pid_t)getpid()
@@ -34463,7 +34463,7 @@ struct unixFile {
unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */
int lastErrno; /* The unix errno from last I/O error */
void *lockingContext; /* Locking style specific state */
- UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */
+ UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */
const char *zPath; /* Name of the file */
unixShm *pShm; /* Shared memory segment information */
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
@@ -34583,21 +34583,21 @@ static pid_t randomnessPid = 0;
# define lseek lseek64
#endif
-#ifdef __linux__
-/*
-** Linux-specific IOCTL magic numbers used for controlling F2FS
-*/
-#define F2FS_IOCTL_MAGIC 0xf5
-#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1)
-#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2)
-#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3)
-#define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5)
-#define F2FS_IOC_GET_FEATURES _IOR(F2FS_IOCTL_MAGIC, 12, u32)
-#define F2FS_FEATURE_ATOMIC_WRITE 0x0004
-#endif /* __linux__ */
-
-
-/*
+#ifdef __linux__
+/*
+** Linux-specific IOCTL magic numbers used for controlling F2FS
+*/
+#define F2FS_IOCTL_MAGIC 0xf5
+#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1)
+#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2)
+#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3)
+#define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5)
+#define F2FS_IOC_GET_FEATURES _IOR(F2FS_IOCTL_MAGIC, 12, u32)
+#define F2FS_FEATURE_ATOMIC_WRITE 0x0004
+#endif /* __linux__ */
+
+
+/*
** Different Unix systems declare open() in different ways. Same use
** open(const char*,int,mode_t). Others use open(const char*,int,...).
** The difference is important when using a pointer to the function.
@@ -34674,7 +34674,7 @@ static struct unix_syscall {
#else
{ "pread64", (sqlite3_syscall_ptr)0, 0 },
#endif
-#define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent)
+#define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent)
{ "write", (sqlite3_syscall_ptr)write, 0 },
#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
@@ -34692,10 +34692,10 @@ static struct unix_syscall {
#else
{ "pwrite64", (sqlite3_syscall_ptr)0, 0 },
#endif
-#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\
+#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\
aSyscall[13].pCurrent)
- { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
+ { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
@@ -34717,91 +34717,91 @@ static struct unix_syscall {
{ "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
-#if defined(HAVE_FCHOWN)
- { "fchown", (sqlite3_syscall_ptr)fchown, 0 },
-#else
- { "fchown", (sqlite3_syscall_ptr)0, 0 },
-#endif
+#if defined(HAVE_FCHOWN)
+ { "fchown", (sqlite3_syscall_ptr)fchown, 0 },
+#else
+ { "fchown", (sqlite3_syscall_ptr)0, 0 },
+#endif
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
#if defined(HAVE_FCHOWN)
- { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 },
+ { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 },
#else
{ "geteuid", (sqlite3_syscall_ptr)0, 0 },
#endif
-#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
-
+#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
+
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
- { "mmap", (sqlite3_syscall_ptr)mmap, 0 },
-#else
- { "mmap", (sqlite3_syscall_ptr)0, 0 },
-#endif
-#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent)
+ { "mmap", (sqlite3_syscall_ptr)mmap, 0 },
+#else
+ { "mmap", (sqlite3_syscall_ptr)0, 0 },
+#endif
+#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent)
-#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
{ "munmap", (sqlite3_syscall_ptr)munmap, 0 },
-#else
- { "munmap", (sqlite3_syscall_ptr)0, 0 },
-#endif
-#define osMunmap ((int(*)(void*,size_t))aSyscall[23].pCurrent)
+#else
+ { "munmap", (sqlite3_syscall_ptr)0, 0 },
+#endif
+#define osMunmap ((int(*)(void*,size_t))aSyscall[23].pCurrent)
-#if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
+#if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
#else
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
#endif
-#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent)
-
-#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent)
+
+#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
{ "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
-#else
- { "getpagesize", (sqlite3_syscall_ptr)0, 0 },
-#endif
-#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent)
-
-#if defined(HAVE_READLINK)
- { "readlink", (sqlite3_syscall_ptr)readlink, 0 },
-#else
- { "readlink", (sqlite3_syscall_ptr)0, 0 },
-#endif
-#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
-
-#if defined(HAVE_LSTAT)
- { "lstat", (sqlite3_syscall_ptr)lstat, 0 },
-#else
- { "lstat", (sqlite3_syscall_ptr)0, 0 },
-#endif
-#define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)
-
-#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+#else
+ { "getpagesize", (sqlite3_syscall_ptr)0, 0 },
+#endif
+#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent)
+
+#if defined(HAVE_READLINK)
+ { "readlink", (sqlite3_syscall_ptr)readlink, 0 },
+#else
+ { "readlink", (sqlite3_syscall_ptr)0, 0 },
+#endif
+#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
+
+#if defined(HAVE_LSTAT)
+ { "lstat", (sqlite3_syscall_ptr)lstat, 0 },
+#else
+ { "lstat", (sqlite3_syscall_ptr)0, 0 },
+#endif
+#define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)
+
+#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
# ifdef __ANDROID__
{ "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 },
#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent)
# else
- { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 },
+ { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 },
#define osIoctl ((int(*)(int,unsigned long,...))aSyscall[28].pCurrent)
# endif
-#else
- { "ioctl", (sqlite3_syscall_ptr)0, 0 },
-#endif
-
+#else
+ { "ioctl", (sqlite3_syscall_ptr)0, 0 },
+#endif
+
}; /* End of the overrideable system calls */
-
-/*
-** On some systems, calls to fchown() will trigger a message in a security
-** log if they come from non-root processes. So avoid calling fchown() if
-** we are not running as root.
-*/
-static int robustFchown(int fd, uid_t uid, gid_t gid){
-#if defined(HAVE_FCHOWN)
- return osGeteuid() ? 0 : osFchown(fd,uid,gid);
-#else
- return 0;
-#endif
-}
-
-/*
+
+/*
+** On some systems, calls to fchown() will trigger a message in a security
+** log if they come from non-root processes. So avoid calling fchown() if
+** we are not running as root.
+*/
+static int robustFchown(int fd, uid_t uid, gid_t gid){
+#if defined(HAVE_FCHOWN)
+ return osGeteuid() ? 0 : osFchown(fd,uid,gid);
+#else
+ return 0;
+#endif
+}
+
+/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "unix" VFSes. Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable
@@ -35101,8 +35101,8 @@ static int robust_ftruncate(int h, sqlite3_int64 sz){
static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
assert( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
(sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
- (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
- (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) );
+ (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
+ (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) );
switch (posixError) {
case EACCES:
case EAGAIN:
@@ -35360,14 +35360,14 @@ struct unixFileId {
#if OS_VXWORKS
struct vxworksFileId *pId; /* Unique file ID for vxworks. */
#else
- /* We are told that some versions of Android contain a bug that
- ** sizes ino_t at only 32-bits instead of 64-bits. (See
- ** https://android-review.googlesource.com/#/c/115351/3/dist/sqlite3.c)
+ /* We are told that some versions of Android contain a bug that
+ ** sizes ino_t at only 32-bits instead of 64-bits. (See
+ ** https://android-review.googlesource.com/#/c/115351/3/dist/sqlite3.c)
** To work around this, always allocate 64-bits for the inode number.
- ** On small machines that only have 32-bit inodes, this wastes 4 bytes,
- ** but that should not be a big deal. */
- /* WAS: ino_t ino; */
- u64 ino; /* Inode number */
+ ** On small machines that only have 32-bit inodes, this wastes 4 bytes,
+ ** but that should not be a big deal. */
+ /* WAS: ino_t ino; */
+ u64 ino; /* Inode number */
#endif
};
@@ -35422,7 +35422,7 @@ struct unixInodeInfo {
**
** Must hold unixBigLock in order to read or write this variable.
*/
-static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
+static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
#ifdef SQLITE_DEBUG
/*
@@ -35442,7 +35442,7 @@ int unixFileMutexNotheld(unixFile *pFile){
/*
**
-** This function - unixLogErrorAtLine(), is only ever called via the macro
+** This function - unixLogErrorAtLine(), is only ever called via the macro
** unixLogError().
**
** It is invoked after an error occurs in an OS function and errno has been
@@ -35615,7 +35615,7 @@ static int findInodeInfo(
rc = osFstat(fd, &statbuf);
if( rc!=0 ){
storeLastErrno(pFile, errno);
-#if defined(EOVERFLOW) && defined(SQLITE_DISABLE_LFS)
+#if defined(EOVERFLOW) && defined(SQLITE_DISABLE_LFS)
if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
#endif
return SQLITE_IOERR;
@@ -35651,7 +35651,7 @@ static int findInodeInfo(
#if OS_VXWORKS
fileId.pId = pFile->pId;
#else
- fileId.ino = (u64)statbuf.st_ino;
+ fileId.ino = (u64)statbuf.st_ino;
#endif
assert( unixMutexHeld() );
pInode = inodeList;
@@ -35661,7 +35661,7 @@ static int findInodeInfo(
if( pInode==0 ){
pInode = sqlite3_malloc64( sizeof(*pInode) );
if( pInode==0 ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
memset(pInode, 0, sizeof(*pInode));
memcpy(&pInode->fileId, &fileId, sizeof(fileId));
@@ -35695,7 +35695,7 @@ static int fileHasMoved(unixFile *pFile){
struct stat buf;
return pFile->pInode!=0 &&
(osStat(pFile->zPath, &buf)!=0
- || (u64)buf.st_ino!=pFile->pInode->fileId.ino);
+ || (u64)buf.st_ino!=pFile->pInode->fileId.ino);
#endif
}
@@ -35712,16 +35712,16 @@ static int fileHasMoved(unixFile *pFile){
static void verifyDbFile(unixFile *pFile){
struct stat buf;
int rc;
-
- /* These verifications occurs for the main database only */
- if( pFile->ctrlFlags & UNIXFILE_NOLOCK ) return;
-
+
+ /* These verifications occurs for the main database only */
+ if( pFile->ctrlFlags & UNIXFILE_NOLOCK ) return;
+
rc = osFstat(pFile->h, &buf);
if( rc!=0 ){
sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
return;
}
- if( buf.st_nlink==0 ){
+ if( buf.st_nlink==0 ){
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
return;
}
@@ -35750,7 +35750,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( pFile );
- assert( pFile->eFileLock<=SHARED_LOCK );
+ assert( pFile->eFileLock<=SHARED_LOCK );
sqlite3_mutex_enter(pFile->pInode->pLockMutex);
/* Check if a thread in this process holds such a lock */
@@ -35848,7 +35848,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
unixInodeInfo *pInode = pFile->pInode;
assert( pInode!=0 );
assert( sqlite3_mutex_held(pInode->pLockMutex) );
- if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){
+ if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){
if( pInode->bProcessLock==0 ){
struct flock lock;
assert( pInode->nLock==0 );
@@ -35898,7 +35898,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
** lock transitions in terms of the POSIX advisory shared and exclusive
** lock primitives (called read-locks and write-locks below, to avoid
** confusion with SQLite lock names). The algorithms are complicated
- ** slightly in order to be compatible with Windows95 systems simultaneously
+ ** slightly in order to be compatible with Windows95 systems simultaneously
** accessing the same database file, in case that is ever required.
**
** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
@@ -35906,14 +35906,14 @@ static int unixLock(sqlite3_file *id, int eFileLock){
** range', a range of 510 bytes at a well known offset.
**
** To obtain a SHARED lock, a read-lock is obtained on the 'pending
- ** byte'. If this is successful, 'shared byte range' is read-locked
- ** and the lock on the 'pending byte' released. (Legacy note: When
- ** SQLite was first developed, Windows95 systems were still very common,
- ** and Widnows95 lacks a shared-lock capability. So on Windows95, a
- ** single randomly selected by from the 'shared byte range' is locked.
- ** Windows95 is now pretty much extinct, but this work-around for the
- ** lack of shared-locks on Windows95 lives on, for backwards
- ** compatibility.)
+ ** byte'. If this is successful, 'shared byte range' is read-locked
+ ** and the lock on the 'pending byte' released. (Legacy note: When
+ ** SQLite was first developed, Windows95 systems were still very common,
+ ** and Widnows95 lacks a shared-lock capability. So on Windows95, a
+ ** single randomly selected by from the 'shared byte range' is locked.
+ ** Windows95 is now pretty much extinct, but this work-around for the
+ ** lack of shared-locks on Windows95 lives on, for backwards
+ ** compatibility.)
**
** A process may only obtain a RESERVED lock after it has a SHARED lock.
** A RESERVED lock is implemented by grabbing a write-lock on the
@@ -36122,12 +36122,12 @@ end_lock:
*/
static void setPendingFd(unixFile *pFile){
unixInodeInfo *pInode = pFile->pInode;
- UnixUnusedFd *p = pFile->pPreallocatedUnused;
+ UnixUnusedFd *p = pFile->pPreallocatedUnused;
assert( unixFileMutexHeld(pFile) );
p->pNext = pInode->pUnused;
pInode->pUnused = p;
pFile->h = -1;
- pFile->pPreallocatedUnused = 0;
+ pFile->pPreallocatedUnused = 0;
}
/*
@@ -36202,7 +36202,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
if( unixFileLock(pFile, &lock)==(-1) ){
tErrno = errno;
rc = SQLITE_IOERR_UNLOCK;
- storeLastErrno(pFile, tErrno);
+ storeLastErrno(pFile, tErrno);
goto end_unlock;
}
lock.l_type = F_RDLCK;
@@ -36224,7 +36224,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
if( unixFileLock(pFile, &lock)==(-1) ){
tErrno = errno;
rc = SQLITE_IOERR_UNLOCK;
- storeLastErrno(pFile, tErrno);
+ storeLastErrno(pFile, tErrno);
goto end_unlock;
}
}else
@@ -36352,7 +36352,7 @@ static int closeUnixFile(sqlite3_file *id){
#endif
OSTRACE(("CLOSE %-3d\n", pFile->h));
OpenCounter(-1);
- sqlite3_free(pFile->pPreallocatedUnused);
+ sqlite3_free(pFile->pPreallocatedUnused);
memset(pFile, 0, sizeof(unixFile));
return SQLITE_OK;
}
@@ -36482,7 +36482,7 @@ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( pFile );
- reserved = osAccess((const char*)pFile->lockingContext, 0)==0;
+ reserved = osAccess((const char*)pFile->lockingContext, 0)==0;
OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
*pResOut = reserved;
return rc;
@@ -36544,7 +36544,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) {
rc = SQLITE_BUSY;
} else {
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( rc!=SQLITE_BUSY ){
+ if( rc!=SQLITE_BUSY ){
storeLastErrno(pFile, tErrno);
}
}
@@ -36593,9 +36593,9 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
rc = osRmdir(zLockFile);
if( rc<0 ){
int tErrno = errno;
- if( tErrno==ENOENT ){
- rc = SQLITE_OK;
- }else{
+ if( tErrno==ENOENT ){
+ rc = SQLITE_OK;
+ }else{
rc = SQLITE_IOERR_UNLOCK;
storeLastErrno(pFile, tErrno);
}
@@ -36609,11 +36609,11 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
** Close a file. Make sure the lock has been released before closing.
*/
static int dotlockClose(sqlite3_file *id) {
- unixFile *pFile = (unixFile*)id;
- assert( id!=0 );
- dotlockUnlock(id, NO_LOCK);
- sqlite3_free(pFile->lockingContext);
- return closeUnixFile(id);
+ unixFile *pFile = (unixFile*)id;
+ assert( id!=0 );
+ dotlockUnlock(id, NO_LOCK);
+ sqlite3_free(pFile->lockingContext);
+ return closeUnixFile(id);
}
/****************** End of the dot-file lock implementation *******************
******************************************************************************/
@@ -36679,8 +36679,8 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
int tErrno = errno;
/* unlock failed with an error */
lrc = SQLITE_IOERR_UNLOCK;
- storeLastErrno(pFile, tErrno);
- rc = lrc;
+ storeLastErrno(pFile, tErrno);
+ rc = lrc;
}
} else {
int tErrno = errno;
@@ -36696,7 +36696,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved));
#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & 0xff) == SQLITE_IOERR ){
+ if( (rc & 0xff) == SQLITE_IOERR ){
rc = SQLITE_OK;
reserved=1;
}
@@ -36763,7 +36763,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) {
OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock),
rc==SQLITE_OK ? "ok" : "failed"));
#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & 0xff) == SQLITE_IOERR ){
+ if( (rc & 0xff) == SQLITE_IOERR ){
rc = SQLITE_BUSY;
}
#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
@@ -36813,9 +36813,9 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) {
** Close a file.
*/
static int flockClose(sqlite3_file *id) {
- assert( id!=0 );
- flockUnlock(id, NO_LOCK);
- return closeUnixFile(id);
+ assert( id!=0 );
+ flockUnlock(id, NO_LOCK);
+ return closeUnixFile(id);
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
@@ -37440,11 +37440,11 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
*/
static int afpClose(sqlite3_file *id) {
int rc = SQLITE_OK;
- unixFile *pFile = (unixFile*)id;
- assert( id!=0 );
- afpUnlock(id, NO_LOCK);
+ unixFile *pFile = (unixFile*)id;
+ assert( id!=0 );
+ afpUnlock(id, NO_LOCK);
assert( unixFileMutexNotheld(pFile) );
- unixEnterMutex();
+ unixEnterMutex();
if( pFile->pInode ){
unixInodeInfo *pInode = pFile->pInode;
sqlite3_mutex_enter(pInode->pLockMutex);
@@ -37458,10 +37458,10 @@ static int afpClose(sqlite3_file *id) {
}
sqlite3_mutex_leave(pInode->pLockMutex);
}
- releaseInodeInfo(pFile);
- sqlite3_free(pFile->lockingContext);
- rc = closeUnixFile(id);
- unixLeaveMutex();
+ releaseInodeInfo(pFile);
+ sqlite3_free(pFile->lockingContext);
+ rc = closeUnixFile(id);
+ unixLeaveMutex();
return rc;
}
@@ -37540,9 +37540,9 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
SimulateIOError( got = -1 );
#else
newOffset = lseek(id->h, offset, SEEK_SET);
- SimulateIOError( newOffset = -1 );
- if( newOffset<0 ){
- storeLastErrno((unixFile*)id, errno);
+ SimulateIOError( newOffset = -1 );
+ if( newOffset<0 ){
+ storeLastErrno((unixFile*)id, errno);
return -1;
}
got = osRead(id->h, pBuf, cnt);
@@ -37586,7 +37586,7 @@ static int unixRead(
/* If this is a database file (not a journal, super-journal or temp
** file), the bytes in the locking range should never be read or written. */
#if 0
- assert( pFile->pPreallocatedUnused==0
+ assert( pFile->pPreallocatedUnused==0
|| offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE
);
@@ -37658,7 +37658,7 @@ static int seekAndWriteFd(
assert( nBuf==(nBuf&0x1ffff) );
assert( fd>2 );
- assert( piErrno!=0 );
+ assert( piErrno!=0 );
nBuf &= 0x1ffff;
TIMER_START;
@@ -37669,10 +37669,10 @@ static int seekAndWriteFd(
#else
do{
i64 iSeek = lseek(fd, iOff, SEEK_SET);
- SimulateIOError( iSeek = -1 );
- if( iSeek<0 ){
- rc = -1;
- break;
+ SimulateIOError( iSeek = -1 );
+ if( iSeek<0 ){
+ rc = -1;
+ break;
}
rc = osWrite(fd, pBuf, nBuf);
}while( rc<0 && errno==EINTR );
@@ -37681,7 +37681,7 @@ static int seekAndWriteFd(
TIMER_END;
OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED));
- if( rc<0 ) *piErrno = errno;
+ if( rc<0 ) *piErrno = errno;
return rc;
}
@@ -37716,7 +37716,7 @@ static int unixWrite(
/* If this is a database file (not a journal, super-journal or temp
** file), the bytes in the locking range should never be read or written. */
#if 0
- assert( pFile->pPreallocatedUnused==0
+ assert( pFile->pPreallocatedUnused==0
|| offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE
);
@@ -37744,7 +37744,7 @@ static int unixWrite(
}
#endif
-#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0
+#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0
/* Deal with as much of this write request as possible by transfering
** data from the memory mapping using memcpy(). */
if( offset<pFile->mmapSize ){
@@ -37761,7 +37761,7 @@ static int unixWrite(
}
#endif
- while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))<amt && wrote>0 ){
+ while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))<amt && wrote>0 ){
amt -= wrote;
offset += wrote;
pBuf = &((char*)pBuf)[wrote];
@@ -37769,7 +37769,7 @@ static int unixWrite(
SimulateIOError(( wrote=(-1), amt=1 ));
SimulateDiskfullError(( wrote=0, amt=1 ));
- if( amt>wrote ){
+ if( amt>wrote ){
if( wrote<0 && pFile->lastErrno!=ENOSPC ){
/* lastErrno set by seekAndWrite */
return SQLITE_IOERR_WRITE;
@@ -37865,15 +37865,15 @@ static int full_fsync(int fd, int fullSync, int dataOnly){
#endif
/* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
- ** no-op. But go ahead and call fstat() to validate the file
- ** descriptor as we need a method to provoke a failure during
- ** coverate testing.
+ ** no-op. But go ahead and call fstat() to validate the file
+ ** descriptor as we need a method to provoke a failure during
+ ** coverate testing.
*/
#ifdef SQLITE_NO_SYNC
- {
- struct stat buf;
- rc = osFstat(fd, &buf);
- }
+ {
+ struct stat buf;
+ rc = osFstat(fd, &buf);
+ }
#elif HAVE_FULLFSYNC
if( fullSync ){
rc = osFcntl(fd, F_FULLFSYNC, 0);
@@ -37939,20 +37939,20 @@ static int openDirectory(const char *zFilename, int *pFd){
char zDirname[MAX_PATHNAME+1];
sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
- for(ii=(int)strlen(zDirname); ii>0 && zDirname[ii]!='/'; ii--);
+ for(ii=(int)strlen(zDirname); ii>0 && zDirname[ii]!='/'; ii--);
if( ii>0 ){
zDirname[ii] = '\0';
- }else{
- if( zDirname[0]!='/' ) zDirname[0] = '.';
- zDirname[1] = 0;
- }
- fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
- if( fd>=0 ){
- OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
- }
+ }else{
+ if( zDirname[0]!='/' ) zDirname[0] = '.';
+ zDirname[1] = 0;
+ }
+ fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
+ if( fd>=0 ){
+ OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
+ }
*pFd = fd;
- if( fd>=0 ) return SQLITE_OK;
- return unixLogError(SQLITE_CANTOPEN_BKPT, "openDirectory", zDirname);
+ if( fd>=0 ) return SQLITE_OK;
+ return unixLogError(SQLITE_CANTOPEN_BKPT, "openDirectory", zDirname);
}
/*
@@ -38005,11 +38005,11 @@ static int unixSync(sqlite3_file *id, int flags){
OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath,
HAVE_FULLFSYNC, isFullsync));
rc = osOpenDirectory(pFile->zPath, &dirfd);
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
full_fsync(dirfd, 0, 0);
robust_close(pFile, dirfd, __LINE__);
- }else{
- assert( rc==SQLITE_CANTOPEN );
+ }else{
+ assert( rc==SQLITE_CANTOPEN );
rc = SQLITE_OK;
}
pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
@@ -38141,11 +38141,11 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
int nWrite = 0; /* Number of bytes written by seekAndWrite */
i64 iWrite; /* Next offset to write to */
- iWrite = (buf.st_size/nBlk)*nBlk + nBlk - 1;
+ iWrite = (buf.st_size/nBlk)*nBlk + nBlk - 1;
assert( iWrite>=buf.st_size );
assert( ((iWrite+1)%nBlk)==0 );
- for(/*no-op*/; iWrite<nSize+nBlk-1; iWrite+=nBlk ){
- if( iWrite>=nSize ) iWrite = nSize - 1;
+ for(/*no-op*/; iWrite<nSize+nBlk-1; iWrite+=nBlk ){
+ if( iWrite>=nSize ) iWrite = nSize - 1;
nWrite = seekAndWrite(pFile, iWrite, "", 1);
if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
}
@@ -38199,21 +38199,21 @@ static int unixGetTempname(int nBuf, char *zBuf);
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
unixFile *pFile = (unixFile*)id;
switch( op ){
-#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
- case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: {
- int rc = osIoctl(pFile->h, F2FS_IOC_START_ATOMIC_WRITE);
- return rc ? SQLITE_IOERR_BEGIN_ATOMIC : SQLITE_OK;
- }
- case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: {
- int rc = osIoctl(pFile->h, F2FS_IOC_COMMIT_ATOMIC_WRITE);
- return rc ? SQLITE_IOERR_COMMIT_ATOMIC : SQLITE_OK;
- }
- case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: {
- int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE);
- return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK;
- }
-#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
-
+#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+ case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: {
+ int rc = osIoctl(pFile->h, F2FS_IOC_START_ATOMIC_WRITE);
+ return rc ? SQLITE_IOERR_BEGIN_ATOMIC : SQLITE_OK;
+ }
+ case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: {
+ int rc = osIoctl(pFile->h, F2FS_IOC_COMMIT_ATOMIC_WRITE);
+ return rc ? SQLITE_IOERR_COMMIT_ATOMIC : SQLITE_OK;
+ }
+ case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: {
+ int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE);
+ return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK;
+ }
+#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
+
case SQLITE_FCNTL_LOCKSTATE: {
*(int*)pArg = pFile->eFileLock;
return SQLITE_OK;
@@ -38272,14 +38272,14 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
if( newLimit>sqlite3GlobalConfig.mxMmap ){
newLimit = sqlite3GlobalConfig.mxMmap;
}
-
- /* The value of newLimit may be eventually cast to (size_t) and passed
- ** to mmap(). Restrict its value to 2GB if (size_t) is not at least a
- ** 64-bit type. */
- if( newLimit>0 && sizeof(size_t)<8 ){
- newLimit = (newLimit & 0x7FFFFFFF);
- }
-
+
+ /* The value of newLimit may be eventually cast to (size_t) and passed
+ ** to mmap(). Restrict its value to 2GB if (size_t) is not at least a
+ ** 64-bit type. */
+ if( newLimit>0 && sizeof(size_t)<8 ){
+ newLimit = (newLimit & 0x7FFFFFFF);
+ }
+
*(i64*)pArg = pFile->mmapSizeMax;
if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
pFile->mmapSizeMax = newLimit;
@@ -38322,41 +38322,41 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
/*
-** If pFd->sectorSize is non-zero when this function is called, it is a
+** If pFd->sectorSize is non-zero when this function is called, it is a
** no-op. Otherwise, the values of pFd->sectorSize and
** pFd->deviceCharacteristics are set according to the file-system
** characteristics.
**
-** There are two versions of this function. One for QNX and one for all
-** other systems.
-*/
-#ifndef __QNXNTO__
-static void setDeviceCharacteristics(unixFile *pFd){
- assert( pFd->deviceCharacteristics==0 || pFd->sectorSize!=0 );
- if( pFd->sectorSize==0 ){
-#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
- int res;
- u32 f = 0;
-
- /* Check for support for F2FS atomic batch writes. */
- res = osIoctl(pFd->h, F2FS_IOC_GET_FEATURES, &f);
- if( res==0 && (f & F2FS_FEATURE_ATOMIC_WRITE) ){
- pFd->deviceCharacteristics = SQLITE_IOCAP_BATCH_ATOMIC;
- }
-#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
-
- /* Set the POWERSAFE_OVERWRITE flag if requested. */
- if( pFd->ctrlFlags & UNIXFILE_PSOW ){
- pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
- }
-
- pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
- }
-}
-#else
+** There are two versions of this function. One for QNX and one for all
+** other systems.
+*/
+#ifndef __QNXNTO__
+static void setDeviceCharacteristics(unixFile *pFd){
+ assert( pFd->deviceCharacteristics==0 || pFd->sectorSize!=0 );
+ if( pFd->sectorSize==0 ){
+#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+ int res;
+ u32 f = 0;
+
+ /* Check for support for F2FS atomic batch writes. */
+ res = osIoctl(pFd->h, F2FS_IOC_GET_FEATURES, &f);
+ if( res==0 && (f & F2FS_FEATURE_ATOMIC_WRITE) ){
+ pFd->deviceCharacteristics = SQLITE_IOCAP_BATCH_ATOMIC;
+ }
+#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
+
+ /* Set the POWERSAFE_OVERWRITE flag if requested. */
+ if( pFd->ctrlFlags & UNIXFILE_PSOW ){
+ pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
+ }
+
+ pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
+ }
+}
+#else
#include <sys/dcmd_blk.h>
#include <sys/statvfs.h>
-static void setDeviceCharacteristics(unixFile *pFile){
+static void setDeviceCharacteristics(unixFile *pFile){
if( pFile->sectorSize == 0 ){
struct statvfs fsInfo;
@@ -38364,7 +38364,7 @@ static void setDeviceCharacteristics(unixFile *pFile){
pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
pFile->deviceCharacteristics = 0;
if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
- return;
+ return;
}
if( !strcmp(fsInfo.f_basetype, "tmp") ) {
@@ -38426,25 +38426,25 @@ static void setDeviceCharacteristics(unixFile *pFile){
pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
}
}
-#endif
-
-/*
-** Return the sector size in bytes of the underlying block device for
-** the specified file. This is almost always 512 bytes, but may be
-** larger for some devices.
-**
-** SQLite code assumes this function cannot fail. It also assumes that
-** if two files are created in the same file-system directory (i.e.
-** a database and its journal file) that the sector size will be the
-** same for both.
-*/
-static int unixSectorSize(sqlite3_file *id){
- unixFile *pFd = (unixFile*)id;
- setDeviceCharacteristics(pFd);
- return pFd->sectorSize;
-}
-
-/*
+#endif
+
+/*
+** Return the sector size in bytes of the underlying block device for
+** the specified file. This is almost always 512 bytes, but may be
+** larger for some devices.
+**
+** SQLite code assumes this function cannot fail. It also assumes that
+** if two files are created in the same file-system directory (i.e.
+** a database and its journal file) that the sector size will be the
+** same for both.
+*/
+static int unixSectorSize(sqlite3_file *id){
+ unixFile *pFd = (unixFile*)id;
+ setDeviceCharacteristics(pFd);
+ return pFd->sectorSize;
+}
+
+/*
** Return the device characteristics for the file.
**
** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
@@ -38458,9 +38458,9 @@ static int unixSectorSize(sqlite3_file *id){
** available to turn it off and URI query parameter available to turn it off.
*/
static int unixDeviceCharacteristics(sqlite3_file *id){
- unixFile *pFd = (unixFile*)id;
- setDeviceCharacteristics(pFd);
- return pFd->deviceCharacteristics;
+ unixFile *pFd = (unixFile*)id;
+ setDeviceCharacteristics(pFd);
+ return pFd->deviceCharacteristics;
}
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
@@ -38522,7 +38522,7 @@ struct unixShmNode {
int szRegion; /* Size of shared-memory regions */
u16 nRegion; /* Size of array apRegion */
u8 isReadonly; /* True if read-only */
- u8 isUnlocked; /* True if no DMS lock held */
+ u8 isUnlocked; /* True if no DMS lock held */
char **apRegion; /* Array of mapped shared-memory regions */
int nRef; /* Number of unixShm objects pointing to this */
unixShm *pFirst; /* All unixShm objects pointing to this */
@@ -38621,7 +38621,7 @@ static int unixShmSystemLock(
assert( n==1 || lockType!=F_RDLCK );
/* Locks are within range */
- assert( n>=1 && n<=SQLITE_SHM_NLOCK );
+ assert( n>=1 && n<=SQLITE_SHM_NLOCK );
if( pShmNode->hShm>=0 ){
int res;
@@ -38704,7 +38704,7 @@ static int unixShmRegionPerMap(void){
static void unixShmPurge(unixFile *pFd){
unixShmNode *p = pFd->pInode->pShmNode;
assert( unixMutexHeld() );
- if( p && ALWAYS(p->nRef==0) ){
+ if( p && ALWAYS(p->nRef==0) ){
int nShmPerMap = unixShmRegionPerMap();
int i;
assert( p->pInode==pFd->pInode );
@@ -38727,69 +38727,69 @@ static void unixShmPurge(unixFile *pFd){
}
/*
-** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
-** take it now. Return SQLITE_OK if successful, or an SQLite error
-** code otherwise.
-**
+** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
+** take it now. Return SQLITE_OK if successful, or an SQLite error
+** code otherwise.
+**
** If the DMS cannot be locked because this is a readonly_shm=1
-** connection and no other process already holds a lock, return
-** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
-*/
-static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
- struct flock lock;
- int rc = SQLITE_OK;
-
- /* Use F_GETLK to determine the locks other processes are holding
- ** on the DMS byte. If it indicates that another process is holding
- ** a SHARED lock, then this process may also take a SHARED lock
+** connection and no other process already holds a lock, return
+** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
+*/
+static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
+ struct flock lock;
+ int rc = SQLITE_OK;
+
+ /* Use F_GETLK to determine the locks other processes are holding
+ ** on the DMS byte. If it indicates that another process is holding
+ ** a SHARED lock, then this process may also take a SHARED lock
** and proceed with opening the *-shm file.
- **
- ** Or, if no other process is holding any lock, then this process
- ** is the first to open it. In this case take an EXCLUSIVE lock on the
- ** DMS byte and truncate the *-shm file to zero bytes in size. Then
- ** downgrade to a SHARED lock on the DMS byte.
- **
- ** If another process is holding an EXCLUSIVE lock on the DMS byte,
- ** return SQLITE_BUSY to the caller (it will try again). An earlier
- ** version of this code attempted the SHARED lock at this point. But
- ** this introduced a subtle race condition: if the process holding
- ** EXCLUSIVE failed just before truncating the *-shm file, then this
- ** process might open and use the *-shm file without truncating it.
- ** And if the *-shm file has been corrupted by a power failure or
- ** system crash, the database itself may also become corrupt. */
- lock.l_whence = SEEK_SET;
- lock.l_start = UNIX_SHM_DMS;
- lock.l_len = 1;
- lock.l_type = F_WRLCK;
+ **
+ ** Or, if no other process is holding any lock, then this process
+ ** is the first to open it. In this case take an EXCLUSIVE lock on the
+ ** DMS byte and truncate the *-shm file to zero bytes in size. Then
+ ** downgrade to a SHARED lock on the DMS byte.
+ **
+ ** If another process is holding an EXCLUSIVE lock on the DMS byte,
+ ** return SQLITE_BUSY to the caller (it will try again). An earlier
+ ** version of this code attempted the SHARED lock at this point. But
+ ** this introduced a subtle race condition: if the process holding
+ ** EXCLUSIVE failed just before truncating the *-shm file, then this
+ ** process might open and use the *-shm file without truncating it.
+ ** And if the *-shm file has been corrupted by a power failure or
+ ** system crash, the database itself may also become corrupt. */
+ lock.l_whence = SEEK_SET;
+ lock.l_start = UNIX_SHM_DMS;
+ lock.l_len = 1;
+ lock.l_type = F_WRLCK;
if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) {
- rc = SQLITE_IOERR_LOCK;
- }else if( lock.l_type==F_UNLCK ){
- if( pShmNode->isReadonly ){
- pShmNode->isUnlocked = 1;
- rc = SQLITE_READONLY_CANTINIT;
- }else{
- rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
+ rc = SQLITE_IOERR_LOCK;
+ }else if( lock.l_type==F_UNLCK ){
+ if( pShmNode->isReadonly ){
+ pShmNode->isUnlocked = 1;
+ rc = SQLITE_READONLY_CANTINIT;
+ }else{
+ rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
/* The first connection to attach must truncate the -shm file. We
** truncate to 3 bytes (an arbitrary small number, less than the
** -shm header size) rather than 0 as a system debugging aid, to
** help detect if a -shm file truncation is legitimate or is the work
** or a rogue process. */
if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){
- rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
- }
- }
- }else if( lock.l_type==F_WRLCK ){
- rc = SQLITE_BUSY;
- }
-
- if( rc==SQLITE_OK ){
- assert( lock.l_type==F_UNLCK || lock.l_type==F_RDLCK );
- rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
- }
- return rc;
-}
-
-/*
+ rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
+ }
+ }
+ }else if( lock.l_type==F_WRLCK ){
+ rc = SQLITE_BUSY;
+ }
+
+ if( rc==SQLITE_OK ){
+ assert( lock.l_type==F_UNLCK || lock.l_type==F_RDLCK );
+ rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
+ }
+ return rc;
+}
+
+/*
** Open a shared-memory area associated with open database file pDbFd.
** This particular implementation uses mmapped files.
**
@@ -38827,14 +38827,14 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
static int unixOpenSharedMemory(unixFile *pDbFd){
struct unixShm *p = 0; /* The connection to be opened */
struct unixShmNode *pShmNode; /* The underlying mmapped file */
- int rc = SQLITE_OK; /* Result code */
+ int rc = SQLITE_OK; /* Result code */
unixInodeInfo *pInode; /* The inode of fd */
- char *zShm; /* Name of the file used for SHM */
+ char *zShm; /* Name of the file used for SHM */
int nShmFilename; /* Size of the SHM filename in bytes */
/* Allocate space for the new unixShm object. */
p = sqlite3_malloc64( sizeof(*p) );
- if( p==0 ) return SQLITE_NOMEM_BKPT;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
memset(p, 0, sizeof(*p));
assert( pDbFd->pShm==0 );
@@ -38855,7 +38855,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** a new *-shm file is created, an attempt will be made to create it
** with the same permissions.
*/
- if( osFstat(pDbFd->h, &sStat) ){
+ if( osFstat(pDbFd->h, &sStat) ){
rc = SQLITE_IOERR_FSTAT;
goto shm_open_err;
}
@@ -38867,32 +38867,32 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
#endif
pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
if( pShmNode==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
- zShm = pShmNode->zFilename = (char*)&pShmNode[1];
+ zShm = pShmNode->zFilename = (char*)&pShmNode[1];
#ifdef SQLITE_SHM_DIRECTORY
sqlite3_snprintf(nShmFilename, zShm,
SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
(u32)sStat.st_ino, (u32)sStat.st_dev);
#else
- sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
- sqlite3FileSuffix3(pDbFd->zPath, zShm);
+ sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
+ sqlite3FileSuffix3(pDbFd->zPath, zShm);
#endif
pShmNode->hShm = -1;
pDbFd->pInode->pShmNode = pShmNode;
pShmNode->pInode = pDbFd->pInode;
- if( sqlite3GlobalConfig.bCoreMutex ){
+ if( sqlite3GlobalConfig.bCoreMutex ){
pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->pShmMutex==0 ){
- rc = SQLITE_NOMEM_BKPT;
- goto shm_open_err;
- }
+ rc = SQLITE_NOMEM_BKPT;
+ goto shm_open_err;
+ }
}
if( pInode->bProcessLock==0 ){
- if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
+ if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW,
(sStat.st_mode&0777));
}
@@ -38900,10 +38900,10 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
pShmNode->hShm = robust_open(zShm, O_RDONLY|O_NOFOLLOW,
(sStat.st_mode&0777));
if( pShmNode->hShm<0 ){
- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
- goto shm_open_err;
- }
- pShmNode->isReadonly = 1;
+ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
+ goto shm_open_err;
+ }
+ pShmNode->isReadonly = 1;
}
/* If this process is running as root, make sure that the SHM file
@@ -38911,9 +38911,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** the original owner will not be able to connect.
*/
robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid);
-
- rc = unixLockSharedMemory(pDbFd, pShmNode);
- if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
+
+ rc = unixLockSharedMemory(pDbFd, pShmNode);
+ if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
}
}
@@ -38937,7 +38937,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
p->pNext = pShmNode->pFirst;
pShmNode->pFirst = p;
sqlite3_mutex_leave(pShmNode->pShmMutex);
- return rc;
+ return rc;
/* Jump here on any error */
shm_open_err:
@@ -38989,11 +38989,11 @@ static int unixShmMap(
p = pDbFd->pShm;
pShmNode = p->pShmNode;
sqlite3_mutex_enter(pShmNode->pShmMutex);
- if( pShmNode->isUnlocked ){
- rc = unixLockSharedMemory(pDbFd, pShmNode);
- if( rc!=SQLITE_OK ) goto shmpage_out;
- pShmNode->isUnlocked = 0;
- }
+ if( pShmNode->isUnlocked ){
+ rc = unixLockSharedMemory(pDbFd, pShmNode);
+ if( rc!=SQLITE_OK ) goto shmpage_out;
+ pShmNode->isUnlocked = 0;
+ }
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
assert( pShmNode->pInode==pDbFd->pInode );
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
@@ -39041,7 +39041,7 @@ static int unixShmMap(
/* Write to the last byte of each newly allocated or extended page */
assert( (nByte % pgsz)==0 );
for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
- int x = 0;
+ int x = 0;
if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){
const char *zFile = pShmNode->zFilename;
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
@@ -39057,7 +39057,7 @@ static int unixShmMap(
pShmNode->apRegion, nReqRegion*sizeof(char *)
);
if( !apNew ){
- rc = SQLITE_IOERR_NOMEM_BKPT;
+ rc = SQLITE_IOERR_NOMEM_BKPT;
goto shmpage_out;
}
pShmNode->apRegion = apNew;
@@ -39077,7 +39077,7 @@ static int unixShmMap(
}else{
pMem = sqlite3_malloc64(nMap);
if( pMem==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto shmpage_out;
}
memset(pMem, 0, nMap);
@@ -39277,11 +39277,11 @@ static void unixShmBarrier(
sqlite3_file *fd /* Database file holding the shared memory */
){
UNUSED_PARAMETER(fd);
- sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
+ sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
assert( fd->pMethods->xLock==nolockLock
|| unixFileMutexNotheld((unixFile*)fd)
);
- unixEnterMutex(); /* Also mutex, for redundancy */
+ unixEnterMutex(); /* Also mutex, for redundancy */
unixLeaveMutex();
}
@@ -39392,9 +39392,9 @@ static void unixRemapfile(
assert( pFd->mmapSizeActual>=pFd->mmapSize );
assert( MAP_FAILED!=0 );
-#ifdef SQLITE_MMAP_READWRITE
+#ifdef SQLITE_MMAP_READWRITE
if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
-#endif
+#endif
if( pOrig ){
#if HAVE_MREMAP
@@ -39466,14 +39466,14 @@ static void unixRemapfile(
** recreated as a result of outstanding references) or an SQLite error
** code otherwise.
*/
-static int unixMapfile(unixFile *pFd, i64 nMap){
+static int unixMapfile(unixFile *pFd, i64 nMap){
assert( nMap>=0 || pFd->nFetchOut==0 );
- assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
+ assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
if( pFd->nFetchOut>0 ) return SQLITE_OK;
if( nMap<0 ){
struct stat statbuf; /* Low-level file information */
- if( osFstat(pFd->h, &statbuf) ){
+ if( osFstat(pFd->h, &statbuf) ){
return SQLITE_IOERR_FSTAT;
}
nMap = statbuf.st_size;
@@ -39482,9 +39482,9 @@ static int unixMapfile(unixFile *pFd, i64 nMap){
nMap = pFd->mmapSizeMax;
}
- assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
+ assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
if( nMap!=pFd->mmapSize ){
- unixRemapfile(pFd, nMap);
+ unixRemapfile(pFd, nMap);
}
return SQLITE_OK;
@@ -39900,7 +39900,7 @@ static int fillInUnixFile(
pNew->pId = vxworksFindFileId(zFilename);
if( pNew->pId==0 ){
ctrlFlags |= UNIXFILE_NOLOCK;
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
#endif
@@ -39956,7 +39956,7 @@ static int fillInUnixFile(
afpLockingContext *pCtx;
pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}else{
/* NB: zFilename exists and remains valid until the file is closed
** according to requirement F11141. So we do not need to make a
@@ -39986,7 +39986,7 @@ static int fillInUnixFile(
nFilename = (int)strlen(zFilename) + 6;
zLockFile = (char *)sqlite3_malloc64(nFilename);
if( zLockFile==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}else{
sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
}
@@ -40009,7 +40009,7 @@ static int fillInUnixFile(
if( zSemName[n]=='/' ) zSemName[n] = '_';
pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
if( pNew->pInode->pSem == SEM_FAILED ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
pNew->pInode->aSemName[0] = '\0';
}
}
@@ -40061,22 +40061,22 @@ static void unixTempFileInit(void){
** If no suitable temporary file directory can be found, return NULL.
*/
static const char *unixTempFileDir(void){
- unsigned int i = 0;
+ unsigned int i = 0;
struct stat buf;
- const char *zDir = sqlite3_temp_directory;
-
- while(1){
- if( zDir!=0
- && osStat(zDir, &buf)==0
- && S_ISDIR(buf.st_mode)
- && osAccess(zDir, 03)==0
- ){
- return zDir;
- }
+ const char *zDir = sqlite3_temp_directory;
+
+ while(1){
+ if( zDir!=0
+ && osStat(zDir, &buf)==0
+ && S_ISDIR(buf.st_mode)
+ && osAccess(zDir, 03)==0
+ ){
+ return zDir;
+ }
if( i>=sizeof(azTempDirs)/sizeof(azTempDirs[0]) ) break;
zDir = azTempDirs[i++];
}
- return 0;
+ return 0;
}
/*
@@ -40086,25 +40086,25 @@ static const char *unixTempFileDir(void){
*/
static int unixGetTempname(int nBuf, char *zBuf){
const char *zDir;
- int iLimit = 0;
+ int iLimit = 0;
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
** function failing.
*/
- zBuf[0] = 0;
+ zBuf[0] = 0;
SimulateIOError( return SQLITE_IOERR );
zDir = unixTempFileDir();
- if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH;
+ if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH;
do{
- u64 r;
- sqlite3_randomness(sizeof(r), &r);
- assert( nBuf>2 );
- zBuf[nBuf-2] = 0;
- sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c",
- zDir, r, 0);
- if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR;
+ u64 r;
+ sqlite3_randomness(sizeof(r), &r);
+ assert( nBuf>2 );
+ zBuf[nBuf-2] = 0;
+ sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c",
+ zDir, r, 0);
+ if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR;
}while( osAccess(zBuf,0)==0 );
return SQLITE_OK;
}
@@ -40145,8 +40145,8 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
#if !OS_VXWORKS
struct stat sStat; /* Results of stat() call */
- unixEnterMutex();
-
+ unixEnterMutex();
+
/* A stat() call may fail for various reasons. If this happens, it is
** almost certain that an open() call on the same path will also fail.
** For this reason, if an error occurs in the stat() call here, it is
@@ -40160,7 +40160,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
pInode = inodeList;
while( pInode && (pInode->fileId.dev!=sStat.st_dev
- || pInode->fileId.ino!=(u64)sStat.st_ino) ){
+ || pInode->fileId.ino!=(u64)sStat.st_ino) ){
pInode = pInode->pNext;
}
if( pInode ){
@@ -40176,33 +40176,33 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
sqlite3_mutex_leave(pInode->pLockMutex);
}
}
- unixLeaveMutex();
+ unixLeaveMutex();
#endif /* if !OS_VXWORKS */
return pUnused;
}
/*
** Find the mode, uid and gid of file zFile.
-*/
-static int getFileMode(
- const char *zFile, /* File name */
- mode_t *pMode, /* OUT: Permissions of zFile */
- uid_t *pUid, /* OUT: uid of zFile. */
- gid_t *pGid /* OUT: gid of zFile. */
-){
- struct stat sStat; /* Output of stat() on database file */
- int rc = SQLITE_OK;
- if( 0==osStat(zFile, &sStat) ){
- *pMode = sStat.st_mode & 0777;
- *pUid = sStat.st_uid;
- *pGid = sStat.st_gid;
- }else{
- rc = SQLITE_IOERR_FSTAT;
- }
- return rc;
-}
-
-/*
+*/
+static int getFileMode(
+ const char *zFile, /* File name */
+ mode_t *pMode, /* OUT: Permissions of zFile */
+ uid_t *pUid, /* OUT: uid of zFile. */
+ gid_t *pGid /* OUT: gid of zFile. */
+){
+ struct stat sStat; /* Output of stat() on database file */
+ int rc = SQLITE_OK;
+ if( 0==osStat(zFile, &sStat) ){
+ *pMode = sStat.st_mode & 0777;
+ *pUid = sStat.st_uid;
+ *pGid = sStat.st_gid;
+ }else{
+ rc = SQLITE_IOERR_FSTAT;
+ }
+ return rc;
+}
+
+/*
** This function is called by unixOpen() to determine the unix permissions
** to create new files with. If no error occurs, then SQLITE_OK is returned
** and a value suitable for passing as the third argument to open(2) is
@@ -40252,28 +40252,28 @@ static int findCreateFileMode(
*/
nDb = sqlite3Strlen30(zPath) - 1;
while( zPath[nDb]!='-' ){
- /* In normal operation, the journal file name will always contain
- ** a '-' character. However in 8+3 filename mode, or if a corrupt
+ /* In normal operation, the journal file name will always contain
+ ** a '-' character. However in 8+3 filename mode, or if a corrupt
** rollback journal specifies a super-journal with a goofy name, then
- ** the '-' might be missing. */
- if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
+ ** the '-' might be missing. */
+ if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
nDb--;
}
memcpy(zDb, zPath, nDb);
zDb[nDb] = '\0';
- rc = getFileMode(zDb, pMode, pUid, pGid);
+ rc = getFileMode(zDb, pMode, pUid, pGid);
}else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
*pMode = 0600;
- }else if( flags & SQLITE_OPEN_URI ){
- /* If this is a main database file and the file was opened using a URI
- ** filename, check for the "modeof" parameter. If present, interpret
- ** its value as a filename and try to copy the mode, uid and gid from
- ** that file. */
- const char *z = sqlite3_uri_parameter(zPath, "modeof");
- if( z ){
- rc = getFileMode(z, pMode, pUid, pGid);
- }
+ }else if( flags & SQLITE_OPEN_URI ){
+ /* If this is a main database file and the file was opened using a URI
+ ** filename, check for the "modeof" parameter. If present, interpret
+ ** its value as a filename and try to copy the mode, uid and gid from
+ ** that file. */
+ const char *z = sqlite3_uri_parameter(zPath, "modeof");
+ if( z ){
+ rc = getFileMode(z, pMode, pUid, pGid);
+ }
}
return rc;
}
@@ -40331,7 +40331,7 @@ static int unixOpen(
** a file-descriptor on the directory too. The first time unixSync()
** is called the directory file descriptor will be fsync()ed and close()d.
*/
- int isNewJrnl = (isCreate && (
+ int isNewJrnl = (isCreate && (
eType==SQLITE_OPEN_SUPER_JOURNAL
|| eType==SQLITE_OPEN_MAIN_JOURNAL
|| eType==SQLITE_OPEN_WAL
@@ -40393,10 +40393,10 @@ static int unixOpen(
}else{
pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
}
- p->pPreallocatedUnused = pUnused;
+ p->pPreallocatedUnused = pUnused;
/* Database filenames are double-zero terminated if they are not
** URIs with parameters. Hence, they can always be passed into
@@ -40405,8 +40405,8 @@ static int unixOpen(
}else if( !zName ){
/* If zName is NULL, the upper layer is requesting a temp file. */
- assert(isDelete && !isNewJrnl);
- rc = unixGetTempname(pVfs->mxPathname, zTmpname);
+ assert(isDelete && !isNewJrnl);
+ rc = unixGetTempname(pVfs->mxPathname, zTmpname);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -40433,31 +40433,31 @@ static int unixOpen(
gid_t gid; /* Groupid for the file */
rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid);
if( rc!=SQLITE_OK ){
- assert( !p->pPreallocatedUnused );
+ assert( !p->pPreallocatedUnused );
assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
return rc;
}
fd = robust_open(zName, openFlags, openMode);
OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
- assert( !isExclusive || (openFlags & O_CREAT)!=0 );
- if( fd<0 ){
- if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){
- /* If unable to create a journal because the directory is not
- ** writable, change the error code to indicate that. */
- rc = SQLITE_READONLY_DIRECTORY;
- }else if( errno!=EISDIR && isReadWrite ){
- /* Failed to open the file for read/write access. Try read-only. */
- flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
- openFlags &= ~(O_RDWR|O_CREAT);
- flags |= SQLITE_OPEN_READONLY;
- openFlags |= O_RDONLY;
- isReadonly = 1;
- fd = robust_open(zName, openFlags, openMode);
- }
+ assert( !isExclusive || (openFlags & O_CREAT)!=0 );
+ if( fd<0 ){
+ if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){
+ /* If unable to create a journal because the directory is not
+ ** writable, change the error code to indicate that. */
+ rc = SQLITE_READONLY_DIRECTORY;
+ }else if( errno!=EISDIR && isReadWrite ){
+ /* Failed to open the file for read/write access. Try read-only. */
+ flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
+ openFlags &= ~(O_RDWR|O_CREAT);
+ flags |= SQLITE_OPEN_READONLY;
+ openFlags |= O_RDONLY;
+ isReadonly = 1;
+ fd = robust_open(zName, openFlags, openMode);
+ }
}
if( fd<0 ){
- int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
- if( rc==SQLITE_OK ) rc = rc2;
+ int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
+ if( rc==SQLITE_OK ) rc = rc2;
goto open_finished;
}
@@ -40474,7 +40474,7 @@ static int unixOpen(
** in that case we do not want to attempt the chown().
*/
if( openMode && (flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL))!=0 ){
- robustFchown(fd, uid, gid);
+ robustFchown(fd, uid, gid);
}
}
assert( fd>=0 );
@@ -40482,8 +40482,8 @@ static int unixOpen(
*pOutFlags = flags;
}
- if( p->pPreallocatedUnused ){
- p->pPreallocatedUnused->fd = fd;
+ if( p->pPreallocatedUnused ){
+ p->pPreallocatedUnused->fd = fd;
p->pPreallocatedUnused->flags =
flags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE);
}
@@ -40495,7 +40495,7 @@ static int unixOpen(
zPath = sqlite3_mprintf("%s", zName);
if( zPath==0 ){
robust_close(p, fd, __LINE__);
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
#else
osUnlink(zName);
@@ -40524,9 +40524,9 @@ static int unixOpen(
/* Set up appropriate ctrlFlags */
if( isDelete ) ctrlFlags |= UNIXFILE_DELETE;
if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY;
- noLock = eType!=SQLITE_OPEN_MAIN_DB;
+ noLock = eType!=SQLITE_OPEN_MAIN_DB;
if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK;
- if( isNewJrnl ) ctrlFlags |= UNIXFILE_DIRSYNC;
+ if( isNewJrnl ) ctrlFlags |= UNIXFILE_DIRSYNC;
if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
#if SQLITE_ENABLE_LOCKING_STYLE
@@ -40564,12 +40564,12 @@ static int unixOpen(
assert( zPath==0 || zPath[0]=='/'
|| eType==SQLITE_OPEN_SUPER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL
- );
+ );
rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
open_finished:
if( rc!=SQLITE_OK ){
- sqlite3_free(p->pPreallocatedUnused);
+ sqlite3_free(p->pPreallocatedUnused);
}
return rc;
}
@@ -40604,12 +40604,12 @@ static int unixDelete(
int fd;
rc = osOpenDirectory(zPath, &fd);
if( rc==SQLITE_OK ){
- if( full_fsync(fd,0,0) ){
+ if( full_fsync(fd,0,0) ){
rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
}
robust_close(0, fd, __LINE__);
- }else{
- assert( rc==SQLITE_CANTOPEN );
+ }else{
+ assert( rc==SQLITE_CANTOPEN );
rc = SQLITE_OK;
}
}
@@ -40635,23 +40635,23 @@ static int unixAccess(
){
UNUSED_PARAMETER(NotUsed);
SimulateIOError( return SQLITE_IOERR_ACCESS; );
- assert( pResOut!=0 );
-
- /* The spec says there are three possible values for flags. But only
- ** two of them are actually used */
- assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE );
-
- if( flags==SQLITE_ACCESS_EXISTS ){
- struct stat buf;
+ assert( pResOut!=0 );
+
+ /* The spec says there are three possible values for flags. But only
+ ** two of them are actually used */
+ assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE );
+
+ if( flags==SQLITE_ACCESS_EXISTS ){
+ struct stat buf;
*pResOut = 0==osStat(zPath, &buf) &&
(!S_ISREG(buf.st_mode) || buf.st_size>0);
- }else{
- *pResOut = osAccess(zPath, W_OK|R_OK)==0;
+ }else{
+ *pResOut = osAccess(zPath, W_OK|R_OK)==0;
}
- return SQLITE_OK;
-}
-
-/*
+ return SQLITE_OK;
+}
+
+/*
** If the last component of the pathname in z[0]..z[j-1] is something
** other than ".." then back it out and return true. If the last
** component is empty or if it is ".." then return false.
@@ -40670,32 +40670,32 @@ static int unixBackupDir(const char *z, int *pJ){
/*
** Convert a relative pathname into a full pathname. Also
** simplify the pathname as follows:
-**
+**
** Remove all instances of /./
** Remove all isntances of /X/../ for any X
-*/
-static int mkFullPathname(
- const char *zPath, /* Input path */
- char *zOut, /* Output buffer */
- int nOut /* Allocated size of buffer zOut */
-){
- int nPath = sqlite3Strlen30(zPath);
- int iOff = 0;
+*/
+static int mkFullPathname(
+ const char *zPath, /* Input path */
+ char *zOut, /* Output buffer */
+ int nOut /* Allocated size of buffer zOut */
+){
+ int nPath = sqlite3Strlen30(zPath);
+ int iOff = 0;
int i, j;
- if( zPath[0]!='/' ){
- if( osGetcwd(zOut, nOut-2)==0 ){
- return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
+ if( zPath[0]!='/' ){
+ if( osGetcwd(zOut, nOut-2)==0 ){
+ return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
}
- iOff = sqlite3Strlen30(zOut);
- zOut[iOff++] = '/';
+ iOff = sqlite3Strlen30(zOut);
+ zOut[iOff++] = '/';
}
- if( (iOff+nPath+1)>nOut ){
- /* SQLite assumes that xFullPathname() nul-terminates the output buffer
- ** even if it returns an error. */
- zOut[iOff] = '\0';
- return SQLITE_CANTOPEN_BKPT;
- }
- sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);
+ if( (iOff+nPath+1)>nOut ){
+ /* SQLite assumes that xFullPathname() nul-terminates the output buffer
+ ** even if it returns an error. */
+ zOut[iOff] = '\0';
+ return SQLITE_CANTOPEN_BKPT;
+ }
+ sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);
/* Remove duplicate '/' characters. Except, two // at the beginning
** of a pathname is allowed since this is important on windows. */
@@ -40749,18 +40749,18 @@ static int unixFullPathname(
int nOut, /* Size of output buffer in bytes */
char *zOut /* Output buffer */
){
-#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT)
- return mkFullPathname(zPath, zOut, nOut);
-#else
- int rc = SQLITE_OK;
- int nByte;
+#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT)
+ return mkFullPathname(zPath, zOut, nOut);
+#else
+ int rc = SQLITE_OK;
+ int nByte;
int nLink = 0; /* Number of symbolic links followed so far */
- const char *zIn = zPath; /* Input path for each iteration of loop */
- char *zDel = 0;
+ const char *zIn = zPath; /* Input path for each iteration of loop */
+ char *zDel = 0;
+
+ assert( pVfs->mxPathname==MAX_PATHNAME );
+ UNUSED_PARAMETER(pVfs);
- assert( pVfs->mxPathname==MAX_PATHNAME );
- UNUSED_PARAMETER(pVfs);
-
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
** function failing. This function could fail if, for example, the
@@ -40768,64 +40768,64 @@ static int unixFullPathname(
*/
SimulateIOError( return SQLITE_ERROR );
- do {
-
- /* Call stat() on path zIn. Set bLink to true if the path is a symbolic
- ** link, or false otherwise. */
- int bLink = 0;
- struct stat buf;
- if( osLstat(zIn, &buf)!=0 ){
- if( errno!=ENOENT ){
- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
- }
- }else{
- bLink = S_ISLNK(buf.st_mode);
- }
-
- if( bLink ){
+ do {
+
+ /* Call stat() on path zIn. Set bLink to true if the path is a symbolic
+ ** link, or false otherwise. */
+ int bLink = 0;
+ struct stat buf;
+ if( osLstat(zIn, &buf)!=0 ){
+ if( errno!=ENOENT ){
+ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
+ }
+ }else{
+ bLink = S_ISLNK(buf.st_mode);
+ }
+
+ if( bLink ){
nLink++;
- if( zDel==0 ){
- zDel = sqlite3_malloc(nOut);
- if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
+ if( zDel==0 ){
+ zDel = sqlite3_malloc(nOut);
+ if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
}else if( nLink>=SQLITE_MAX_SYMLINKS ){
- rc = SQLITE_CANTOPEN_BKPT;
- }
-
- if( rc==SQLITE_OK ){
- nByte = osReadlink(zIn, zDel, nOut-1);
- if( nByte<0 ){
- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
- }else{
- if( zDel[0]!='/' ){
- int n;
- for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
- if( nByte+n+1>nOut ){
- rc = SQLITE_CANTOPEN_BKPT;
- }else{
- memmove(&zDel[n], zDel, nByte+1);
- memcpy(zDel, zIn, n);
- nByte += n;
- }
- }
- zDel[nByte] = '\0';
- }
- }
-
- zIn = zDel;
- }
-
- assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' );
- if( rc==SQLITE_OK && zIn!=zOut ){
- rc = mkFullPathname(zIn, zOut, nOut);
- }
- if( bLink==0 ) break;
- zIn = zOut;
- }while( rc==SQLITE_OK );
-
- sqlite3_free(zDel);
+ rc = SQLITE_CANTOPEN_BKPT;
+ }
+
+ if( rc==SQLITE_OK ){
+ nByte = osReadlink(zIn, zDel, nOut-1);
+ if( nByte<0 ){
+ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
+ }else{
+ if( zDel[0]!='/' ){
+ int n;
+ for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
+ if( nByte+n+1>nOut ){
+ rc = SQLITE_CANTOPEN_BKPT;
+ }else{
+ memmove(&zDel[n], zDel, nByte+1);
+ memcpy(zDel, zIn, n);
+ nByte += n;
+ }
+ }
+ zDel[nByte] = '\0';
+ }
+ }
+
+ zIn = zDel;
+ }
+
+ assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' );
+ if( rc==SQLITE_OK && zIn!=zOut ){
+ rc = mkFullPathname(zIn, zOut, nOut);
+ }
+ if( bLink==0 ) break;
+ zIn = zOut;
+ }while( rc==SQLITE_OK );
+
+ sqlite3_free(zDel);
if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK;
- return rc;
-#endif /* HAVE_READLINK && HAVE_LSTAT */
+ return rc;
+#endif /* HAVE_READLINK && HAVE_LSTAT */
}
@@ -40995,8 +40995,8 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
*piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
#else
struct timeval sNow;
- (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */
- *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
+ (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */
+ *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
#endif
#ifdef SQLITE_TEST
@@ -41008,7 +41008,7 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
return rc;
}
-#ifndef SQLITE_OMIT_DEPRECATED
+#ifndef SQLITE_OMIT_DEPRECATED
/*
** Find the current time (in Universal Coordinated Time). Write the
** current time and date as a Julian Day number into *prNow and
@@ -41022,21 +41022,21 @@ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
*prNow = i/86400000.0;
return rc;
}
-#else
-# define unixCurrentTime 0
-#endif
+#else
+# define unixCurrentTime 0
+#endif
/*
-** The xGetLastError() method is designed to return a better
-** low-level error message when operating-system problems come up
-** during SQLite operation. Only the integer return code is currently
-** used.
+** The xGetLastError() method is designed to return a better
+** low-level error message when operating-system problems come up
+** during SQLite operation. Only the integer return code is currently
+** used.
*/
static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
UNUSED_PARAMETER(NotUsed);
UNUSED_PARAMETER(NotUsed2);
UNUSED_PARAMETER(NotUsed3);
- return errno;
+ return errno;
}
@@ -41291,7 +41291,7 @@ static int proxyCreateLockPath(const char *lockPath){
}
buf[i] = lockPath[i];
}
- OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n",lockPath,osGetpid(0)));
+ OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n",lockPath,osGetpid(0)));
return 0;
}
@@ -41327,7 +41327,7 @@ static int proxyCreateUnixFile(
}else{
pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
}
if( fd<0 ){
@@ -41360,7 +41360,7 @@ static int proxyCreateUnixFile(
pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
if( pNew==NULL ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto end_create_proxy;
}
memset(pNew, 0, sizeof(unixFile));
@@ -41370,7 +41370,7 @@ static int proxyCreateUnixFile(
dummyVfs.zName = "dummy";
pUnused->fd = fd;
pUnused->flags = openFlags;
- pNew->pPreallocatedUnused = pUnused;
+ pNew->pPreallocatedUnused = pUnused;
rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0);
if( rc==SQLITE_OK ){
@@ -41703,7 +41703,7 @@ static int proxyTakeConch(unixFile *pFile){
writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]);
robust_ftruncate(conchFile->h, writeSize);
rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0);
- full_fsync(conchFile->h,0,0);
+ full_fsync(conchFile->h,0,0);
/* If we created a new conch file (not just updated the contents of a
** valid conch file), try to match the permissions of the database
*/
@@ -41773,7 +41773,7 @@ static int proxyTakeConch(unixFile *pFile){
if( tempLockPath ){
pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath);
if( !pCtx->lockProxyPath ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
}
}
@@ -41838,7 +41838,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
** the name of the original database file. */
*pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
if( conchPath==0 ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(conchPath, dbPath, len+1);
@@ -41954,7 +41954,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
memset(pCtx, 0, sizeof(*pCtx));
@@ -41990,7 +41990,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
if( rc==SQLITE_OK ){
pCtx->dbPath = sqlite3DbStrDup(0, dbPath);
if( pCtx->dbPath==NULL ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
}
if( rc==SQLITE_OK ){
@@ -42176,7 +42176,7 @@ static int proxyUnlock(sqlite3_file *id, int eFileLock) {
** Close a file that uses proxy locks.
*/
static int proxyClose(sqlite3_file *id) {
- if( ALWAYS(id) ){
+ if( ALWAYS(id) ){
unixFile *pFile = (unixFile*)id;
proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
unixFile *lockProxy = pCtx->lockProxy;
@@ -42320,7 +42320,7 @@ SQLITE_API int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==29 );
+ assert( ArraySize(aSyscall)==29 );
/* Register all VFSes defined in the aVfs[] array */
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
@@ -42446,10 +42446,10 @@ SQLITE_API int sqlite3_os_end(void){
# define NTDDI_WINBLUE 0x06030000
#endif
-#ifndef NTDDI_WINTHRESHOLD
-# define NTDDI_WINTHRESHOLD 0x06040000
-#endif
-
+#ifndef NTDDI_WINTHRESHOLD
+# define NTDDI_WINTHRESHOLD 0x06040000
+#endif
+
/*
** Check to see if the GetVersionEx[AW] functions are deprecated on the
** target system. GetVersionEx was first deprecated in Win8.1.
@@ -42463,19 +42463,19 @@ SQLITE_API int sqlite3_os_end(void){
#endif
/*
-** Check to see if the CreateFileMappingA function is supported on the
-** target system. It is unavailable when using "mincore.lib" on Win10.
-** When compiling for Windows 10, always assume "mincore.lib" is in use.
-*/
-#ifndef SQLITE_WIN32_CREATEFILEMAPPINGA
-# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD
-# define SQLITE_WIN32_CREATEFILEMAPPINGA 0
-# else
-# define SQLITE_WIN32_CREATEFILEMAPPINGA 1
-# endif
-#endif
-
-/*
+** Check to see if the CreateFileMappingA function is supported on the
+** target system. It is unavailable when using "mincore.lib" on Win10.
+** When compiling for Windows 10, always assume "mincore.lib" is in use.
+*/
+#ifndef SQLITE_WIN32_CREATEFILEMAPPINGA
+# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD
+# define SQLITE_WIN32_CREATEFILEMAPPINGA 0
+# else
+# define SQLITE_WIN32_CREATEFILEMAPPINGA 1
+# endif
+#endif
+
+/*
** This constant should already be defined (in the "WinDef.h" SDK file).
*/
#ifndef MAX_PATH
@@ -42660,17 +42660,17 @@ struct winFile {
};
/*
-** The winVfsAppData structure is used for the pAppData member for all of the
-** Win32 VFS variants.
-*/
-typedef struct winVfsAppData winVfsAppData;
-struct winVfsAppData {
- const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */
- void *pAppData; /* The extra pAppData, if any. */
- BOOL bNoLock; /* Non-zero if locking is disabled. */
-};
-
-/*
+** The winVfsAppData structure is used for the pAppData member for all of the
+** Win32 VFS variants.
+*/
+typedef struct winVfsAppData winVfsAppData;
+struct winVfsAppData {
+ const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */
+ void *pAppData; /* The extra pAppData, if any. */
+ BOOL bNoLock; /* Non-zero if locking is disabled. */
+};
+
+/*
** Allowed values for winFile.ctrlFlags
*/
#define WINFILE_RDONLY 0x02 /* Connection is read only */
@@ -42705,72 +42705,72 @@ struct winVfsAppData {
******************************************************************************
*/
#ifndef SQLITE_WIN32_HEAP_CREATE
-# define SQLITE_WIN32_HEAP_CREATE (TRUE)
-#endif
-
-/*
- * This is the maximum possible initial size of the Win32-specific heap, in
- * bytes.
- */
-#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE
-# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U)
-#endif
-
-/*
- * This is the extra space for the initial size of the Win32-specific heap,
- * in bytes. This value may be zero.
- */
-#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA
-# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304)
-#endif
-
-/*
- * Calculate the maximum legal cache size, in pages, based on the maximum
- * possible initial heap size and the default page size, setting aside the
- * needed extra space.
- */
-#ifndef SQLITE_WIN32_MAX_CACHE_SIZE
-# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \
- (SQLITE_WIN32_HEAP_INIT_EXTRA)) / \
- (SQLITE_DEFAULT_PAGE_SIZE))
-#endif
-
-/*
- * This is cache size used in the calculation of the initial size of the
- * Win32-specific heap. It cannot be negative.
- */
-#ifndef SQLITE_WIN32_CACHE_SIZE
-# if SQLITE_DEFAULT_CACHE_SIZE>=0
-# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
-# else
-# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
-# endif
-#endif
-
-/*
- * Make sure that the calculated cache size, in pages, cannot cause the
- * initial size of the Win32-specific heap to exceed the maximum amount
- * of memory that can be specified in the call to HeapCreate.
- */
-#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE
-# undef SQLITE_WIN32_CACHE_SIZE
-# define SQLITE_WIN32_CACHE_SIZE (2000)
-#endif
-
-/*
+# define SQLITE_WIN32_HEAP_CREATE (TRUE)
+#endif
+
+/*
+ * This is the maximum possible initial size of the Win32-specific heap, in
+ * bytes.
+ */
+#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE
+# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U)
+#endif
+
+/*
+ * This is the extra space for the initial size of the Win32-specific heap,
+ * in bytes. This value may be zero.
+ */
+#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA
+# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304)
+#endif
+
+/*
+ * Calculate the maximum legal cache size, in pages, based on the maximum
+ * possible initial heap size and the default page size, setting aside the
+ * needed extra space.
+ */
+#ifndef SQLITE_WIN32_MAX_CACHE_SIZE
+# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \
+ (SQLITE_WIN32_HEAP_INIT_EXTRA)) / \
+ (SQLITE_DEFAULT_PAGE_SIZE))
+#endif
+
+/*
+ * This is cache size used in the calculation of the initial size of the
+ * Win32-specific heap. It cannot be negative.
+ */
+#ifndef SQLITE_WIN32_CACHE_SIZE
+# if SQLITE_DEFAULT_CACHE_SIZE>=0
+# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
+# else
+# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
+# endif
+#endif
+
+/*
+ * Make sure that the calculated cache size, in pages, cannot cause the
+ * initial size of the Win32-specific heap to exceed the maximum amount
+ * of memory that can be specified in the call to HeapCreate.
+ */
+#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE
+# undef SQLITE_WIN32_CACHE_SIZE
+# define SQLITE_WIN32_CACHE_SIZE (2000)
+#endif
+
+/*
* The initial size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
-# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
- (SQLITE_DEFAULT_PAGE_SIZE) + \
- (SQLITE_WIN32_HEAP_INIT_EXTRA))
+# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
+ (SQLITE_DEFAULT_PAGE_SIZE) + \
+ (SQLITE_WIN32_HEAP_INIT_EXTRA))
#endif
/*
* The maximum size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_MAX_SIZE
-# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
+# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
#endif
/*
@@ -42778,7 +42778,7 @@ struct winVfsAppData {
* zero for the default behavior.
*/
#ifndef SQLITE_WIN32_HEAP_FLAGS
-# define SQLITE_WIN32_HEAP_FLAGS (0)
+# define SQLITE_WIN32_HEAP_FLAGS (0)
#endif
@@ -42925,9 +42925,9 @@ static struct win_syscall {
#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
- (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \
- SQLITE_WIN32_CREATEFILEMAPPINGA
+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
+ (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \
+ SQLITE_WIN32_CREATEFILEMAPPINGA
{ "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 },
#else
{ "CreateFileMappingA", (SYSCALL)0, 0 },
@@ -43157,7 +43157,7 @@ static struct win_syscall {
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
-#if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX
+#if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
#else
{ "GetVersionExA", (SYSCALL)0, 0 },
@@ -43167,7 +43167,7 @@ static struct win_syscall {
LPOSVERSIONINFOA))aSyscall[34].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
- SQLITE_WIN32_GETVERSIONEX
+ SQLITE_WIN32_GETVERSIONEX
{ "GetVersionExW", (SYSCALL)GetVersionExW, 0 },
#else
{ "GetVersionExW", (SYSCALL)0, 0 },
@@ -43618,7 +43618,7 @@ static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
** "pnLargest" argument, if non-zero, will be used to return the size of the
** largest committed free block in the heap, in bytes.
*/
-SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){
+SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){
int rc = SQLITE_OK;
UINT nLargest = 0;
HANDLE hHeap;
@@ -43636,7 +43636,7 @@ SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){
if( lastErrno==NO_ERROR ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
(void*)hHeap);
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}else{
sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
osGetLastError(), (void*)hHeap);
@@ -43658,12 +43658,12 @@ SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){
** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
** be returned and no changes will be made to the Win32 native heap.
*/
-SQLITE_API int sqlite3_win32_reset_heap(){
+SQLITE_API int sqlite3_win32_reset_heap(){
int rc;
MUTEX_LOGIC( sqlite3_mutex *pMainMtx; ) /* The main static mutex */
MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
MUTEX_LOGIC( pMainMtx = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); )
- MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
+ MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
sqlite3_mutex_enter(pMainMtx);
sqlite3_mutex_enter(pMem);
winMemAssertMagic();
@@ -43703,17 +43703,17 @@ SQLITE_API int sqlite3_win32_reset_heap(){
** (if available).
*/
-SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
+SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !zBuf ){
- (void)SQLITE_MISUSE_BKPT;
- return;
- }
-#endif
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !zBuf ){
+ (void)SQLITE_MISUSE_BKPT;
+ return;
+ }
+#endif
#if defined(SQLITE_WIN32_HAS_ANSI)
if( nMin>0 ){
memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
@@ -43749,7 +43749,7 @@ SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
static HANDLE sleepObj = NULL;
#endif
-SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
+SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
#if SQLITE_OS_WINRT
if ( sleepObj==NULL ){
sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
@@ -43784,7 +43784,7 @@ SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
** the LockFileEx() API.
*/
-#if !SQLITE_WIN32_GETVERSIONEX
+#if !SQLITE_WIN32_GETVERSIONEX
# define osIsNT() (1)
#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
# define osIsNT() (1)
@@ -43798,14 +43798,14 @@ SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
** This function determines if the machine is running a version of Windows
** based on the NT kernel.
*/
-SQLITE_API int sqlite3_win32_is_nt(void){
+SQLITE_API int sqlite3_win32_is_nt(void){
#if SQLITE_OS_WINRT
/*
** NOTE: The WinRT sub-platform is always assumed to be based on the NT
** kernel.
*/
return 1;
-#elif SQLITE_WIN32_GETVERSIONEX
+#elif SQLITE_WIN32_GETVERSIONEX
if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){
#if defined(SQLITE_WIN32_HAS_ANSI)
OSVERSIONINFOA sInfo;
@@ -43962,7 +43962,7 @@ static int winMemInit(void *pAppData){
"failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
dwMaximumSize);
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
pWinMemData->bOwned = TRUE;
assert( pWinMemData->bOwned );
@@ -43972,7 +43972,7 @@ static int winMemInit(void *pAppData){
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
"failed to GetProcessHeap (%lu)", osGetLastError());
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
pWinMemData->bOwned = FALSE;
assert( !pWinMemData->bOwned );
@@ -44039,247 +44039,247 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
#endif /* SQLITE_WIN32_MALLOC */
/*
-** Convert a UTF-8 string to Microsoft Unicode.
+** Convert a UTF-8 string to Microsoft Unicode.
**
-** Space to hold the returned string is obtained from sqlite3_malloc().
+** Space to hold the returned string is obtained from sqlite3_malloc().
*/
-static LPWSTR winUtf8ToUnicode(const char *zText){
+static LPWSTR winUtf8ToUnicode(const char *zText){
int nChar;
- LPWSTR zWideText;
+ LPWSTR zWideText;
- nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0);
+ nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0);
if( nChar==0 ){
return 0;
}
- zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) );
- if( zWideText==0 ){
+ zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) );
+ if( zWideText==0 ){
return 0;
}
- nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText,
+ nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText,
nChar);
if( nChar==0 ){
- sqlite3_free(zWideText);
- zWideText = 0;
+ sqlite3_free(zWideText);
+ zWideText = 0;
}
- return zWideText;
+ return zWideText;
}
/*
-** Convert a Microsoft Unicode string to UTF-8.
-**
-** Space to hold the returned string is obtained from sqlite3_malloc().
+** Convert a Microsoft Unicode string to UTF-8.
+**
+** Space to hold the returned string is obtained from sqlite3_malloc().
*/
-static char *winUnicodeToUtf8(LPCWSTR zWideText){
+static char *winUnicodeToUtf8(LPCWSTR zWideText){
int nByte;
- char *zText;
+ char *zText;
- nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0);
+ nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0);
if( nByte == 0 ){
return 0;
}
- zText = sqlite3MallocZero( nByte );
- if( zText==0 ){
+ zText = sqlite3MallocZero( nByte );
+ if( zText==0 ){
return 0;
}
- nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte,
+ nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte,
0, 0);
if( nByte == 0 ){
- sqlite3_free(zText);
- zText = 0;
+ sqlite3_free(zText);
+ zText = 0;
}
- return zText;
+ return zText;
}
/*
-** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM
-** code page.
+** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM
+** code page.
**
-** Space to hold the returned string is obtained from sqlite3_malloc().
+** Space to hold the returned string is obtained from sqlite3_malloc().
*/
-static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){
+static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){
int nByte;
- LPWSTR zMbcsText;
- int codepage = useAnsi ? CP_ACP : CP_OEMCP;
+ LPWSTR zMbcsText;
+ int codepage = useAnsi ? CP_ACP : CP_OEMCP;
- nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL,
+ nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL,
0)*sizeof(WCHAR);
if( nByte==0 ){
return 0;
}
- zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) );
- if( zMbcsText==0 ){
+ zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) );
+ if( zMbcsText==0 ){
return 0;
}
- nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText,
+ nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText,
nByte);
if( nByte==0 ){
- sqlite3_free(zMbcsText);
- zMbcsText = 0;
+ sqlite3_free(zMbcsText);
+ zMbcsText = 0;
}
- return zMbcsText;
+ return zMbcsText;
}
/*
-** Convert a Microsoft Unicode string to a multi-byte character string,
-** using the ANSI or OEM code page.
+** Convert a Microsoft Unicode string to a multi-byte character string,
+** using the ANSI or OEM code page.
**
-** Space to hold the returned string is obtained from sqlite3_malloc().
+** Space to hold the returned string is obtained from sqlite3_malloc().
*/
-static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){
+static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){
int nByte;
- char *zText;
- int codepage = useAnsi ? CP_ACP : CP_OEMCP;
+ char *zText;
+ int codepage = useAnsi ? CP_ACP : CP_OEMCP;
- nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0);
+ nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0);
if( nByte == 0 ){
return 0;
}
- zText = sqlite3MallocZero( nByte );
- if( zText==0 ){
+ zText = sqlite3MallocZero( nByte );
+ if( zText==0 ){
return 0;
}
- nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText,
+ nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText,
nByte, 0, 0);
if( nByte == 0 ){
- sqlite3_free(zText);
- zText = 0;
+ sqlite3_free(zText);
+ zText = 0;
}
- return zText;
+ return zText;
}
/*
-** Convert a multi-byte character string to UTF-8.
-**
-** Space to hold the returned string is obtained from sqlite3_malloc().
+** Convert a multi-byte character string to UTF-8.
+**
+** Space to hold the returned string is obtained from sqlite3_malloc().
*/
-static char *winMbcsToUtf8(const char *zText, int useAnsi){
- char *zTextUtf8;
+static char *winMbcsToUtf8(const char *zText, int useAnsi){
+ char *zTextUtf8;
LPWSTR zTmpWide;
- zTmpWide = winMbcsToUnicode(zText, useAnsi);
+ zTmpWide = winMbcsToUnicode(zText, useAnsi);
if( zTmpWide==0 ){
return 0;
}
- zTextUtf8 = winUnicodeToUtf8(zTmpWide);
+ zTextUtf8 = winUnicodeToUtf8(zTmpWide);
sqlite3_free(zTmpWide);
- return zTextUtf8;
+ return zTextUtf8;
}
/*
-** Convert a UTF-8 string to a multi-byte character string.
-**
-** Space to hold the returned string is obtained from sqlite3_malloc().
+** Convert a UTF-8 string to a multi-byte character string.
+**
+** Space to hold the returned string is obtained from sqlite3_malloc().
*/
-static char *winUtf8ToMbcs(const char *zText, int useAnsi){
- char *zTextMbcs;
+static char *winUtf8ToMbcs(const char *zText, int useAnsi){
+ char *zTextMbcs;
LPWSTR zTmpWide;
- zTmpWide = winUtf8ToUnicode(zText);
+ zTmpWide = winUtf8ToUnicode(zText);
if( zTmpWide==0 ){
return 0;
}
- zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi);
+ zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi);
sqlite3_free(zTmpWide);
- return zTextMbcs;
-}
-
-/*
-** This is a public wrapper for the winUtf8ToUnicode() function.
-*/
-SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !zText ){
- (void)SQLITE_MISUSE_BKPT;
- return 0;
- }
-#endif
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return winUtf8ToUnicode(zText);
-}
-
-/*
-** This is a public wrapper for the winUnicodeToUtf8() function.
-*/
-SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !zWideText ){
- (void)SQLITE_MISUSE_BKPT;
- return 0;
- }
-#endif
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return winUnicodeToUtf8(zWideText);
-}
-
-/*
-** This is a public wrapper for the winMbcsToUtf8() function.
-*/
-SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !zText ){
- (void)SQLITE_MISUSE_BKPT;
- return 0;
- }
-#endif
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return winMbcsToUtf8(zText, osAreFileApisANSI());
-}
-
-/*
-** This is a public wrapper for the winMbcsToUtf8() function.
-*/
-SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !zText ){
- (void)SQLITE_MISUSE_BKPT;
- return 0;
- }
-#endif
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return winMbcsToUtf8(zText, useAnsi);
-}
-
-/*
-** This is a public wrapper for the winUtf8ToMbcs() function.
-*/
-SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zText){
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !zText ){
- (void)SQLITE_MISUSE_BKPT;
- return 0;
- }
-#endif
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return winUtf8ToMbcs(zText, osAreFileApisANSI());
-}
-
-/*
-** This is a public wrapper for the winUtf8ToMbcs() function.
-*/
-SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !zText ){
- (void)SQLITE_MISUSE_BKPT;
- return 0;
- }
-#endif
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return winUtf8ToMbcs(zText, useAnsi);
-}
-
-/*
+ return zTextMbcs;
+}
+
+/*
+** This is a public wrapper for the winUtf8ToUnicode() function.
+*/
+SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !zText ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+ if( sqlite3_initialize() ) return 0;
+#endif
+ return winUtf8ToUnicode(zText);
+}
+
+/*
+** This is a public wrapper for the winUnicodeToUtf8() function.
+*/
+SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !zWideText ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+ if( sqlite3_initialize() ) return 0;
+#endif
+ return winUnicodeToUtf8(zWideText);
+}
+
+/*
+** This is a public wrapper for the winMbcsToUtf8() function.
+*/
+SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !zText ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+ if( sqlite3_initialize() ) return 0;
+#endif
+ return winMbcsToUtf8(zText, osAreFileApisANSI());
+}
+
+/*
+** This is a public wrapper for the winMbcsToUtf8() function.
+*/
+SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !zText ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+ if( sqlite3_initialize() ) return 0;
+#endif
+ return winMbcsToUtf8(zText, useAnsi);
+}
+
+/*
+** This is a public wrapper for the winUtf8ToMbcs() function.
+*/
+SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zText){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !zText ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+ if( sqlite3_initialize() ) return 0;
+#endif
+ return winUtf8ToMbcs(zText, osAreFileApisANSI());
+}
+
+/*
+** This is a public wrapper for the winUtf8ToMbcs() function.
+*/
+SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !zText ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+ if( sqlite3_initialize() ) return 0;
+#endif
+ return winUtf8ToMbcs(zText, useAnsi);
+}
+
+/*
** This function is the same as sqlite3_win32_set_directory (below); however,
** it accepts a UTF-8 string.
*/
@@ -44306,7 +44306,7 @@ SQLITE_API int sqlite3_win32_set_directory8(
if( zValue && zValue[0] ){
zCopy = sqlite3_mprintf("%s", zValue);
if ( zCopy==0 ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
}
sqlite3_free(*ppDirectory);
@@ -44411,7 +44411,7 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
sqlite3BeginBenignMalloc();
- zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
+ zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
sqlite3EndBenignMalloc();
/* free the system buffer allocated by FormatMessage */
osLocalFree(zTemp);
@@ -44553,17 +44553,17 @@ static void winLogIoerr(int nRetry, int lineno){
}
}
-/*
-** This #if does not rely on the SQLITE_OS_WINCE define because the
-** corresponding section in "date.c" cannot use it.
+/*
+** This #if does not rely on the SQLITE_OS_WINCE define because the
+** corresponding section in "date.c" cannot use it.
*/
-#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
- (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
+#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
+ (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
/*
-** The MSVC CRT on Windows CE may not have a localtime() function.
-** So define a substitute.
+** The MSVC CRT on Windows CE may not have a localtime() function.
+** So define a substitute.
*/
-/* # include <time.h> */
+/* # include <time.h> */
struct tm *__cdecl localtime(const time_t *t)
{
static struct tm y;
@@ -44587,10 +44587,10 @@ struct tm *__cdecl localtime(const time_t *t)
}
#endif
-#if SQLITE_OS_WINCE
-/*************************************************************************
-** This section contains code for WinCE only.
-*/
+#if SQLITE_OS_WINCE
+/*************************************************************************
+** This section contains code for WinCE only.
+*/
#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
/*
@@ -44621,7 +44621,7 @@ static int winceCreateLock(const char *zFilename, winFile *pFile){
zName = winUtf8ToUnicode(zFilename);
if( zName==0 ){
/* out of memory */
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
/* Initialize the local lockdata */
@@ -45046,12 +45046,12 @@ static int winClose(sqlite3_file *id){
}while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
#if SQLITE_OS_WINCE
#define WINCE_DELETION_ATTEMPTS 3
- {
- winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData;
- if( pAppData==NULL || !pAppData->bNoLock ){
- winceDestroyLock(pFile);
- }
- }
+ {
+ winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData;
+ if( pAppData==NULL || !pAppData->bNoLock ){
+ winceDestroyLock(pFile);
+ }
+ }
if( pFile->zDeleteOnClose ){
int cnt = 0;
while(
@@ -45179,7 +45179,7 @@ static int winWrite(
"offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
pFile->h, pBuf, amt, offset, pFile->locktype));
-#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0
+#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0
/* Deal with as much of this write request as possible by transfering
** data from the memory mapping using memcpy(). */
if( offset<pFile->mmapSize ){
@@ -45641,8 +45641,8 @@ static int winLock(sqlite3_file *id, int locktype){
** the PENDING_LOCK byte is temporary.
*/
newLocktype = pFile->locktype;
- if( pFile->locktype==NO_LOCK
- || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK)
+ if( pFile->locktype==NO_LOCK
+ || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK)
){
int cnt = 3;
while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
@@ -45758,7 +45758,7 @@ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
res = 1;
OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res));
}else{
- res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE,0,1,0);
+ res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE,0,1,0);
if( res ){
winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
}
@@ -45815,44 +45815,44 @@ static int winUnlock(sqlite3_file *id, int locktype){
return rc;
}
-/******************************************************************************
-****************************** No-op Locking **********************************
-**
-** Of the various locking implementations available, this is by far the
-** simplest: locking is ignored. No attempt is made to lock the database
-** file for reading or writing.
-**
-** This locking mode is appropriate for use on read-only databases
-** (ex: databases that are burned into CD-ROM, for example.) It can
-** also be used if the application employs some external mechanism to
-** prevent simultaneous access of the same database by two or more
-** database connections. But there is a serious risk of database
-** corruption if this locking mode is used in situations where multiple
-** database connections are accessing the same database file at the same
-** time and one or more of those connections are writing.
-*/
-
-static int winNolockLock(sqlite3_file *id, int locktype){
- UNUSED_PARAMETER(id);
- UNUSED_PARAMETER(locktype);
- return SQLITE_OK;
-}
-
-static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){
- UNUSED_PARAMETER(id);
- UNUSED_PARAMETER(pResOut);
- return SQLITE_OK;
-}
-
-static int winNolockUnlock(sqlite3_file *id, int locktype){
- UNUSED_PARAMETER(id);
- UNUSED_PARAMETER(locktype);
- return SQLITE_OK;
-}
-
-/******************* End of the no-op lock implementation *********************
-******************************************************************************/
-
+/******************************************************************************
+****************************** No-op Locking **********************************
+**
+** Of the various locking implementations available, this is by far the
+** simplest: locking is ignored. No attempt is made to lock the database
+** file for reading or writing.
+**
+** This locking mode is appropriate for use on read-only databases
+** (ex: databases that are burned into CD-ROM, for example.) It can
+** also be used if the application employs some external mechanism to
+** prevent simultaneous access of the same database by two or more
+** database connections. But there is a serious risk of database
+** corruption if this locking mode is used in situations where multiple
+** database connections are accessing the same database file at the same
+** time and one or more of those connections are writing.
+*/
+
+static int winNolockLock(sqlite3_file *id, int locktype){
+ UNUSED_PARAMETER(id);
+ UNUSED_PARAMETER(locktype);
+ return SQLITE_OK;
+}
+
+static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){
+ UNUSED_PARAMETER(id);
+ UNUSED_PARAMETER(pResOut);
+ return SQLITE_OK;
+}
+
+static int winNolockUnlock(sqlite3_file *id, int locktype){
+ UNUSED_PARAMETER(id);
+ UNUSED_PARAMETER(locktype);
+ return SQLITE_OK;
+}
+
+/******************* End of the no-op lock implementation *********************
+******************************************************************************/
+
/*
** If *pArg is initially negative then this is a query. Set *pArg to
** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
@@ -45887,7 +45887,7 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
- case SQLITE_FCNTL_LAST_ERRNO: {
+ case SQLITE_FCNTL_LAST_ERRNO: {
*(int*)pArg = (int)pFile->lastErrno;
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
@@ -45945,12 +45945,12 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
- case SQLITE_FCNTL_WIN32_GET_HANDLE: {
- LPHANDLE phFile = (LPHANDLE)pArg;
- *phFile = pFile->h;
- OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
- return SQLITE_OK;
- }
+ case SQLITE_FCNTL_WIN32_GET_HANDLE: {
+ LPHANDLE phFile = (LPHANDLE)pArg;
+ *phFile = pFile->h;
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+ return SQLITE_OK;
+ }
#ifdef SQLITE_TEST
case SQLITE_FCNTL_WIN32_SET_HANDLE: {
LPHANDLE phFile = (LPHANDLE)pArg;
@@ -45978,14 +45978,14 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
if( newLimit>sqlite3GlobalConfig.mxMmap ){
newLimit = sqlite3GlobalConfig.mxMmap;
}
-
- /* The value of newLimit may be eventually cast to (SIZE_T) and passed
- ** to MapViewOfFile(). Restrict its value to 2GB if (SIZE_T) is not at
- ** least a 64-bit type. */
- if( newLimit>0 && sizeof(SIZE_T)<8 ){
- newLimit = (newLimit & 0x7FFFFFFF);
- }
-
+
+ /* The value of newLimit may be eventually cast to (SIZE_T) and passed
+ ** to MapViewOfFile(). Restrict its value to 2GB if (SIZE_T) is not at
+ ** least a 64-bit type. */
+ if( newLimit>0 && sizeof(SIZE_T)<8 ){
+ newLimit = (newLimit & 0x7FFFFFFF);
+ }
+
*(i64*)pArg = pFile->mmapSizeMax;
if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
pFile->mmapSizeMax = newLimit;
@@ -46093,9 +46093,9 @@ struct winShmNode {
int szRegion; /* Size of shared-memory regions */
int nRegion; /* Size of array apRegion */
- u8 isReadonly; /* True if read-only */
- u8 isUnlocked; /* True if no DMS lock held */
-
+ u8 isReadonly; /* True if read-only */
+ u8 isUnlocked; /* True if no DMS lock held */
+
struct ShmRegion {
HANDLE hMap; /* File handle from CreateFileMapping */
void *pMap;
@@ -46150,30 +46150,30 @@ struct winShm {
/*
** Apply advisory locks for all n bytes beginning at ofst.
*/
-#define WINSHM_UNLCK 1
-#define WINSHM_RDLCK 2
-#define WINSHM_WRLCK 3
+#define WINSHM_UNLCK 1
+#define WINSHM_RDLCK 2
+#define WINSHM_WRLCK 3
static int winShmSystemLock(
winShmNode *pFile, /* Apply locks to this open shared-memory segment */
- int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */
+ int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */
int ofst, /* Offset to first byte to be locked/unlocked */
int nByte /* Number of bytes to lock or unlock */
){
int rc = 0; /* Result code form Lock/UnlockFileEx() */
/* Access to the winShmNode object is serialized by the caller */
- assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) );
+ assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) );
OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
pFile->hFile.h, lockType, ofst, nByte));
/* Release/Acquire the system-level lock */
- if( lockType==WINSHM_UNLCK ){
+ if( lockType==WINSHM_UNLCK ){
rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
}else{
/* Initialize the locking parameters */
DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
- if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
+ if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
}
@@ -46185,7 +46185,7 @@ static int winShmSystemLock(
}
OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n",
- pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" :
+ pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" :
"winLockFile", pFile->lastErrno, sqlite3ErrName(rc)));
return rc;
@@ -46244,37 +46244,37 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
}
/*
-** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
-** take it now. Return SQLITE_OK if successful, or an SQLite error
-** code otherwise.
-**
-** If the DMS cannot be locked because this is a readonly_shm=1
-** connection and no other process already holds a lock, return
-** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
-*/
-static int winLockSharedMemory(winShmNode *pShmNode){
- int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1);
-
- if( rc==SQLITE_OK ){
- if( pShmNode->isReadonly ){
- pShmNode->isUnlocked = 1;
- winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
- return SQLITE_READONLY_CANTINIT;
- }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){
- winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
- return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
- "winLockSharedMemory", pShmNode->zFilename);
- }
- }
-
- if( rc==SQLITE_OK ){
- winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
- }
-
- return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
-}
-
-/*
+** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
+** take it now. Return SQLITE_OK if successful, or an SQLite error
+** code otherwise.
+**
+** If the DMS cannot be locked because this is a readonly_shm=1
+** connection and no other process already holds a lock, return
+** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
+*/
+static int winLockSharedMemory(winShmNode *pShmNode){
+ int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1);
+
+ if( rc==SQLITE_OK ){
+ if( pShmNode->isReadonly ){
+ pShmNode->isUnlocked = 1;
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+ return SQLITE_READONLY_CANTINIT;
+ }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+ return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
+ "winLockSharedMemory", pShmNode->zFilename);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+ }
+
+ return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
+}
+
+/*
** Open the shared-memory area associated with database file pDbFd.
**
** When opening a new shared-memory file, if no other instances of that
@@ -46283,9 +46283,9 @@ static int winLockSharedMemory(winShmNode *pShmNode){
*/
static int winOpenSharedMemory(winFile *pDbFd){
struct winShm *p; /* The connection to be opened */
- winShmNode *pShmNode = 0; /* The underlying mmapped file */
- int rc = SQLITE_OK; /* Result code */
- winShmNode *pNew; /* Newly allocated winShmNode */
+ winShmNode *pShmNode = 0; /* The underlying mmapped file */
+ int rc = SQLITE_OK; /* Result code */
+ winShmNode *pNew; /* Newly allocated winShmNode */
int nName; /* Size of zName in bytes */
assert( pDbFd->pShm==0 ); /* Not previously opened */
@@ -46294,12 +46294,12 @@ static int winOpenSharedMemory(winFile *pDbFd){
** allocate space for a new winShmNode and filename.
*/
p = sqlite3MallocZero( sizeof(*p) );
- if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT;
+ if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT;
nName = sqlite3Strlen30(pDbFd->zPath);
pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
if( pNew==0 ){
sqlite3_free(p);
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
pNew->zFilename = (char*)&pNew[1];
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
@@ -46318,40 +46318,40 @@ static int winOpenSharedMemory(winFile *pDbFd){
if( pShmNode ){
sqlite3_free(pNew);
}else{
- int inFlags = SQLITE_OPEN_WAL;
- int outFlags = 0;
-
+ int inFlags = SQLITE_OPEN_WAL;
+ int outFlags = 0;
+
pShmNode = pNew;
pNew = 0;
((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
pShmNode->pNext = winShmNodeList;
winShmNodeList = pShmNode;
- if( sqlite3GlobalConfig.bCoreMutex ){
- pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
- if( pShmNode->mutex==0 ){
- rc = SQLITE_IOERR_NOMEM_BKPT;
- goto shm_open_err;
- }
- }
-
- if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
- inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
- }else{
- inFlags |= SQLITE_OPEN_READONLY;
- }
- rc = winOpen(pDbFd->pVfs, pShmNode->zFilename,
- (sqlite3_file*)&pShmNode->hFile,
- inFlags, &outFlags);
- if( rc!=SQLITE_OK ){
- rc = winLogError(rc, osGetLastError(), "winOpenShm",
- pShmNode->zFilename);
+ if( sqlite3GlobalConfig.bCoreMutex ){
+ pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+ if( pShmNode->mutex==0 ){
+ rc = SQLITE_IOERR_NOMEM_BKPT;
+ goto shm_open_err;
+ }
+ }
+
+ if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
+ inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
+ }else{
+ inFlags |= SQLITE_OPEN_READONLY;
+ }
+ rc = winOpen(pDbFd->pVfs, pShmNode->zFilename,
+ (sqlite3_file*)&pShmNode->hFile,
+ inFlags, &outFlags);
+ if( rc!=SQLITE_OK ){
+ rc = winLogError(rc, osGetLastError(), "winOpenShm",
+ pShmNode->zFilename);
goto shm_open_err;
}
- if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1;
+ if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1;
- rc = winLockSharedMemory(pShmNode);
- if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
+ rc = winLockSharedMemory(pShmNode);
+ if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
}
/* Make the new connection a child of the winShmNode */
@@ -46374,11 +46374,11 @@ static int winOpenSharedMemory(winFile *pDbFd){
p->pNext = pShmNode->pFirst;
pShmNode->pFirst = p;
sqlite3_mutex_leave(pShmNode->mutex);
- return rc;
+ return rc;
/* Jump here on any error */
shm_open_err:
- winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */
sqlite3_free(p);
sqlite3_free(pNew);
@@ -46467,7 +46467,7 @@ static int winShmLock(
/* Unlock the system-level locks */
if( (mask & allMask)==0 ){
- rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n);
+ rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n);
}else{
rc = SQLITE_OK;
}
@@ -46495,7 +46495,7 @@ static int winShmLock(
/* Get shared locks at the system level, if necessary */
if( rc==SQLITE_OK ){
if( (allShared & mask)==0 ){
- rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n);
+ rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n);
}else{
rc = SQLITE_OK;
}
@@ -46520,7 +46520,7 @@ static int winShmLock(
** also mark the local connection as being locked.
*/
if( rc==SQLITE_OK ){
- rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n);
+ rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n);
if( rc==SQLITE_OK ){
assert( (p->sharedMask & mask)==0 );
p->exclMask |= mask;
@@ -46544,8 +46544,8 @@ static void winShmBarrier(
sqlite3_file *fd /* Database holding the shared memory */
){
UNUSED_PARAMETER(fd);
- sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
- winShmEnterMutex(); /* Also mutex, for redundancy */
+ sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
+ winShmEnterMutex(); /* Also mutex, for redundancy */
winShmLeaveMutex();
}
@@ -46578,8 +46578,8 @@ static int winShmMap(
winFile *pDbFd = (winFile*)fd;
winShm *pShm = pDbFd->pShm;
winShmNode *pShmNode;
- DWORD protect = PAGE_READWRITE;
- DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ;
+ DWORD protect = PAGE_READWRITE;
+ DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ;
int rc = SQLITE_OK;
if( !pShm ){
@@ -46591,11 +46591,11 @@ static int winShmMap(
pShmNode = pShm->pShmNode;
sqlite3_mutex_enter(pShmNode->mutex);
- if( pShmNode->isUnlocked ){
- rc = winLockSharedMemory(pShmNode);
- if( rc!=SQLITE_OK ) goto shmpage_out;
- pShmNode->isUnlocked = 0;
- }
+ if( pShmNode->isUnlocked ){
+ rc = winLockSharedMemory(pShmNode);
+ if( rc!=SQLITE_OK ) goto shmpage_out;
+ pShmNode->isUnlocked = 0;
+ }
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
if( pShmNode->nRegion<=iRegion ){
@@ -46637,31 +46637,31 @@ static int winShmMap(
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
);
if( !apNew ){
- rc = SQLITE_IOERR_NOMEM_BKPT;
+ rc = SQLITE_IOERR_NOMEM_BKPT;
goto shmpage_out;
}
pShmNode->aRegion = apNew;
- if( pShmNode->isReadonly ){
- protect = PAGE_READONLY;
- flags = FILE_MAP_READ;
- }
-
+ if( pShmNode->isReadonly ){
+ protect = PAGE_READONLY;
+ flags = FILE_MAP_READ;
+ }
+
while( pShmNode->nRegion<=iRegion ){
HANDLE hMap = NULL; /* file-mapping handle */
void *pMap = 0; /* Mapped memory region */
#if SQLITE_OS_WINRT
hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
- NULL, protect, nByte, NULL
+ NULL, protect, nByte, NULL
);
#elif defined(SQLITE_WIN32_HAS_WIDE)
hMap = osCreateFileMappingW(pShmNode->hFile.h,
- NULL, protect, 0, nByte, NULL
+ NULL, protect, 0, nByte, NULL
);
-#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
+#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
hMap = osCreateFileMappingA(pShmNode->hFile.h,
- NULL, protect, 0, nByte, NULL
+ NULL, protect, 0, nByte, NULL
);
#endif
OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
@@ -46671,11 +46671,11 @@ static int winShmMap(
int iOffset = pShmNode->nRegion*szRegion;
int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
#if SQLITE_OS_WINRT
- pMap = osMapViewOfFileFromApp(hMap, flags,
+ pMap = osMapViewOfFileFromApp(hMap, flags,
iOffset - iOffsetShift, szRegion + iOffsetShift
);
#else
- pMap = osMapViewOfFile(hMap, flags,
+ pMap = osMapViewOfFile(hMap, flags,
0, iOffset - iOffsetShift, szRegion + iOffsetShift
);
#endif
@@ -46706,7 +46706,7 @@ shmpage_out:
}else{
*pp = 0;
}
- if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
+ if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
sqlite3_mutex_leave(pShmNode->mutex);
return rc;
}
@@ -46803,19 +46803,19 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
DWORD flags = FILE_MAP_READ;
winUnmapfile(pFd);
-#ifdef SQLITE_MMAP_READWRITE
+#ifdef SQLITE_MMAP_READWRITE
if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){
protect = PAGE_READWRITE;
flags |= FILE_MAP_WRITE;
}
-#endif
+#endif
#if SQLITE_OS_WINRT
pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
#elif defined(SQLITE_WIN32_HAS_WIDE)
pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
(DWORD)((nMap>>32) & 0xffffffff),
(DWORD)(nMap & 0xffffffff), NULL);
-#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
+#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
(DWORD)((nMap>>32) & 0xffffffff),
(DWORD)(nMap & 0xffffffff), NULL);
@@ -46976,44 +46976,44 @@ static const sqlite3_io_methods winIoMethod = {
winUnfetch /* xUnfetch */
};
-/*
-** This vector defines all the methods that can operate on an
-** sqlite3_file for win32 without performing any locking.
-*/
-static const sqlite3_io_methods winIoNolockMethod = {
- 3, /* iVersion */
- winClose, /* xClose */
- winRead, /* xRead */
- winWrite, /* xWrite */
- winTruncate, /* xTruncate */
- winSync, /* xSync */
- winFileSize, /* xFileSize */
- winNolockLock, /* xLock */
- winNolockUnlock, /* xUnlock */
- winNolockCheckReservedLock, /* xCheckReservedLock */
- winFileControl, /* xFileControl */
- winSectorSize, /* xSectorSize */
- winDeviceCharacteristics, /* xDeviceCharacteristics */
- winShmMap, /* xShmMap */
- winShmLock, /* xShmLock */
- winShmBarrier, /* xShmBarrier */
- winShmUnmap, /* xShmUnmap */
- winFetch, /* xFetch */
- winUnfetch /* xUnfetch */
-};
-
-static winVfsAppData winAppData = {
- &winIoMethod, /* pMethod */
- 0, /* pAppData */
- 0 /* bNoLock */
-};
-
-static winVfsAppData winNolockAppData = {
- &winIoNolockMethod, /* pMethod */
- 0, /* pAppData */
- 1 /* bNoLock */
-};
-
+/*
+** This vector defines all the methods that can operate on an
+** sqlite3_file for win32 without performing any locking.
+*/
+static const sqlite3_io_methods winIoNolockMethod = {
+ 3, /* iVersion */
+ winClose, /* xClose */
+ winRead, /* xRead */
+ winWrite, /* xWrite */
+ winTruncate, /* xTruncate */
+ winSync, /* xSync */
+ winFileSize, /* xFileSize */
+ winNolockLock, /* xLock */
+ winNolockUnlock, /* xUnlock */
+ winNolockCheckReservedLock, /* xCheckReservedLock */
+ winFileControl, /* xFileControl */
+ winSectorSize, /* xSectorSize */
+ winDeviceCharacteristics, /* xDeviceCharacteristics */
+ winShmMap, /* xShmMap */
+ winShmLock, /* xShmLock */
+ winShmBarrier, /* xShmBarrier */
+ winShmUnmap, /* xShmUnmap */
+ winFetch, /* xFetch */
+ winUnfetch /* xUnfetch */
+};
+
+static winVfsAppData winAppData = {
+ &winIoMethod, /* pMethod */
+ 0, /* pAppData */
+ 0 /* bNoLock */
+};
+
+static winVfsAppData winNolockAppData = {
+ &winIoNolockMethod, /* pMethod */
+ 0, /* pAppData */
+ 1 /* bNoLock */
+};
+
/****************************************************************************
**************************** sqlite3_vfs methods ****************************
**
@@ -47034,7 +47034,7 @@ static char *winConvertToUtf8Filename(const void *zFilename){
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
- zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI());
+ zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI());
}
#endif
/* caller will handle out of memory */
@@ -47055,7 +47055,7 @@ static void *winConvertFromUtf8Filename(const char *zFilename){
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
- zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI());
+ zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI());
}
#endif
/* caller will handle out of memory */
@@ -47110,7 +47110,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
zBuf = sqlite3MallocZero( nBuf );
if( !zBuf ){
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
/* Figure out the effective temporary directory. First, check if one
@@ -47168,7 +47168,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zConverted ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( winIsDir(zConverted) ){
sqlite3_snprintf(nMax, zBuf, "%s", zDir);
@@ -47181,7 +47181,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zConverted ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( cygwin_conv_path(
osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
@@ -47202,7 +47202,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
sqlite3_free(zConverted);
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
sqlite3_free(zUtf8);
@@ -47220,7 +47220,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zWidePath ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osGetTempPathW(nMax, zWidePath)==0 ){
sqlite3_free(zWidePath);
@@ -47238,7 +47238,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
sqlite3_free(zWidePath);
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
@@ -47248,7 +47248,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zMbcsPath ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osGetTempPathA(nMax, zMbcsPath)==0 ){
sqlite3_free(zBuf);
@@ -47256,14 +47256,14 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
"winGetTempname3", 0);
}
- zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI());
+ zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI());
if( zUtf8 ){
sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
sqlite3_free(zUtf8);
}else{
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
}
#endif /* SQLITE_WIN32_HAS_ANSI */
@@ -47342,19 +47342,19 @@ static int winIsDir(const void *zConverted){
return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
}
-/* forward reference */
-static int winAccess(
- sqlite3_vfs *pVfs, /* Not used on win32 */
- const char *zFilename, /* Name of file to check */
- int flags, /* Type of test to make on this file */
- int *pResOut /* OUT: Result */
-);
-
+/* forward reference */
+static int winAccess(
+ sqlite3_vfs *pVfs, /* Not used on win32 */
+ const char *zFilename, /* Name of file to check */
+ int flags, /* Type of test to make on this file */
+ int *pResOut /* OUT: Result */
+);
+
/*
** Open a file.
*/
static int winOpen(
- sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */
+ sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */
const char *zName, /* Name of the file (UTF-8) */
sqlite3_file *id, /* Write the SQLite file handle here */
int flags, /* Open mode flags */
@@ -47369,7 +47369,7 @@ static int winOpen(
#if SQLITE_OS_WINCE
int isTemp = 0;
#endif
- winVfsAppData *pAppData;
+ winVfsAppData *pAppData;
winFile *pFile = (winFile*)id;
void *zConverted; /* Filename in OS encoding */
const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
@@ -47464,7 +47464,7 @@ static int winOpen(
if( zConverted==0 ){
sqlite3_free(zTmpname);
OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( winIsDir(zConverted) ){
@@ -47530,58 +47530,58 @@ static int winOpen(
extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extendedParameters.lpSecurityAttributes = NULL;
extendedParameters.hTemplateFile = NULL;
- do{
- h = osCreateFile2((LPCWSTR)zConverted,
- dwDesiredAccess,
- dwShareMode,
- dwCreationDisposition,
- &extendedParameters);
- if( h!=INVALID_HANDLE_VALUE ) break;
- if( isReadWrite ){
- int rc2, isRO = 0;
- sqlite3BeginBenignMalloc();
- rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
- sqlite3EndBenignMalloc();
- if( rc2==SQLITE_OK && isRO ) break;
- }
- }while( winRetryIoerr(&cnt, &lastErrno) );
-#else
- do{
- h = osCreateFileW((LPCWSTR)zConverted,
- dwDesiredAccess,
- dwShareMode, NULL,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- NULL);
- if( h!=INVALID_HANDLE_VALUE ) break;
- if( isReadWrite ){
- int rc2, isRO = 0;
- sqlite3BeginBenignMalloc();
- rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
- sqlite3EndBenignMalloc();
- if( rc2==SQLITE_OK && isRO ) break;
- }
- }while( winRetryIoerr(&cnt, &lastErrno) );
+ do{
+ h = osCreateFile2((LPCWSTR)zConverted,
+ dwDesiredAccess,
+ dwShareMode,
+ dwCreationDisposition,
+ &extendedParameters);
+ if( h!=INVALID_HANDLE_VALUE ) break;
+ if( isReadWrite ){
+ int rc2, isRO = 0;
+ sqlite3BeginBenignMalloc();
+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ sqlite3EndBenignMalloc();
+ if( rc2==SQLITE_OK && isRO ) break;
+ }
+ }while( winRetryIoerr(&cnt, &lastErrno) );
+#else
+ do{
+ h = osCreateFileW((LPCWSTR)zConverted,
+ dwDesiredAccess,
+ dwShareMode, NULL,
+ dwCreationDisposition,
+ dwFlagsAndAttributes,
+ NULL);
+ if( h!=INVALID_HANDLE_VALUE ) break;
+ if( isReadWrite ){
+ int rc2, isRO = 0;
+ sqlite3BeginBenignMalloc();
+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ sqlite3EndBenignMalloc();
+ if( rc2==SQLITE_OK && isRO ) break;
+ }
+ }while( winRetryIoerr(&cnt, &lastErrno) );
#endif
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
- do{
- h = osCreateFileA((LPCSTR)zConverted,
- dwDesiredAccess,
- dwShareMode, NULL,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- NULL);
- if( h!=INVALID_HANDLE_VALUE ) break;
- if( isReadWrite ){
- int rc2, isRO = 0;
- sqlite3BeginBenignMalloc();
- rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
- sqlite3EndBenignMalloc();
- if( rc2==SQLITE_OK && isRO ) break;
- }
- }while( winRetryIoerr(&cnt, &lastErrno) );
+ do{
+ h = osCreateFileA((LPCSTR)zConverted,
+ dwDesiredAccess,
+ dwShareMode, NULL,
+ dwCreationDisposition,
+ dwFlagsAndAttributes,
+ NULL);
+ if( h!=INVALID_HANDLE_VALUE ) break;
+ if( isReadWrite ){
+ int rc2, isRO = 0;
+ sqlite3BeginBenignMalloc();
+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ sqlite3EndBenignMalloc();
+ if( rc2==SQLITE_OK && isRO ) break;
+ }
+ }while( winRetryIoerr(&cnt, &lastErrno) );
}
#endif
winLogIoerr(cnt, __LINE__);
@@ -47598,8 +47598,8 @@ static int winOpen(
~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
pOutFlags);
}else{
- pFile->lastErrno = lastErrno;
- winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
+ pFile->lastErrno = lastErrno;
+ winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
return SQLITE_CANTOPEN_BKPT;
}
}
@@ -47616,20 +47616,20 @@ static int winOpen(
"rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ?
*pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
- pAppData = (winVfsAppData*)pVfs->pAppData;
-
+ pAppData = (winVfsAppData*)pVfs->pAppData;
+
#if SQLITE_OS_WINCE
- {
- if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
- && ((pAppData==NULL) || !pAppData->bNoLock)
- && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
- ){
- osCloseHandle(h);
- sqlite3_free(zConverted);
- sqlite3_free(zTmpname);
- OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
- return rc;
- }
+ {
+ if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
+ && ((pAppData==NULL) || !pAppData->bNoLock)
+ && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
+ ){
+ osCloseHandle(h);
+ sqlite3_free(zConverted);
+ sqlite3_free(zTmpname);
+ OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
+ return rc;
+ }
}
if( isTemp ){
pFile->zDeleteOnClose = zConverted;
@@ -47695,7 +47695,7 @@ static int winDelete(
zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osIsNT() ){
do {
@@ -47803,7 +47803,7 @@ static int winAccess(
zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osIsNT() ){
int cnt = 0;
@@ -47927,20 +47927,20 @@ static int winFullPathname(
int nFull, /* Size of output buffer in bytes */
char *zFull /* Output buffer */
){
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
- DWORD nByte;
- void *zConverted;
- char *zOut;
-#endif
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
+ DWORD nByte;
+ void *zConverted;
+ char *zOut;
+#endif
/* If this path name begins with "/X:" or "\\?\", where "X" is any
** alphabetic character, discard the initial "/" from the pathname.
- */
+ */
if( zRelative[0]=='/' && (winIsDriveLetterAndColon(zRelative+1)
|| winIsLongPathPrefix(zRelative+1)) ){
- zRelative++;
- }
-
+ zRelative++;
+ }
+
#if defined(__CYGWIN__)
SimulateIOError( return SQLITE_ERROR );
UNUSED_PARAMETER(nFull);
@@ -47954,7 +47954,7 @@ static int winFullPathname(
*/
char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
if( !zOut ){
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( cygwin_conv_path(
(osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
@@ -47966,7 +47966,7 @@ static int winFullPathname(
char *zUtf8 = winConvertToUtf8Filename(zOut);
if( !zUtf8 ){
sqlite3_free(zOut);
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
sqlite3_data_directory, winGetDirSep(), zUtf8);
@@ -47976,7 +47976,7 @@ static int winFullPathname(
}else{
char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
if( !zOut ){
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( cygwin_conv_path(
(osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
@@ -47988,7 +47988,7 @@ static int winFullPathname(
char *zUtf8 = winConvertToUtf8Filename(zOut);
if( !zUtf8 ){
sqlite3_free(zOut);
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
sqlite3_free(zUtf8);
@@ -48037,7 +48037,7 @@ static int winFullPathname(
}
zConverted = winConvertFromUtf8Filename(zRelative);
if( zConverted==0 ){
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osIsNT() ){
LPWSTR zTemp;
@@ -48051,7 +48051,7 @@ static int winFullPathname(
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
@@ -48077,7 +48077,7 @@ static int winFullPathname(
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
@@ -48087,7 +48087,7 @@ static int winFullPathname(
"winFullPathname4", zRelative);
}
sqlite3_free(zConverted);
- zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
+ zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
sqlite3_free(zTemp);
}
#endif
@@ -48096,7 +48096,7 @@ static int winFullPathname(
sqlite3_free(zOut);
return SQLITE_OK;
}else{
- return SQLITE_IOERR_NOMEM_BKPT;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
#endif
}
@@ -48171,82 +48171,82 @@ static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
#define winDlClose 0
#endif
-/* State information for the randomness gatherer. */
-typedef struct EntropyGatherer EntropyGatherer;
-struct EntropyGatherer {
- unsigned char *a; /* Gather entropy into this buffer */
- int na; /* Size of a[] in bytes */
- int i; /* XOR next input into a[i] */
- int nXor; /* Number of XOR operations done */
-};
-
-#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
-/* Mix sz bytes of entropy into p. */
-static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){
- int j, k;
- for(j=0, k=p->i; j<sz; j++){
- p->a[k++] ^= x[j];
- if( k>=p->na ) k = 0;
- }
- p->i = k;
- p->nXor += sz;
-}
-#endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */
-
+/* State information for the randomness gatherer. */
+typedef struct EntropyGatherer EntropyGatherer;
+struct EntropyGatherer {
+ unsigned char *a; /* Gather entropy into this buffer */
+ int na; /* Size of a[] in bytes */
+ int i; /* XOR next input into a[i] */
+ int nXor; /* Number of XOR operations done */
+};
+
+#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
+/* Mix sz bytes of entropy into p. */
+static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){
+ int j, k;
+ for(j=0, k=p->i; j<sz; j++){
+ p->a[k++] ^= x[j];
+ if( k>=p->na ) k = 0;
+ }
+ p->i = k;
+ p->nXor += sz;
+}
+#endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */
+
/*
** Write up to nBuf bytes of randomness into zBuf.
*/
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
+#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
+ UNUSED_PARAMETER(pVfs);
+ memset(zBuf, 0, nBuf);
+ return nBuf;
+#else
+ EntropyGatherer e;
UNUSED_PARAMETER(pVfs);
memset(zBuf, 0, nBuf);
- return nBuf;
-#else
- EntropyGatherer e;
- UNUSED_PARAMETER(pVfs);
- memset(zBuf, 0, nBuf);
- e.a = (unsigned char*)zBuf;
- e.na = nBuf;
- e.nXor = 0;
- e.i = 0;
- {
+ e.a = (unsigned char*)zBuf;
+ e.na = nBuf;
+ e.nXor = 0;
+ e.i = 0;
+ {
SYSTEMTIME x;
osGetSystemTime(&x);
- xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME));
+ xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME));
}
- {
+ {
DWORD pid = osGetCurrentProcessId();
- xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD));
+ xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD));
}
#if SQLITE_OS_WINRT
- {
+ {
ULONGLONG cnt = osGetTickCount64();
- xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG));
+ xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG));
}
#else
- {
+ {
DWORD cnt = osGetTickCount();
- xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD));
+ xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD));
}
-#endif /* SQLITE_OS_WINRT */
- {
+#endif /* SQLITE_OS_WINRT */
+ {
LARGE_INTEGER i;
osQueryPerformanceCounter(&i);
- xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER));
+ xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER));
}
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
- {
+ {
UUID id;
memset(&id, 0, sizeof(UUID));
osUuidCreate(&id);
- xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
+ xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
memset(&id, 0, sizeof(UUID));
osUuidCreateSequential(&id);
- xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
+ xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
}
-#endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */
- return e.nXor>nBuf ? nBuf : e.nXor;
-#endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */
+#endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */
+ return e.nXor>nBuf ? nBuf : e.nXor;
+#endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */
}
@@ -48362,116 +48362,116 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
** sqlite3_errmsg(), possibly making IO errors easier to debug.
*/
static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
- DWORD e = osGetLastError();
+ DWORD e = osGetLastError();
UNUSED_PARAMETER(pVfs);
- if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf);
- return e;
+ if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf);
+ return e;
}
/*
** Initialize and deinitialize the operating system interface.
*/
-SQLITE_API int sqlite3_os_init(void){
+SQLITE_API int sqlite3_os_init(void){
static sqlite3_vfs winVfs = {
- 3, /* iVersion */
- sizeof(winFile), /* szOsFile */
+ 3, /* iVersion */
+ sizeof(winFile), /* szOsFile */
SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
- 0, /* pNext */
- "win32", /* zName */
- &winAppData, /* pAppData */
- winOpen, /* xOpen */
- winDelete, /* xDelete */
- winAccess, /* xAccess */
- winFullPathname, /* xFullPathname */
- winDlOpen, /* xDlOpen */
- winDlError, /* xDlError */
- winDlSym, /* xDlSym */
- winDlClose, /* xDlClose */
- winRandomness, /* xRandomness */
- winSleep, /* xSleep */
- winCurrentTime, /* xCurrentTime */
- winGetLastError, /* xGetLastError */
- winCurrentTimeInt64, /* xCurrentTimeInt64 */
- winSetSystemCall, /* xSetSystemCall */
- winGetSystemCall, /* xGetSystemCall */
- winNextSystemCall, /* xNextSystemCall */
+ 0, /* pNext */
+ "win32", /* zName */
+ &winAppData, /* pAppData */
+ winOpen, /* xOpen */
+ winDelete, /* xDelete */
+ winAccess, /* xAccess */
+ winFullPathname, /* xFullPathname */
+ winDlOpen, /* xDlOpen */
+ winDlError, /* xDlError */
+ winDlSym, /* xDlSym */
+ winDlClose, /* xDlClose */
+ winRandomness, /* xRandomness */
+ winSleep, /* xSleep */
+ winCurrentTime, /* xCurrentTime */
+ winGetLastError, /* xGetLastError */
+ winCurrentTimeInt64, /* xCurrentTimeInt64 */
+ winSetSystemCall, /* xSetSystemCall */
+ winGetSystemCall, /* xGetSystemCall */
+ winNextSystemCall, /* xNextSystemCall */
};
#if defined(SQLITE_WIN32_HAS_WIDE)
static sqlite3_vfs winLongPathVfs = {
- 3, /* iVersion */
- sizeof(winFile), /* szOsFile */
+ 3, /* iVersion */
+ sizeof(winFile), /* szOsFile */
SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
- 0, /* pNext */
- "win32-longpath", /* zName */
- &winAppData, /* pAppData */
- winOpen, /* xOpen */
- winDelete, /* xDelete */
- winAccess, /* xAccess */
- winFullPathname, /* xFullPathname */
- winDlOpen, /* xDlOpen */
- winDlError, /* xDlError */
- winDlSym, /* xDlSym */
- winDlClose, /* xDlClose */
- winRandomness, /* xRandomness */
- winSleep, /* xSleep */
- winCurrentTime, /* xCurrentTime */
- winGetLastError, /* xGetLastError */
- winCurrentTimeInt64, /* xCurrentTimeInt64 */
- winSetSystemCall, /* xSetSystemCall */
- winGetSystemCall, /* xGetSystemCall */
- winNextSystemCall, /* xNextSystemCall */
+ 0, /* pNext */
+ "win32-longpath", /* zName */
+ &winAppData, /* pAppData */
+ winOpen, /* xOpen */
+ winDelete, /* xDelete */
+ winAccess, /* xAccess */
+ winFullPathname, /* xFullPathname */
+ winDlOpen, /* xDlOpen */
+ winDlError, /* xDlError */
+ winDlSym, /* xDlSym */
+ winDlClose, /* xDlClose */
+ winRandomness, /* xRandomness */
+ winSleep, /* xSleep */
+ winCurrentTime, /* xCurrentTime */
+ winGetLastError, /* xGetLastError */
+ winCurrentTimeInt64, /* xCurrentTimeInt64 */
+ winSetSystemCall, /* xSetSystemCall */
+ winGetSystemCall, /* xGetSystemCall */
+ winNextSystemCall, /* xNextSystemCall */
+ };
+#endif
+ static sqlite3_vfs winNolockVfs = {
+ 3, /* iVersion */
+ sizeof(winFile), /* szOsFile */
+ SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
+ 0, /* pNext */
+ "win32-none", /* zName */
+ &winNolockAppData, /* pAppData */
+ winOpen, /* xOpen */
+ winDelete, /* xDelete */
+ winAccess, /* xAccess */
+ winFullPathname, /* xFullPathname */
+ winDlOpen, /* xDlOpen */
+ winDlError, /* xDlError */
+ winDlSym, /* xDlSym */
+ winDlClose, /* xDlClose */
+ winRandomness, /* xRandomness */
+ winSleep, /* xSleep */
+ winCurrentTime, /* xCurrentTime */
+ winGetLastError, /* xGetLastError */
+ winCurrentTimeInt64, /* xCurrentTimeInt64 */
+ winSetSystemCall, /* xSetSystemCall */
+ winGetSystemCall, /* xGetSystemCall */
+ winNextSystemCall, /* xNextSystemCall */
+ };
+#if defined(SQLITE_WIN32_HAS_WIDE)
+ static sqlite3_vfs winLongPathNolockVfs = {
+ 3, /* iVersion */
+ sizeof(winFile), /* szOsFile */
+ SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
+ 0, /* pNext */
+ "win32-longpath-none", /* zName */
+ &winNolockAppData, /* pAppData */
+ winOpen, /* xOpen */
+ winDelete, /* xDelete */
+ winAccess, /* xAccess */
+ winFullPathname, /* xFullPathname */
+ winDlOpen, /* xDlOpen */
+ winDlError, /* xDlError */
+ winDlSym, /* xDlSym */
+ winDlClose, /* xDlClose */
+ winRandomness, /* xRandomness */
+ winSleep, /* xSleep */
+ winCurrentTime, /* xCurrentTime */
+ winGetLastError, /* xGetLastError */
+ winCurrentTimeInt64, /* xCurrentTimeInt64 */
+ winSetSystemCall, /* xSetSystemCall */
+ winGetSystemCall, /* xGetSystemCall */
+ winNextSystemCall, /* xNextSystemCall */
};
#endif
- static sqlite3_vfs winNolockVfs = {
- 3, /* iVersion */
- sizeof(winFile), /* szOsFile */
- SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
- 0, /* pNext */
- "win32-none", /* zName */
- &winNolockAppData, /* pAppData */
- winOpen, /* xOpen */
- winDelete, /* xDelete */
- winAccess, /* xAccess */
- winFullPathname, /* xFullPathname */
- winDlOpen, /* xDlOpen */
- winDlError, /* xDlError */
- winDlSym, /* xDlSym */
- winDlClose, /* xDlClose */
- winRandomness, /* xRandomness */
- winSleep, /* xSleep */
- winCurrentTime, /* xCurrentTime */
- winGetLastError, /* xGetLastError */
- winCurrentTimeInt64, /* xCurrentTimeInt64 */
- winSetSystemCall, /* xSetSystemCall */
- winGetSystemCall, /* xGetSystemCall */
- winNextSystemCall, /* xNextSystemCall */
- };
-#if defined(SQLITE_WIN32_HAS_WIDE)
- static sqlite3_vfs winLongPathNolockVfs = {
- 3, /* iVersion */
- sizeof(winFile), /* szOsFile */
- SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
- 0, /* pNext */
- "win32-longpath-none", /* zName */
- &winNolockAppData, /* pAppData */
- winOpen, /* xOpen */
- winDelete, /* xDelete */
- winAccess, /* xAccess */
- winFullPathname, /* xFullPathname */
- winDlOpen, /* xDlOpen */
- winDlError, /* xDlError */
- winDlSym, /* xDlSym */
- winDlClose, /* xDlClose */
- winRandomness, /* xRandomness */
- winSleep, /* xSleep */
- winCurrentTime, /* xCurrentTime */
- winGetLastError, /* xGetLastError */
- winCurrentTimeInt64, /* xCurrentTimeInt64 */
- winSetSystemCall, /* xSetSystemCall */
- winGetSystemCall, /* xGetSystemCall */
- winNextSystemCall, /* xNextSystemCall */
- };
-#endif
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
@@ -48493,12 +48493,12 @@ SQLITE_API int sqlite3_os_init(void){
sqlite3_vfs_register(&winLongPathVfs, 0);
#endif
- sqlite3_vfs_register(&winNolockVfs, 0);
-
-#if defined(SQLITE_WIN32_HAS_WIDE)
- sqlite3_vfs_register(&winLongPathNolockVfs, 0);
-#endif
-
+ sqlite3_vfs_register(&winNolockVfs, 0);
+
+#if defined(SQLITE_WIN32_HAS_WIDE)
+ sqlite3_vfs_register(&winLongPathNolockVfs, 0);
+#endif
+
#ifndef SQLITE_OMIT_WAL
winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
#endif
@@ -48506,7 +48506,7 @@ SQLITE_API int sqlite3_os_init(void){
return SQLITE_OK;
}
-SQLITE_API int sqlite3_os_end(void){
+SQLITE_API int sqlite3_os_end(void){
#if SQLITE_OS_WINRT
if( sleepObj!=NULL ){
osCloseHandle(sleepObj);
@@ -49449,8 +49449,8 @@ SQLITE_PRIVATE int sqlite3MemdbInit(void){
/* 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-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
+#define BITVEC_USIZE \
+ (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
/* Type of the array "element" for the bitmap representation.
** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE.
@@ -49585,7 +49585,7 @@ SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){
i = i%p->iDivisor;
if( p->u.apSub[bin]==0 ){
p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
- if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM_BKPT;
+ if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM_BKPT;
}
p = p->u.apSub[bin];
}
@@ -49620,7 +49620,7 @@ bitvec_set_rehash:
int rc;
u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
if( aiValues==0 ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}else{
memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
memset(p->u.apSub, 0, sizeof(p->u.apSub));
@@ -49701,7 +49701,7 @@ SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
return p->iSize;
}
-#ifndef SQLITE_UNTESTABLE
+#ifndef SQLITE_UNTESTABLE
/*
** Let V[] be an array of unsigned characters sufficient to hold
** up to N bits. Let I be an integer between 0 and N. 0<=I<N.
@@ -49816,7 +49816,7 @@ bitvec_end:
sqlite3BitvecDestroy(pBitvec);
return rc;
}
-#endif /* SQLITE_UNTESTABLE */
+#endif /* SQLITE_UNTESTABLE */
/************** End of bitvec.c **********************************************/
/************** Begin file pcache.c ******************************************/
@@ -49836,36 +49836,36 @@ bitvec_end:
/* #include "sqliteInt.h" */
/*
-** A complete page cache is an instance of this structure. Every
-** entry in the cache holds a single page of the database file. The
-** btree layer only operates on the cached copy of the database pages.
-**
-** A page cache entry is "clean" if it exactly matches what is currently
-** on disk. A page is "dirty" if it has been modified and needs to be
-** persisted to disk.
-**
-** pDirty, pDirtyTail, pSynced:
-** All dirty pages are linked into the doubly linked list using
-** PgHdr.pDirtyNext and pDirtyPrev. The list is maintained in LRU order
-** such that p was added to the list more recently than p->pDirtyNext.
-** PCache.pDirty points to the first (newest) element in the list and
-** pDirtyTail to the last (oldest).
-**
-** The PCache.pSynced variable is used to optimize searching for a dirty
-** page to eject from the cache mid-transaction. It is better to eject
+** A complete page cache is an instance of this structure. Every
+** entry in the cache holds a single page of the database file. The
+** btree layer only operates on the cached copy of the database pages.
+**
+** A page cache entry is "clean" if it exactly matches what is currently
+** on disk. A page is "dirty" if it has been modified and needs to be
+** persisted to disk.
+**
+** pDirty, pDirtyTail, pSynced:
+** All dirty pages are linked into the doubly linked list using
+** PgHdr.pDirtyNext and pDirtyPrev. The list is maintained in LRU order
+** such that p was added to the list more recently than p->pDirtyNext.
+** PCache.pDirty points to the first (newest) element in the list and
+** pDirtyTail to the last (oldest).
+**
+** The PCache.pSynced variable is used to optimize searching for a dirty
+** page to eject from the cache mid-transaction. It is better to eject
** a page that does not require a journal sync than one that does.
** Therefore, pSynced is maintained so that it *almost* always points
-** to either the oldest page in the pDirty/pDirtyTail list that has a
-** clear PGHDR_NEED_SYNC flag or to a page that is older than this one
-** (so that the right page to eject can be found by following pDirtyPrev
-** pointers).
+** to either the oldest page in the pDirty/pDirtyTail list that has a
+** clear PGHDR_NEED_SYNC flag or to a page that is older than this one
+** (so that the right page to eject can be found by following pDirtyPrev
+** pointers).
*/
struct PCache {
PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */
PgHdr *pSynced; /* Last synced page in dirty page list */
- int nRefSum; /* Sum of ref counts over all pages */
+ int nRefSum; /* Sum of ref counts over all pages */
int szCache; /* Configured cache size */
- int szSpill; /* Size before spilling occurs */
+ int szSpill; /* Size before spilling occurs */
int szPage; /* Size of every page in this cache */
int szExtra; /* Size of extra space for each page */
u8 bPurgeable; /* True if pages are on backing store */
@@ -49875,95 +49875,95 @@ struct PCache {
sqlite3_pcache *pCache; /* Pluggable cache module */
};
-/********************************** Test and Debug Logic **********************/
-/*
-** Debug tracing macros. Enable by by changing the "0" to "1" and
-** recompiling.
-**
-** When sqlite3PcacheTrace is 1, single line trace messages are issued.
-** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries
-** is displayed for many operations, resulting in a lot of output.
-*/
-#if defined(SQLITE_DEBUG) && 0
- int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */
- int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */
-# define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;}
- void pcacheDump(PCache *pCache){
- int N;
- int i, j;
- sqlite3_pcache_page *pLower;
- PgHdr *pPg;
- unsigned char *a;
-
- if( sqlite3PcacheTrace<2 ) return;
- if( pCache->pCache==0 ) return;
- N = sqlite3PcachePagecount(pCache);
- if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump;
- for(i=1; i<=N; i++){
- pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0);
- if( pLower==0 ) continue;
- pPg = (PgHdr*)pLower->pExtra;
- printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags);
- a = (unsigned char *)pLower->pBuf;
- for(j=0; j<12; j++) printf("%02x", a[j]);
- printf("\n");
- if( pPg->pPage==0 ){
- sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0);
- }
- }
- }
- #else
-# define pcacheTrace(X)
-# define pcacheDump(X)
-#endif
-
-/*
-** Check invariants on a PgHdr entry. Return true if everything is OK.
-** Return false if any invariant is violated.
-**
-** This routine is for use inside of assert() statements only. For
-** example:
-**
-** assert( sqlite3PcachePageSanity(pPg) );
-*/
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){
- PCache *pCache;
- assert( pPg!=0 );
- assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */
- pCache = pPg->pCache;
- assert( pCache!=0 ); /* Every page has an associated PCache */
- if( pPg->flags & PGHDR_CLEAN ){
- assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */
- assert( pCache->pDirty!=pPg ); /* CLEAN pages not on dirty list */
- assert( pCache->pDirtyTail!=pPg );
- }
- /* WRITEABLE pages must also be DIRTY */
- if( pPg->flags & PGHDR_WRITEABLE ){
- assert( pPg->flags & PGHDR_DIRTY ); /* WRITEABLE implies DIRTY */
- }
- /* NEED_SYNC can be set independently of WRITEABLE. This can happen,
- ** for example, when using the sqlite3PagerDontWrite() optimization:
- ** (1) Page X is journalled, and gets WRITEABLE and NEED_SEEK.
- ** (2) Page X moved to freelist, WRITEABLE is cleared
- ** (3) Page X reused, WRITEABLE is set again
- ** If NEED_SYNC had been cleared in step 2, then it would not be reset
- ** in step 3, and page might be written into the database without first
- ** syncing the rollback journal, which might cause corruption on a power
- ** loss.
- **
- ** Another example is when the database page size is smaller than the
- ** disk sector size. When any page of a sector is journalled, all pages
- ** in that sector are marked NEED_SYNC even if they are still CLEAN, just
- ** in case they are later modified, since all pages in the same sector
- ** must be journalled and synced before any of those pages can be safely
- ** written.
- */
- return 1;
-}
-#endif /* SQLITE_DEBUG */
-
-
+/********************************** Test and Debug Logic **********************/
+/*
+** Debug tracing macros. Enable by by changing the "0" to "1" and
+** recompiling.
+**
+** When sqlite3PcacheTrace is 1, single line trace messages are issued.
+** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries
+** is displayed for many operations, resulting in a lot of output.
+*/
+#if defined(SQLITE_DEBUG) && 0
+ int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */
+ int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */
+# define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;}
+ void pcacheDump(PCache *pCache){
+ int N;
+ int i, j;
+ sqlite3_pcache_page *pLower;
+ PgHdr *pPg;
+ unsigned char *a;
+
+ if( sqlite3PcacheTrace<2 ) return;
+ if( pCache->pCache==0 ) return;
+ N = sqlite3PcachePagecount(pCache);
+ if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump;
+ for(i=1; i<=N; i++){
+ pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0);
+ if( pLower==0 ) continue;
+ pPg = (PgHdr*)pLower->pExtra;
+ printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags);
+ a = (unsigned char *)pLower->pBuf;
+ for(j=0; j<12; j++) printf("%02x", a[j]);
+ printf("\n");
+ if( pPg->pPage==0 ){
+ sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0);
+ }
+ }
+ }
+ #else
+# define pcacheTrace(X)
+# define pcacheDump(X)
+#endif
+
+/*
+** Check invariants on a PgHdr entry. Return true if everything is OK.
+** Return false if any invariant is violated.
+**
+** This routine is for use inside of assert() statements only. For
+** example:
+**
+** assert( sqlite3PcachePageSanity(pPg) );
+*/
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){
+ PCache *pCache;
+ assert( pPg!=0 );
+ assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */
+ pCache = pPg->pCache;
+ assert( pCache!=0 ); /* Every page has an associated PCache */
+ if( pPg->flags & PGHDR_CLEAN ){
+ assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */
+ assert( pCache->pDirty!=pPg ); /* CLEAN pages not on dirty list */
+ assert( pCache->pDirtyTail!=pPg );
+ }
+ /* WRITEABLE pages must also be DIRTY */
+ if( pPg->flags & PGHDR_WRITEABLE ){
+ assert( pPg->flags & PGHDR_DIRTY ); /* WRITEABLE implies DIRTY */
+ }
+ /* NEED_SYNC can be set independently of WRITEABLE. This can happen,
+ ** for example, when using the sqlite3PagerDontWrite() optimization:
+ ** (1) Page X is journalled, and gets WRITEABLE and NEED_SEEK.
+ ** (2) Page X moved to freelist, WRITEABLE is cleared
+ ** (3) Page X reused, WRITEABLE is set again
+ ** If NEED_SYNC had been cleared in step 2, then it would not be reset
+ ** in step 3, and page might be written into the database without first
+ ** syncing the rollback journal, which might cause corruption on a power
+ ** loss.
+ **
+ ** Another example is when the database page size is smaller than the
+ ** disk sector size. When any page of a sector is journalled, all pages
+ ** in that sector are marked NEED_SYNC even if they are still CLEAN, just
+ ** in case they are later modified, since all pages in the same sector
+ ** must be journalled and synced before any of those pages can be safely
+ ** written.
+ */
+ return 1;
+}
+#endif /* SQLITE_DEBUG */
+
+
/********************************** Linked List Management ********************/
/* Allowed values for second argument to pcacheManageDirtyList() */
@@ -49980,16 +49980,16 @@ SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){
static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
PCache *p = pPage->pCache;
- pcacheTrace(("%p.DIRTYLIST.%s %d\n", p,
- addRemove==1 ? "REMOVE" : addRemove==2 ? "ADD" : "FRONT",
- pPage->pgno));
+ pcacheTrace(("%p.DIRTYLIST.%s %d\n", p,
+ addRemove==1 ? "REMOVE" : addRemove==2 ? "ADD" : "FRONT",
+ pPage->pgno));
if( addRemove & PCACHE_DIRTYLIST_REMOVE ){
assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
assert( pPage->pDirtyPrev || pPage==p->pDirty );
/* Update the PCache1.pSynced variable if necessary. */
if( p->pSynced==pPage ){
- p->pSynced = pPage->pDirtyPrev;
+ p->pSynced = pPage->pDirtyPrev;
}
if( pPage->pDirtyNext ){
@@ -50002,20 +50002,20 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
}else{
/* If there are now no dirty pages in the cache, set eCreate to 2.
- ** This is an optimization that allows sqlite3PcacheFetch() to skip
- ** searching for a dirty page to eject from the cache when it might
- ** otherwise have to. */
+ ** This is an optimization that allows sqlite3PcacheFetch() to skip
+ ** searching for a dirty page to eject from the cache when it might
+ ** otherwise have to. */
assert( pPage==p->pDirty );
p->pDirty = pPage->pDirtyNext;
- assert( p->bPurgeable || p->eCreate==2 );
- if( p->pDirty==0 ){ /*OPTIMIZATION-IF-TRUE*/
- assert( p->bPurgeable==0 || p->eCreate==1 );
+ assert( p->bPurgeable || p->eCreate==2 );
+ if( p->pDirty==0 ){ /*OPTIMIZATION-IF-TRUE*/
+ assert( p->bPurgeable==0 || p->eCreate==1 );
p->eCreate = 2;
}
}
}
if( addRemove & PCACHE_DIRTYLIST_ADD ){
- pPage->pDirtyPrev = 0;
+ pPage->pDirtyPrev = 0;
pPage->pDirtyNext = p->pDirty;
if( pPage->pDirtyNext ){
assert( pPage->pDirtyNext->pDirtyPrev==0 );
@@ -50028,19 +50028,19 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
}
}
p->pDirty = pPage;
-
- /* If pSynced is NULL and this page has a clear NEED_SYNC flag, set
+
+ /* If pSynced is NULL and this page has a clear NEED_SYNC flag, set
** pSynced to point to it. Checking the NEED_SYNC flag is an
- ** optimization, as if pSynced points to a page with the NEED_SYNC
+ ** optimization, as if pSynced points to a page with the NEED_SYNC
** flag set sqlite3PcacheFetchStress() searches through all newer
- ** entries of the dirty-list for a page with NEED_SYNC clear anyway. */
+ ** entries of the dirty-list for a page with NEED_SYNC clear anyway. */
if( !p->pSynced
- && 0==(pPage->flags&PGHDR_NEED_SYNC) /*OPTIMIZATION-IF-FALSE*/
- ){
+ && 0==(pPage->flags&PGHDR_NEED_SYNC) /*OPTIMIZATION-IF-FALSE*/
+ ){
p->pSynced = pPage;
}
}
- pcacheDump(p);
+ pcacheDump(p);
}
/*
@@ -50049,14 +50049,14 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
*/
static void pcacheUnpin(PgHdr *p){
if( p->pCache->bPurgeable ){
- pcacheTrace(("%p.UNPIN %d\n", p->pCache, p->pgno));
+ pcacheTrace(("%p.UNPIN %d\n", p->pCache, p->pgno));
sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
- pcacheDump(p->pCache);
+ pcacheDump(p->pCache);
}
}
/*
-** Compute the number of pages of cache requested. p->szCache is the
+** Compute the number of pages of cache requested. p->szCache is the
** cache size requested by the "PRAGMA cache_size" statement.
*/
static int numberOfCachePages(PCache *p){
@@ -50108,12 +50108,12 @@ SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); }
** has already been allocated and is passed in as the p pointer.
** The caller discovers how much space needs to be allocated by
** calling sqlite3PcacheSize().
-**
-** szExtra is some extra space allocated for each page. The first
-** 8 bytes of the extra space will be zeroed as the page is allocated,
-** but remaining content will be uninitialized. Though it is opaque
-** to this module, the extra space really ends up being the MemPage
-** structure in the pager.
+**
+** szExtra is some extra space allocated for each page. The first
+** 8 bytes of the extra space will be zeroed as the page is allocated,
+** but remaining content will be uninitialized. Though it is opaque
+** to this module, the extra space really ends up being the MemPage
+** structure in the pager.
*/
SQLITE_PRIVATE int sqlite3PcacheOpen(
int szPage, /* Size of every page */
@@ -50126,14 +50126,14 @@ SQLITE_PRIVATE int sqlite3PcacheOpen(
memset(p, 0, sizeof(PCache));
p->szPage = 1;
p->szExtra = szExtra;
- assert( szExtra>=8 ); /* First 8 bytes will be zeroed */
+ assert( szExtra>=8 ); /* First 8 bytes will be zeroed */
p->bPurgeable = bPurgeable;
p->eCreate = 2;
p->xStress = xStress;
p->pStress = pStress;
p->szCache = 100;
- p->szSpill = 1;
- pcacheTrace(("%p.OPEN szPage %d bPurgeable %d\n",p,szPage,bPurgeable));
+ p->szSpill = 1;
+ pcacheTrace(("%p.OPEN szPage %d bPurgeable %d\n",p,szPage,bPurgeable));
return sqlite3PcacheSetPageSize(p, szPage);
}
@@ -50142,21 +50142,21 @@ SQLITE_PRIVATE int sqlite3PcacheOpen(
** are no outstanding page references when this function is called.
*/
SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
- assert( pCache->nRefSum==0 && pCache->pDirty==0 );
+ assert( pCache->nRefSum==0 && pCache->pDirty==0 );
if( pCache->szPage ){
sqlite3_pcache *pNew;
pNew = sqlite3GlobalConfig.pcache2.xCreate(
szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
pCache->bPurgeable
);
- if( pNew==0 ) return SQLITE_NOMEM_BKPT;
+ if( pNew==0 ) return SQLITE_NOMEM_BKPT;
sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
if( pCache->pCache ){
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
}
pCache->pCache = pNew;
pCache->szPage = szPage;
- pcacheTrace(("%p.PAGESIZE %d\n",pCache,szPage));
+ pcacheTrace(("%p.PAGESIZE %d\n",pCache,szPage));
}
return SQLITE_OK;
}
@@ -50191,12 +50191,12 @@ SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(
int createFlag /* If true, create page if it does not exist already */
){
int eCreate;
- sqlite3_pcache_page *pRes;
+ sqlite3_pcache_page *pRes;
assert( pCache!=0 );
assert( pCache->pCache!=0 );
assert( createFlag==3 || createFlag==0 );
- assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) );
+ assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) );
/* eCreate defines what to do if the page does not exist.
** 0 Do not allocate a new page. (createFlag==0)
@@ -50209,15 +50209,15 @@ SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(
assert( eCreate==0 || eCreate==1 || eCreate==2 );
assert( createFlag==0 || pCache->eCreate==eCreate );
assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
- pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
- pcacheTrace(("%p.FETCH %d%s (result: %p)\n",pCache,pgno,
- createFlag?" create":"",pRes));
- return pRes;
+ pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
+ pcacheTrace(("%p.FETCH %d%s (result: %p)\n",pCache,pgno,
+ createFlag?" create":"",pRes));
+ return pRes;
}
/*
** If the sqlite3PcacheFetch() routine is unable to allocate a new
-** page because no clean pages are available for reuse and the cache
+** page because no clean pages are available for reuse and the cache
** size limit has been reached, then this routine can be invoked to
** try harder to allocate a page. This routine might invoke the stress
** callback to spill dirty pages to the journal. It will then try to
@@ -50234,43 +50234,43 @@ SQLITE_PRIVATE int sqlite3PcacheFetchStress(
PgHdr *pPg;
if( pCache->eCreate==2 ) return 0;
- if( sqlite3PcachePagecount(pCache)>pCache->szSpill ){
+ if( sqlite3PcachePagecount(pCache)>pCache->szSpill ){
/* Find a dirty page to write-out and recycle. First try to find a
- ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
+ ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
** cleared), but if that is not possible settle for any other
- ** unreferenced dirty page.
- **
- ** If the LRU page in the dirty list that has a clear PGHDR_NEED_SYNC
- ** flag is currently referenced, then the following may leave pSynced
- ** set incorrectly (pointing to other than the LRU page with NEED_SYNC
- ** cleared). This is Ok, as pSynced is just an optimization. */
+ ** unreferenced dirty page.
+ **
+ ** If the LRU page in the dirty list that has a clear PGHDR_NEED_SYNC
+ ** flag is currently referenced, then the following may leave pSynced
+ ** set incorrectly (pointing to other than the LRU page with NEED_SYNC
+ ** cleared). This is Ok, as pSynced is just an optimization. */
for(pPg=pCache->pSynced;
pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC));
- pPg=pPg->pDirtyPrev
- );
- pCache->pSynced = pPg;
- if( !pPg ){
- for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
- }
- if( pPg ){
- int rc;
+ pPg=pPg->pDirtyPrev
+ );
+ pCache->pSynced = pPg;
+ if( !pPg ){
+ for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
+ }
+ if( pPg ){
+ int rc;
#ifdef SQLITE_LOG_CACHE_SPILL
sqlite3_log(SQLITE_FULL,
- "spill page %d making room for %d - cache used: %d/%d",
- pPg->pgno, pgno,
+ "spill page %d making room for %d - cache used: %d/%d",
+ pPg->pgno, pgno,
sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache),
numberOfCachePages(pCache));
#endif
- pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno));
- rc = pCache->xStress(pCache->pStress, pPg);
- pcacheDump(pCache);
- if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
- return rc;
- }
+ pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno));
+ rc = pCache->xStress(pCache->pStress, pPg);
+ pcacheDump(pCache);
+ if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
+ return rc;
+ }
}
}
*ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
- return *ppPage==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
+ return *ppPage==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
}
/*
@@ -50291,11 +50291,11 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
assert( pPage!=0 );
pPgHdr = (PgHdr*)pPage->pExtra;
assert( pPgHdr->pPage==0 );
- memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty));
+ memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty));
pPgHdr->pPage = pPage;
pPgHdr->pData = pPage->pBuf;
pPgHdr->pExtra = (void *)&pPgHdr[1];
- memset(pPgHdr->pExtra, 0, 8);
+ memset(pPgHdr->pExtra, 0, 8);
pPgHdr->pCache = pCache;
pPgHdr->pgno = pgno;
pPgHdr->flags = PGHDR_CLEAN;
@@ -50321,9 +50321,9 @@ SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(
if( !pPgHdr->pPage ){
return pcacheFetchFinishWithInit(pCache, pgno, pPage);
}
- pCache->nRefSum++;
+ pCache->nRefSum++;
pPgHdr->nRef++;
- assert( sqlite3PcachePageSanity(pPgHdr) );
+ assert( sqlite3PcachePageSanity(pPgHdr) );
return pPgHdr;
}
@@ -50333,11 +50333,11 @@ SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(
*/
SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
assert( p->nRef>0 );
- p->pCache->nRefSum--;
- if( (--p->nRef)==0 ){
+ p->pCache->nRefSum--;
+ if( (--p->nRef)==0 ){
if( p->flags&PGHDR_CLEAN ){
pcacheUnpin(p);
- }else{
+ }else{
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
}
}
@@ -50348,9 +50348,9 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
*/
SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
assert(p->nRef>0);
- assert( sqlite3PcachePageSanity(p) );
+ assert( sqlite3PcachePageSanity(p) );
p->nRef++;
- p->pCache->nRefSum++;
+ p->pCache->nRefSum++;
}
/*
@@ -50360,11 +50360,11 @@ SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
*/
SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
assert( p->nRef==1 );
- assert( sqlite3PcachePageSanity(p) );
+ assert( sqlite3PcachePageSanity(p) );
if( p->flags&PGHDR_DIRTY ){
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
}
- p->pCache->nRefSum--;
+ p->pCache->nRefSum--;
sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
}
@@ -50374,16 +50374,16 @@ SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
*/
SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
assert( p->nRef>0 );
- assert( sqlite3PcachePageSanity(p) );
- if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/
+ assert( sqlite3PcachePageSanity(p) );
+ if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/
p->flags &= ~PGHDR_DONT_WRITE;
if( p->flags & PGHDR_CLEAN ){
p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN);
- pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno));
+ pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno));
assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY );
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
}
- assert( sqlite3PcachePageSanity(p) );
+ assert( sqlite3PcachePageSanity(p) );
}
}
@@ -50392,16 +50392,16 @@ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
** make it so.
*/
SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
- assert( sqlite3PcachePageSanity(p) );
- assert( (p->flags & PGHDR_DIRTY)!=0 );
- assert( (p->flags & PGHDR_CLEAN)==0 );
- pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
- p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
- p->flags |= PGHDR_CLEAN;
- pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno));
- assert( sqlite3PcachePageSanity(p) );
- if( p->nRef==0 ){
- pcacheUnpin(p);
+ assert( sqlite3PcachePageSanity(p) );
+ assert( (p->flags & PGHDR_DIRTY)!=0 );
+ assert( (p->flags & PGHDR_CLEAN)==0 );
+ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
+ p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
+ p->flags |= PGHDR_CLEAN;
+ pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno));
+ assert( sqlite3PcachePageSanity(p) );
+ if( p->nRef==0 ){
+ pcacheUnpin(p);
}
}
@@ -50410,25 +50410,25 @@ SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
*/
SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){
PgHdr *p;
- pcacheTrace(("%p.CLEAN-ALL\n",pCache));
+ pcacheTrace(("%p.CLEAN-ALL\n",pCache));
while( (p = pCache->pDirty)!=0 ){
sqlite3PcacheMakeClean(p);
}
}
/*
-** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages.
-*/
-SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache *pCache){
- PgHdr *p;
- pcacheTrace(("%p.CLEAR-WRITEABLE\n",pCache));
- for(p=pCache->pDirty; p; p=p->pDirtyNext){
- p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
- }
- pCache->pSynced = pCache->pDirtyTail;
-}
-
-/*
+** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages.
+*/
+SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache *pCache){
+ PgHdr *p;
+ pcacheTrace(("%p.CLEAR-WRITEABLE\n",pCache));
+ for(p=pCache->pDirty; p; p=p->pDirtyNext){
+ p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
+ }
+ pCache->pSynced = pCache->pDirtyTail;
+}
+
+/*
** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
*/
SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){
@@ -50446,8 +50446,8 @@ SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
PCache *pCache = p->pCache;
assert( p->nRef>0 );
assert( newPgno>0 );
- assert( sqlite3PcachePageSanity(p) );
- pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
+ assert( sqlite3PcachePageSanity(p) );
+ pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
p->pgno = newPgno;
if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
@@ -50468,7 +50468,7 @@ SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
if( pCache->pCache ){
PgHdr *p;
PgHdr *pNext;
- pcacheTrace(("%p.TRUNCATE %d\n",pCache,pgno));
+ pcacheTrace(("%p.TRUNCATE %d\n",pCache,pgno));
for(p=pCache->pDirty; p; p=pNext){
pNext = p->pDirtyNext;
/* This routine never gets call with a positive pgno except right
@@ -50476,16 +50476,16 @@ SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
** it must be that pgno==0.
*/
assert( p->pgno>0 );
- if( p->pgno>pgno ){
+ if( p->pgno>pgno ){
assert( p->flags&PGHDR_DIRTY );
sqlite3PcacheMakeClean(p);
}
}
- if( pgno==0 && pCache->nRefSum ){
+ if( pgno==0 && pCache->nRefSum ){
sqlite3_pcache_page *pPage1;
pPage1 = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0);
if( ALWAYS(pPage1) ){ /* Page 1 is always available in cache, because
- ** pCache->nRefSum>0 */
+ ** pCache->nRefSum>0 */
memset(pPage1->pBuf, 0, pCache->szPage);
pgno = 1;
}
@@ -50499,7 +50499,7 @@ SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
*/
SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
assert( pCache->pCache!=0 );
- pcacheTrace(("%p.CLOSE\n",pCache));
+ pcacheTrace(("%p.CLOSE\n",pCache));
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
}
@@ -50512,29 +50512,29 @@ SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){
/*
** Merge two lists of pages connected by pDirty and in pgno order.
-** Do not bother fixing the pDirtyPrev pointers.
+** Do not bother fixing the pDirtyPrev pointers.
*/
static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
PgHdr result, *pTail;
pTail = &result;
- assert( pA!=0 && pB!=0 );
- for(;;){
+ assert( pA!=0 && pB!=0 );
+ for(;;){
if( pA->pgno<pB->pgno ){
pTail->pDirty = pA;
pTail = pA;
pA = pA->pDirty;
- if( pA==0 ){
- pTail->pDirty = pB;
- break;
- }
+ if( pA==0 ){
+ pTail->pDirty = pB;
+ break;
+ }
}else{
pTail->pDirty = pB;
pTail = pB;
pB = pB->pDirty;
- if( pB==0 ){
- pTail->pDirty = pA;
- break;
- }
+ if( pB==0 ){
+ pTail->pDirty = pA;
+ break;
+ }
}
}
return result.pDirty;
@@ -50577,8 +50577,8 @@ static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
}
p = a[0];
for(i=1; i<N_SORT_BUCKET; i++){
- if( a[i]==0 ) continue;
- p = p ? pcacheMergeDirtyList(p, a[i]) : a[i];
+ if( a[i]==0 ) continue;
+ p = p ? pcacheMergeDirtyList(p, a[i]) : a[i];
}
return p;
}
@@ -50595,13 +50595,13 @@ SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
}
/*
-** Return the total number of references to all pages held by the cache.
-**
-** This is not the total number of pages referenced, but the sum of the
-** reference count for all pages.
+** Return the total number of references to all pages held by the cache.
+**
+** This is not the total number of pages referenced, but the sum of the
+** reference count for all pages.
*/
SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
- return pCache->nRefSum;
+ return pCache->nRefSum;
}
/*
@@ -50639,25 +50639,25 @@ SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
}
/*
-** Set the suggested cache-spill value. Make no changes if if the
-** argument is zero. Return the effective cache-spill size, which will
-** be the larger of the szSpill and szCache.
-*/
-SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *p, int mxPage){
- int res;
- assert( p->pCache!=0 );
- if( mxPage ){
- if( mxPage<0 ){
- mxPage = (int)((-1024*(i64)mxPage)/(p->szPage+p->szExtra));
- }
- p->szSpill = mxPage;
- }
- res = numberOfCachePages(p);
+** Set the suggested cache-spill value. Make no changes if if the
+** argument is zero. Return the effective cache-spill size, which will
+** be the larger of the szSpill and szCache.
+*/
+SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *p, int mxPage){
+ int res;
+ assert( p->pCache!=0 );
+ if( mxPage ){
+ if( mxPage<0 ){
+ mxPage = (int)((-1024*(i64)mxPage)/(p->szPage+p->szExtra));
+ }
+ p->szSpill = mxPage;
+ }
+ res = numberOfCachePages(p);
if( res<p->szSpill ) res = p->szSpill;
- return res;
-}
-
-/*
+ return res;
+}
+
+/*
** Free up as much memory as possible from the page cache.
*/
SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
@@ -50671,17 +50671,17 @@ SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
*/
SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
-/*
-** Return the number of dirty pages currently in the cache, as a percentage
-** of the configured cache size.
-*/
-SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache *pCache){
- PgHdr *pDirty;
- int nDirty = 0;
- int nCache = numberOfCachePages(pCache);
- for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++;
- return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
-}
+/*
+** Return the number of dirty pages currently in the cache, as a percentage
+** of the configured cache size.
+*/
+SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache *pCache){
+ PgHdr *pDirty;
+ int nDirty = 0;
+ int nCache = numberOfCachePages(pCache);
+ for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++;
+ return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
+}
#ifdef SQLITE_DIRECT_OVERFLOW_READ
/*
@@ -50775,7 +50775,7 @@ SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHd
** that is allocated when the page cache is created. The size of the local
** bulk allocation can be adjusted using
**
-** sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N).
+** sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N).
**
** If N is positive, then N pages worth of memory are allocated using a single
** sqlite3Malloc() call and that memory is used for the first N pages allocated.
@@ -50797,11 +50797,11 @@ typedef struct PgHdr1 PgHdr1;
typedef struct PgFreeslot PgFreeslot;
typedef struct PGroup PGroup;
-/*
+/*
** Each cache entry is represented by an instance of the following
-** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
+** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
** PgHdr1.pCache->szPage bytes is allocated directly before this structure
-** in memory.
+** in memory.
**
** Note: Variables isBulkLocal and isAnchor were once type "u8". That works,
** but causes a 2-byte gap in the structure for most architectures (since
@@ -50812,26 +50812,26 @@ typedef struct PGroup PGroup;
** can cause a valgrind error if the unitialized gap is accessed. Using u16
** ensures there is no such gap, and therefore no bytes of unitialized memory
** in the structure.
-*/
-struct PgHdr1 {
- sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */
- unsigned int iKey; /* Key value (page number) */
+*/
+struct PgHdr1 {
+ sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */
+ unsigned int iKey; /* Key value (page number) */
u16 isBulkLocal; /* This page from bulk local storage */
u16 isAnchor; /* This is the PGroup.lru element */
- PgHdr1 *pNext; /* Next in hash table chain */
- PCache1 *pCache; /* Cache that currently owns this page */
- PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
- PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
+ PgHdr1 *pNext; /* Next in hash table chain */
+ PCache1 *pCache; /* Cache that currently owns this page */
+ PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
+ PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
/* NB: pLruPrev is only valid if pLruNext!=0 */
-};
-
-/*
+};
+
+/*
** A page is pinned if it is not on the LRU list. To be "pinned" means
** that the page is in active use and must not be deallocated.
-*/
-#define PAGE_IS_PINNED(p) ((p)->pLruNext==0)
-#define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0)
-
+*/
+#define PAGE_IS_PINNED(p) ((p)->pLruNext==0)
+#define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0)
+
/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
** of one or more PCaches that are able to recycle each other's unpinned
** pages when they are under memory pressure. A PGroup is an instance of
@@ -50859,8 +50859,8 @@ struct PGroup {
unsigned int nMaxPage; /* Sum of nMax for purgeable caches */
unsigned int nMinPage; /* Sum of nMin for purgeable caches */
unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */
- unsigned int nPurgeable; /* Number of purgeable pages allocated */
- PgHdr1 lru; /* The beginning and end of the LRU list */
+ unsigned int nPurgeable; /* Number of purgeable pages allocated */
+ PgHdr1 lru; /* The beginning and end of the LRU list */
};
/* Each page cache is an instance of the following object. Every
@@ -50873,13 +50873,13 @@ struct PGroup {
*/
struct PCache1 {
/* Cache configuration parameters. Page size (szPage) and the purgeable
- ** flag (bPurgeable) and the pnPurgeable pointer are all set when the
+ ** flag (bPurgeable) and the pnPurgeable pointer are all set when the
** cache is created and are never changed thereafter. nMax may be
** modified at any time by a call to the pcache1Cachesize() method.
** The PGroup mutex must be held when accessing nMax.
*/
PGroup *pGroup; /* PGroup this cache belongs to */
- unsigned int *pnPurgeable; /* Pointer to pGroup->nPurgeable */
+ unsigned int *pnPurgeable; /* Pointer to pGroup->nPurgeable */
int szPage; /* Size of database content section */
int szExtra; /* sizeof(MemPage)+sizeof(PgHdr) */
int szAlloc; /* Total size of one pcache line */
@@ -50961,7 +50961,7 @@ static SQLITE_WSD struct PCacheGlobal {
/******************************************************************************/
/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
-
+
/*
** This function is called during initialization if a static buffer is
** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE
@@ -50975,7 +50975,7 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
if( pcache1.isInit ){
PgFreeslot *p;
if( pBuf==0 ) sz = n = 0;
- if( n==0 ) sz = 0;
+ if( n==0 ) sz = 0;
sz = ROUNDDOWN8(sz);
pcache1.szSlot = sz;
pcache1.nSlot = pcache1.nFreeSlot = n;
@@ -51010,23 +51010,23 @@ static int pcache1InitBulk(PCache1 *pCache){
szBulk = -1024 * (i64)pcache1.nInitPage;
}
if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){
- szBulk = pCache->szAlloc*(i64)pCache->nMax;
+ szBulk = pCache->szAlloc*(i64)pCache->nMax;
}
zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
sqlite3EndBenignMalloc();
if( zBulk ){
int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
- do{
+ do{
PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage];
pX->page.pBuf = zBulk;
pX->page.pExtra = &pX[1];
pX->isBulkLocal = 1;
- pX->isAnchor = 0;
+ pX->isAnchor = 0;
pX->pNext = pCache->pFree;
pX->pLruPrev = 0; /* Initializing this saves a valgrind error */
pCache->pFree = pX;
zBulk += pCache->szAlloc;
- }while( --nBulk );
+ }while( --nBulk );
}
return pCache->pFree!=0;
}
@@ -51051,7 +51051,7 @@ static void *pcache1Alloc(int nByte){
pcache1.nFreeSlot--;
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
assert( pcache1.nFreeSlot>=0 );
- sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
+ sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
}
sqlite3_mutex_leave(pcache1.mutex);
@@ -51065,7 +51065,7 @@ static void *pcache1Alloc(int nByte){
if( p ){
int sz = sqlite3MallocSize(p);
sqlite3_mutex_enter(pcache1.mutex);
- sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
+ sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
sqlite3_mutex_leave(pcache1.mutex);
}
@@ -51080,7 +51080,7 @@ static void *pcache1Alloc(int nByte){
*/
static void pcache1Free(void *p){
if( p==0 ) return;
- if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){
+ if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){
PgFreeslot *pSlot;
sqlite3_mutex_enter(pcache1.mutex);
sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
@@ -51095,13 +51095,13 @@ static void pcache1Free(void *p){
assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
- {
- int nFreed = 0;
- nFreed = sqlite3MallocSize(p);
- sqlite3_mutex_enter(pcache1.mutex);
- sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
- sqlite3_mutex_leave(pcache1.mutex);
- }
+ {
+ int nFreed = 0;
+ nFreed = sqlite3MallocSize(p);
+ sqlite3_mutex_enter(pcache1.mutex);
+ sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
+ sqlite3_mutex_leave(pcache1.mutex);
+ }
#endif
sqlite3_free(p);
}
@@ -51128,7 +51128,7 @@ static int pcache1MemSize(void *p){
/*
** Allocate a new page object initially associated with cache pCache.
*/
-static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
+static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
PgHdr1 *p = 0;
void *pPg;
@@ -51147,7 +51147,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
assert( pCache->pGroup==&pcache1.grp );
pcache1LeaveMutex(pCache->pGroup);
#endif
- if( benignMalloc ){ sqlite3BeginBenignMalloc(); }
+ if( benignMalloc ){ sqlite3BeginBenignMalloc(); }
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
pPg = pcache1Alloc(pCache->szPage);
p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
@@ -51159,7 +51159,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
#else
pPg = pcache1Alloc(pCache->szAlloc);
#endif
- if( benignMalloc ){ sqlite3EndBenignMalloc(); }
+ if( benignMalloc ){ sqlite3EndBenignMalloc(); }
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
pcache1EnterMutex(pCache->pGroup);
#endif
@@ -51170,10 +51170,10 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
p->page.pBuf = pPg;
p->page.pExtra = &p[1];
p->isBulkLocal = 0;
- p->isAnchor = 0;
+ p->isAnchor = 0;
p->pLruPrev = 0; /* Initializing this saves a valgrind error */
}
- (*pCache->pnPurgeable)++;
+ (*pCache->pnPurgeable)++;
return p;
}
@@ -51194,7 +51194,7 @@ static void pcache1FreePage(PgHdr1 *p){
sqlite3_free(p);
#endif
}
- (*pCache->pnPurgeable)--;
+ (*pCache->pnPurgeable)--;
}
/*
@@ -51291,18 +51291,18 @@ static void pcache1ResizeHash(PCache1 *p){
*/
static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){
assert( pPage!=0 );
- assert( PAGE_IS_UNPINNED(pPage) );
- assert( pPage->pLruNext );
- assert( pPage->pLruPrev );
- assert( sqlite3_mutex_held(pPage->pCache->pGroup->mutex) );
- pPage->pLruPrev->pLruNext = pPage->pLruNext;
- pPage->pLruNext->pLruPrev = pPage->pLruPrev;
+ assert( PAGE_IS_UNPINNED(pPage) );
+ assert( pPage->pLruNext );
+ assert( pPage->pLruPrev );
+ assert( sqlite3_mutex_held(pPage->pCache->pGroup->mutex) );
+ pPage->pLruPrev->pLruNext = pPage->pLruNext;
+ pPage->pLruNext->pLruPrev = pPage->pLruPrev;
pPage->pLruNext = 0;
/* pPage->pLruPrev = 0;
** No need to clear pLruPrev as it is never accessed if pLruNext is 0 */
- assert( pPage->isAnchor==0 );
- assert( pPage->pCache->pGroup->lru.isAnchor==1 );
- pPage->pCache->nRecyclable--;
+ assert( pPage->isAnchor==0 );
+ assert( pPage->pCache->pGroup->lru.isAnchor==1 );
+ pPage->pCache->nRecyclable--;
return pPage;
}
@@ -51334,13 +51334,13 @@ static void pcache1RemoveFromHash(PgHdr1 *pPage, int freeFlag){
*/
static void pcache1EnforceMaxPage(PCache1 *pCache){
PGroup *pGroup = pCache->pGroup;
- PgHdr1 *p;
+ PgHdr1 *p;
assert( sqlite3_mutex_held(pGroup->mutex) );
- while( pGroup->nPurgeable>pGroup->nMaxPage
- && (p=pGroup->lru.pLruPrev)->isAnchor==0
- ){
+ while( pGroup->nPurgeable>pGroup->nMaxPage
+ && (p=pGroup->lru.pLruPrev)->isAnchor==0
+ ){
assert( p->pCache->pGroup==pGroup );
- assert( PAGE_IS_UNPINNED(p) );
+ assert( PAGE_IS_UNPINNED(p) );
pcache1PinPage(p);
pcache1RemoveFromHash(p, 1);
}
@@ -51361,45 +51361,45 @@ static void pcache1TruncateUnsafe(
PCache1 *pCache, /* The cache to truncate */
unsigned int iLimit /* Drop pages with this pgno or larger */
){
- TESTONLY( int nPage = 0; ) /* To assert pCache->nPage is correct */
- unsigned int h, iStop;
+ TESTONLY( int nPage = 0; ) /* To assert pCache->nPage is correct */
+ unsigned int h, iStop;
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
- assert( pCache->iMaxKey >= iLimit );
- assert( pCache->nHash > 0 );
- if( pCache->iMaxKey - iLimit < pCache->nHash ){
- /* If we are just shaving the last few pages off the end of the
- ** cache, then there is no point in scanning the entire hash table.
- ** Only scan those hash slots that might contain pages that need to
- ** be removed. */
- h = iLimit % pCache->nHash;
- iStop = pCache->iMaxKey % pCache->nHash;
- TESTONLY( nPage = -10; ) /* Disable the pCache->nPage validity check */
- }else{
- /* This is the general case where many pages are being removed.
- ** It is necessary to scan the entire hash table */
- h = pCache->nHash/2;
- iStop = h - 1;
- }
- for(;;){
- PgHdr1 **pp;
+ assert( pCache->iMaxKey >= iLimit );
+ assert( pCache->nHash > 0 );
+ if( pCache->iMaxKey - iLimit < pCache->nHash ){
+ /* If we are just shaving the last few pages off the end of the
+ ** cache, then there is no point in scanning the entire hash table.
+ ** Only scan those hash slots that might contain pages that need to
+ ** be removed. */
+ h = iLimit % pCache->nHash;
+ iStop = pCache->iMaxKey % pCache->nHash;
+ TESTONLY( nPage = -10; ) /* Disable the pCache->nPage validity check */
+ }else{
+ /* This is the general case where many pages are being removed.
+ ** It is necessary to scan the entire hash table */
+ h = pCache->nHash/2;
+ iStop = h - 1;
+ }
+ for(;;){
+ PgHdr1 **pp;
PgHdr1 *pPage;
- assert( h<pCache->nHash );
+ assert( h<pCache->nHash );
pp = &pCache->apHash[h];
while( (pPage = *pp)!=0 ){
if( pPage->iKey>=iLimit ){
pCache->nPage--;
*pp = pPage->pNext;
- if( PAGE_IS_UNPINNED(pPage) ) pcache1PinPage(pPage);
+ if( PAGE_IS_UNPINNED(pPage) ) pcache1PinPage(pPage);
pcache1FreePage(pPage);
}else{
pp = &pPage->pNext;
- TESTONLY( if( nPage>=0 ) nPage++; )
+ TESTONLY( if( nPage>=0 ) nPage++; )
}
}
- if( h==iStop ) break;
- h = (h+1) % pCache->nHash;
+ if( h==iStop ) break;
+ h = (h+1) % pCache->nHash;
}
- assert( nPage<0 || pCache->nPage==(unsigned)nPage );
+ assert( nPage<0 || pCache->nPage==(unsigned)nPage );
}
/******************************************************************************/
@@ -51439,8 +51439,8 @@ static int pcache1Init(void *NotUsed){
#if SQLITE_THREADSAFE
if( sqlite3GlobalConfig.bCoreMutex ){
- pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU);
- pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM);
+ pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU);
+ pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM);
}
#endif
if( pcache1.separateCache
@@ -51493,10 +51493,10 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
pGroup = &pcache1.grp;
}
pcache1EnterMutex(pGroup);
- if( pGroup->lru.isAnchor==0 ){
- pGroup->lru.isAnchor = 1;
- pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
- }
+ if( pGroup->lru.isAnchor==0 ){
+ pGroup->lru.isAnchor = 1;
+ pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
+ }
pCache->pGroup = pGroup;
pCache->szPage = szPage;
pCache->szExtra = szExtra;
@@ -51507,8 +51507,8 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
pCache->nMin = 10;
pGroup->nMinPage += pCache->nMin;
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
- pCache->pnPurgeable = &pGroup->nPurgeable;
- }else{
+ pCache->pnPurgeable = &pGroup->nPurgeable;
+ }else{
pCache->pnPurgeable = &pCache->nPurgeableDummy;
}
pcache1LeaveMutex(pGroup);
@@ -51612,12 +51612,12 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
/* Step 4. Try to recycle a page. */
if( pCache->bPurgeable
- && !pGroup->lru.pLruPrev->isAnchor
+ && !pGroup->lru.pLruPrev->isAnchor
&& ((pCache->nPage+1>=pCache->nMax) || pcache1UnderMemoryPressure(pCache))
){
PCache1 *pOther;
- pPage = pGroup->lru.pLruPrev;
- assert( PAGE_IS_UNPINNED(pPage) );
+ pPage = pGroup->lru.pLruPrev;
+ assert( PAGE_IS_UNPINNED(pPage) );
pcache1RemoveFromHash(pPage, 0);
pcache1PinPage(pPage);
pOther = pPage->pCache;
@@ -51625,7 +51625,7 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
pcache1FreePage(pPage);
pPage = 0;
}else{
- pGroup->nPurgeable -= (pOther->bPurgeable - pCache->bPurgeable);
+ pGroup->nPurgeable -= (pOther->bPurgeable - pCache->bPurgeable);
}
}
@@ -51633,7 +51633,7 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
** attempt to allocate a new one.
*/
if( !pPage ){
- pPage = pcache1AllocPage(pCache, createFlag==1);
+ pPage = pcache1AllocPage(pCache, createFlag==1);
}
if( pPage ){
@@ -51725,12 +51725,12 @@ static PgHdr1 *pcache1FetchNoMutex(
pPage = pCache->apHash[iKey % pCache->nHash];
while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
- /* Step 2: If the page was found in the hash table, then return it.
- ** If the page was not in the hash table and createFlag is 0, abort.
- ** Otherwise (page not in hash and createFlag!=0) continue with
- ** subsequent steps to try to create the page. */
+ /* Step 2: If the page was found in the hash table, then return it.
+ ** If the page was not in the hash table and createFlag is 0, abort.
+ ** Otherwise (page not in hash and createFlag!=0) continue with
+ ** subsequent steps to try to create the page. */
if( pPage ){
- if( PAGE_IS_UNPINNED(pPage) ){
+ if( PAGE_IS_UNPINNED(pPage) ){
return pcache1PinPage(pPage);
}else{
return pPage;
@@ -51805,16 +51805,16 @@ static void pcache1Unpin(
** part of the PGroup LRU list.
*/
assert( pPage->pLruNext==0 );
- assert( PAGE_IS_PINNED(pPage) );
+ assert( PAGE_IS_PINNED(pPage) );
- if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){
+ if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){
pcache1RemoveFromHash(pPage, 1);
}else{
/* Add the page to the PGroup LRU list. */
- PgHdr1 **ppFirst = &pGroup->lru.pLruNext;
- pPage->pLruPrev = &pGroup->lru;
- (pPage->pLruNext = *ppFirst)->pLruPrev = pPage;
- *ppFirst = pPage;
+ PgHdr1 **ppFirst = &pGroup->lru.pLruNext;
+ pPage->pLruPrev = &pGroup->lru;
+ (pPage->pLruNext = *ppFirst)->pLruPrev = pPage;
+ *ppFirst = pPage;
pCache->nRecyclable++;
}
@@ -51884,7 +51884,7 @@ static void pcache1Destroy(sqlite3_pcache *p){
PGroup *pGroup = pCache->pGroup;
assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
pcache1EnterMutex(pGroup);
- if( pCache->nPage ) pcache1TruncateUnsafe(pCache, 0);
+ if( pCache->nPage ) pcache1TruncateUnsafe(pCache, 0);
assert( pGroup->nMaxPage >= pCache->nMax );
pGroup->nMaxPage -= pCache->nMax;
assert( pGroup->nMinPage >= pCache->nMin );
@@ -51948,18 +51948,18 @@ SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
int nFree = 0;
assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
assert( sqlite3_mutex_notheld(pcache1.mutex) );
- if( sqlite3GlobalConfig.pPage==0 ){
+ if( sqlite3GlobalConfig.pPage==0 ){
PgHdr1 *p;
pcache1EnterMutex(&pcache1.grp);
- while( (nReq<0 || nFree<nReq)
- && (p=pcache1.grp.lru.pLruPrev)!=0
- && p->isAnchor==0
- ){
+ while( (nReq<0 || nFree<nReq)
+ && (p=pcache1.grp.lru.pLruPrev)!=0
+ && p->isAnchor==0
+ ){
nFree += pcache1MemSize(p->page.pBuf);
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
nFree += sqlite3MemSize(p);
#endif
- assert( PAGE_IS_UNPINNED(p) );
+ assert( PAGE_IS_UNPINNED(p) );
pcache1PinPage(p);
pcache1RemoveFromHash(p, 1);
}
@@ -51982,11 +51982,11 @@ SQLITE_PRIVATE void sqlite3PcacheStats(
){
PgHdr1 *p;
int nRecyclable = 0;
- for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){
- assert( PAGE_IS_UNPINNED(p) );
+ for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){
+ assert( PAGE_IS_UNPINNED(p) );
nRecyclable++;
}
- *pnCurrent = pcache1.grp.nPurgeable;
+ *pnCurrent = pcache1.grp.nPurgeable;
*pnMax = (int)pcache1.grp.nMaxPage;
*pnMin = (int)pcache1.grp.nMinPage;
*pnRecyclable = nRecyclable;
@@ -52054,9 +52054,9 @@ SQLITE_PRIVATE void sqlite3PcacheStats(
** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST
** primitives are constant time. The cost of DESTROY is O(N).
**
-** TEST and SMALLEST may not be used by the same RowSet. This used to
-** be possible, but the feature was not used, so it was removed in order
-** to simplify the code.
+** TEST and SMALLEST may not be used by the same RowSet. This used to
+** be possible, but the feature was not used, so it was removed in order
+** to simplify the code.
*/
/* #include "sqliteInt.h" */
@@ -52181,11 +52181,11 @@ SQLITE_PRIVATE void sqlite3RowSetDelete(void *pArg){
*/
static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
assert( p!=0 );
- if( p->nFresh==0 ){ /*OPTIMIZATION-IF-FALSE*/
- /* We could allocate a fresh RowSetEntry each time one is needed, but it
- ** is more efficient to pull a preallocated entry from the pool */
+ if( p->nFresh==0 ){ /*OPTIMIZATION-IF-FALSE*/
+ /* We could allocate a fresh RowSetEntry each time one is needed, but it
+ ** is more efficient to pull a preallocated entry from the pool */
struct RowSetChunk *pNew;
- pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew));
+ pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew));
if( pNew==0 ){
return 0;
}
@@ -52217,9 +52217,9 @@ SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
pEntry->pRight = 0;
pLast = p->pLast;
if( pLast ){
- if( rowid<=pLast->v ){ /*OPTIMIZATION-IF-FALSE*/
- /* Avoid unnecessary sorts by preserving the ROWSET_SORTED flags
- ** where possible */
+ if( rowid<=pLast->v ){ /*OPTIMIZATION-IF-FALSE*/
+ /* Avoid unnecessary sorts by preserving the ROWSET_SORTED flags
+ ** where possible */
p->rsFlags &= ~ROWSET_SORTED;
}
pLast->pRight = pEntry;
@@ -52243,24 +52243,24 @@ static struct RowSetEntry *rowSetEntryMerge(
struct RowSetEntry *pTail;
pTail = &head;
- assert( pA!=0 && pB!=0 );
- for(;;){
+ assert( pA!=0 && pB!=0 );
+ for(;;){
assert( pA->pRight==0 || pA->v<=pA->pRight->v );
assert( pB->pRight==0 || pB->v<=pB->pRight->v );
- if( pA->v<=pB->v ){
- if( pA->v<pB->v ) pTail = pTail->pRight = pA;
+ if( pA->v<=pB->v ){
+ if( pA->v<pB->v ) pTail = pTail->pRight = pA;
pA = pA->pRight;
- if( pA==0 ){
- pTail->pRight = pB;
- break;
- }
- }else{
- pTail = pTail->pRight = pB;
+ if( pA==0 ){
+ pTail->pRight = pB;
+ break;
+ }
+ }else{
+ pTail = pTail->pRight = pB;
pB = pB->pRight;
- if( pB==0 ){
- pTail->pRight = pA;
- break;
- }
+ if( pB==0 ){
+ pTail->pRight = pA;
+ break;
+ }
}
}
return head.pRight;
@@ -52285,10 +52285,10 @@ static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){
aBucket[i] = pIn;
pIn = pNext;
}
- pIn = aBucket[0];
- for(i=1; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
- if( aBucket[i]==0 ) continue;
- pIn = pIn ? rowSetEntryMerge(pIn, aBucket[i]) : aBucket[i];
+ pIn = aBucket[0];
+ for(i=1; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
+ if( aBucket[i]==0 ) continue;
+ pIn = pIn ? rowSetEntryMerge(pIn, aBucket[i]) : aBucket[i];
}
return pIn;
}
@@ -52340,27 +52340,27 @@ static struct RowSetEntry *rowSetNDeepTree(
){
struct RowSetEntry *p; /* Root of the new tree */
struct RowSetEntry *pLeft; /* Left subtree */
- if( *ppList==0 ){ /*OPTIMIZATION-IF-TRUE*/
- /* Prevent unnecessary deep recursion when we run out of entries */
+ if( *ppList==0 ){ /*OPTIMIZATION-IF-TRUE*/
+ /* Prevent unnecessary deep recursion when we run out of entries */
return 0;
}
- if( iDepth>1 ){ /*OPTIMIZATION-IF-TRUE*/
- /* This branch causes a *balanced* tree to be generated. A valid tree
- ** is still generated without this branch, but the tree is wildly
- ** unbalanced and inefficient. */
- pLeft = rowSetNDeepTree(ppList, iDepth-1);
+ if( iDepth>1 ){ /*OPTIMIZATION-IF-TRUE*/
+ /* This branch causes a *balanced* tree to be generated. A valid tree
+ ** is still generated without this branch, but the tree is wildly
+ ** unbalanced and inefficient. */
+ pLeft = rowSetNDeepTree(ppList, iDepth-1);
+ p = *ppList;
+ if( p==0 ){ /*OPTIMIZATION-IF-FALSE*/
+ /* It is safe to always return here, but the resulting tree
+ ** would be unbalanced */
+ return pLeft;
+ }
+ p->pLeft = pLeft;
+ *ppList = p->pRight;
+ p->pRight = rowSetNDeepTree(ppList, iDepth-1);
+ }else{
p = *ppList;
- if( p==0 ){ /*OPTIMIZATION-IF-FALSE*/
- /* It is safe to always return here, but the resulting tree
- ** would be unbalanced */
- return pLeft;
- }
- p->pLeft = pLeft;
*ppList = p->pRight;
- p->pRight = rowSetNDeepTree(ppList, iDepth-1);
- }else{
- p = *ppList;
- *ppList = p->pRight;
p->pLeft = p->pRight = 0;
}
return p;
@@ -52395,31 +52395,31 @@ static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
** 0 if the RowSet is already empty.
**
** After this routine has been called, the sqlite3RowSetInsert()
-** routine may not be called again.
-**
-** This routine may not be called after sqlite3RowSetTest() has
-** been used. Older versions of RowSet allowed that, but as the
-** capability was not used by the code generator, it was removed
-** for code economy.
+** routine may not be called again.
+**
+** This routine may not be called after sqlite3RowSetTest() has
+** been used. Older versions of RowSet allowed that, but as the
+** capability was not used by the code generator, it was removed
+** for code economy.
*/
SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
assert( p!=0 );
- assert( p->pForest==0 ); /* Cannot be used with sqlite3RowSetText() */
+ assert( p->pForest==0 ); /* Cannot be used with sqlite3RowSetText() */
/* Merge the forest into a single sorted list on first call */
- if( (p->rsFlags & ROWSET_NEXT)==0 ){ /*OPTIMIZATION-IF-FALSE*/
- if( (p->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
- p->pEntry = rowSetEntrySort(p->pEntry);
- }
- p->rsFlags |= ROWSET_SORTED|ROWSET_NEXT;
- }
+ if( (p->rsFlags & ROWSET_NEXT)==0 ){ /*OPTIMIZATION-IF-FALSE*/
+ if( (p->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
+ p->pEntry = rowSetEntrySort(p->pEntry);
+ }
+ p->rsFlags |= ROWSET_SORTED|ROWSET_NEXT;
+ }
/* Return the next entry on the list */
if( p->pEntry ){
*pRowid = p->pEntry->v;
p->pEntry = p->pEntry->pRight;
- if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/
- /* Free memory immediately, rather than waiting on sqlite3_finalize() */
+ if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/
+ /* Free memory immediately, rather than waiting on sqlite3_finalize() */
sqlite3RowSetClear(p);
}
return 1;
@@ -52442,14 +52442,14 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64
/* This routine is never called after sqlite3RowSetNext() */
assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
- /* Sort entries into the forest on the first test of a new batch.
- ** To save unnecessary work, only do this when the batch number changes.
+ /* Sort entries into the forest on the first test of a new batch.
+ ** To save unnecessary work, only do this when the batch number changes.
*/
- if( iBatch!=pRowSet->iBatch ){ /*OPTIMIZATION-IF-FALSE*/
+ if( iBatch!=pRowSet->iBatch ){ /*OPTIMIZATION-IF-FALSE*/
p = pRowSet->pEntry;
if( p ){
struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
- if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
+ if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
/* Only sort the current set of entries if they need it */
p = rowSetEntrySort(p);
}
@@ -52540,21 +52540,21 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64
** the implementation of each function in log.c for further details.
*/
-#ifndef SQLITE_WAL_H
-#define SQLITE_WAL_H
+#ifndef SQLITE_WAL_H
+#define SQLITE_WAL_H
/* #include "sqliteInt.h" */
-/* Macros for extracting appropriate sync flags for either transaction
-** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)):
+/* Macros for extracting appropriate sync flags for either transaction
+** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)):
*/
-#define WAL_SYNC_FLAGS(X) ((X)&0x03)
-#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03)
+#define WAL_SYNC_FLAGS(X) ((X)&0x03)
+#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03)
#ifdef SQLITE_OMIT_WAL
# define sqlite3WalOpen(x,y,z) 0
# define sqlite3WalLimit(x,y)
-# define sqlite3WalClose(v,w,x,y,z) 0
+# define sqlite3WalClose(v,w,x,y,z) 0
# define sqlite3WalBeginReadTransaction(y,z) 0
# define sqlite3WalEndReadTransaction(z)
# define sqlite3WalDbsize(y) 0
@@ -52564,13 +52564,13 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64
# define sqlite3WalSavepoint(y,z)
# define sqlite3WalSavepointUndo(y,z) 0
# define sqlite3WalFrames(u,v,w,x,y,z) 0
-# define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0
+# define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0
# define sqlite3WalCallback(z) 0
# define sqlite3WalExclusiveMode(y,z) 0
# define sqlite3WalHeapMemory(z) 0
# define sqlite3WalFramesize(z) 0
# define sqlite3WalFindFrame(x,y,z) 0
-# define sqlite3WalFile(x) 0
+# define sqlite3WalFile(x) 0
#else
#define WAL_SAVEPOINT_NDATA 4
@@ -52582,7 +52582,7 @@ typedef struct Wal Wal;
/* Open and close a connection to a write-ahead log. */
SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
-SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *);
+SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *);
/* Set the limiting size of a WAL file. */
SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
@@ -52625,7 +52625,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
/* Copy pages from the log to the database file */
SQLITE_PRIVATE int sqlite3WalCheckpoint(
Wal *pWal, /* Write-ahead log connection */
- sqlite3 *db, /* Check this handle's interrupt flag */
+ sqlite3 *db, /* Check this handle's interrupt flag */
int eMode, /* One of PASSIVE, FULL and RESTART */
int (*xBusy)(void*), /* Function to call when busy */
void *pBusyArg, /* Context argument for xBusyHandler */
@@ -52654,14 +52654,14 @@ SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op);
*/
SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
-#ifdef SQLITE_ENABLE_SNAPSHOT
-SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);
-SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot);
-SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal);
+#ifdef SQLITE_ENABLE_SNAPSHOT
+SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);
+SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot);
+SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal);
SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot);
SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal);
-#endif
-
+#endif
+
#ifdef SQLITE_ENABLE_ZIPVFS
/* If the WAL file is not empty, return the number of bytes of content
** stored in each frame (i.e. the db page-size when the WAL was created).
@@ -52669,16 +52669,16 @@ SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal);
SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
#endif
-/* Return the sqlite3_file object for the WAL file */
-SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal);
-
+/* Return the sqlite3_file object for the WAL file */
+SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal);
+
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock);
SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db);
#endif
#endif /* ifndef SQLITE_OMIT_WAL */
-#endif /* SQLITE_WAL_H */
+#endif /* SQLITE_WAL_H */
/************** End of wal.h *************************************************/
/************** Continuing where we left off in pager.c **********************/
@@ -52789,8 +52789,8 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
** struct as its argument.
*/
-#define PAGERID(p) (SQLITE_PTR_TO_INT(p->fd))
-#define FILEHANDLEID(fd) (SQLITE_PTR_TO_INT(fd))
+#define PAGERID(p) (SQLITE_PTR_TO_INT(p->fd))
+#define FILEHANDLEID(fd) (SQLITE_PTR_TO_INT(fd))
/*
** The Pager.eState variable stores the current 'state' of a pager. A
@@ -53075,7 +53075,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
*/
#define MAX_SECTOR_SIZE 0x10000
-
+
/*
** An instance of the following structure is allocated for each active
** savepoint and statement transaction in the system. All such structures
@@ -53264,18 +53264,18 @@ struct PagerSavepoint {
** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode
** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX
** sub-codes.
-**
-** syncFlags, walSyncFlags
-**
-** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03).
-** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode
-** and contains the flags used to sync the checkpoint operations in the
-** lower two bits, and sync flags used for transaction commits in the WAL
-** file in bits 0x04 and 0x08. In other words, to get the correct sync flags
-** for checkpoint operations, use (walSyncFlags&0x03) and to get the correct
-** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note
-** that with synchronous=NORMAL in WAL mode, transaction commit is not synced
-** meaning that the 0x04 and 0x08 bits are both zero.
+**
+** syncFlags, walSyncFlags
+**
+** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03).
+** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode
+** and contains the flags used to sync the checkpoint operations in the
+** lower two bits, and sync flags used for transaction commits in the WAL
+** file in bits 0x04 and 0x08. In other words, to get the correct sync flags
+** for checkpoint operations, use (walSyncFlags&0x03) and to get the correct
+** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note
+** that with synchronous=NORMAL in WAL mode, transaction commit is not synced
+** meaning that the 0x04 and 0x08 bits are both zero.
*/
struct Pager {
sqlite3_vfs *pVfs; /* OS functions to use for IO */
@@ -53284,9 +53284,9 @@ struct Pager {
u8 useJournal; /* Use a rollback journal on this file */
u8 noSync; /* Do not sync the journal if true */
u8 fullSync; /* Do extra syncs of the journal for robustness */
- u8 extraSync; /* sync directory after journal delete */
+ u8 extraSync; /* sync directory after journal delete */
u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */
- u8 walSyncFlags; /* See description above */
+ u8 walSyncFlags; /* See description above */
u8 tempFile; /* zFilename is a temporary or immutable file */
u8 noLock; /* Do not lock (except in WAL mode) */
u8 readOnly; /* True for a read-only database */
@@ -53309,7 +53309,7 @@ struct Pager {
u8 doNotSpill; /* Do not spill the cache when non-zero */
u8 subjInMemory; /* True to use in-memory sub-journals */
u8 bUseFetch; /* True to use xFetch() */
- u8 hasHeldSharedLock; /* True if a shared lock has ever been held */
+ u8 hasHeldSharedLock; /* True if a shared lock has ever been held */
Pgno dbSize; /* Number of pages in the database */
Pgno dbOrigSize; /* dbSize before the current transaction */
Pgno dbFileSize; /* Number of pages in the database file */
@@ -53353,7 +53353,7 @@ struct Pager {
int nRead; /* Database pages read */
#endif
void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
- int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
+ int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */
PCache *pPCache; /* Pointer to page cache object */
#ifndef SQLITE_OMIT_WAL
@@ -53484,11 +53484,11 @@ SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
}
#endif
return 1;
-}
-#endif
+}
+#endif
#ifndef SQLITE_OMIT_WAL
-# define pagerUseWal(x) ((x)->pWal!=0)
+# define pagerUseWal(x) ((x)->pWal!=0)
#else
# define pagerUseWal(x) 0
# define pagerRollbackWal(x) 0
@@ -53541,7 +53541,7 @@ static int assert_pager_state(Pager *p){
** state.
*/
if( MEMDB ){
- assert( !isOpen(p->fd) );
+ assert( !isOpen(p->fd) );
assert( p->noSync );
assert( p->journalMode==PAGER_JOURNALMODE_OFF
|| p->journalMode==PAGER_JOURNALMODE_MEMORY
@@ -53608,7 +53608,7 @@ static int assert_pager_state(Pager *p){
assert( isOpen(p->jfd)
|| p->journalMode==PAGER_JOURNALMODE_OFF
|| p->journalMode==PAGER_JOURNALMODE_WAL
- || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
+ || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
);
assert( pPager->dbOrigSize<=pPager->dbHintSize );
break;
@@ -53620,7 +53620,7 @@ static int assert_pager_state(Pager *p){
assert( isOpen(p->jfd)
|| p->journalMode==PAGER_JOURNALMODE_OFF
|| p->journalMode==PAGER_JOURNALMODE_WAL
- || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
+ || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
);
break;
@@ -53630,7 +53630,7 @@ static int assert_pager_state(Pager *p){
** back to OPEN state.
*/
assert( pPager->errCode!=SQLITE_OK );
- assert( sqlite3PcacheRefCount(pPager->pPCache)>0 || pPager->tempFile );
+ assert( sqlite3PcacheRefCount(pPager->pPCache)>0 || pPager->tempFile );
break;
}
@@ -53693,30 +53693,30 @@ char *print_pager_state(Pager *p){
}
#endif
-/* Forward references to the various page getters */
-static int getPageNormal(Pager*,Pgno,DbPage**,int);
-static int getPageError(Pager*,Pgno,DbPage**,int);
-#if SQLITE_MAX_MMAP_SIZE>0
-static int getPageMMap(Pager*,Pgno,DbPage**,int);
-#endif
-
+/* Forward references to the various page getters */
+static int getPageNormal(Pager*,Pgno,DbPage**,int);
+static int getPageError(Pager*,Pgno,DbPage**,int);
+#if SQLITE_MAX_MMAP_SIZE>0
+static int getPageMMap(Pager*,Pgno,DbPage**,int);
+#endif
+
/*
-** Set the Pager.xGet method for the appropriate routine used to fetch
-** content from the pager.
-*/
-static void setGetterMethod(Pager *pPager){
- if( pPager->errCode ){
- pPager->xGet = getPageError;
-#if SQLITE_MAX_MMAP_SIZE>0
+** Set the Pager.xGet method for the appropriate routine used to fetch
+** content from the pager.
+*/
+static void setGetterMethod(Pager *pPager){
+ if( pPager->errCode ){
+ pPager->xGet = getPageError;
+#if SQLITE_MAX_MMAP_SIZE>0
}else if( USEFETCH(pPager) ){
- pPager->xGet = getPageMMap;
-#endif /* SQLITE_MAX_MMAP_SIZE>0 */
- }else{
- pPager->xGet = getPageNormal;
- }
-}
-
-/*
+ pPager->xGet = getPageMMap;
+#endif /* SQLITE_MAX_MMAP_SIZE>0 */
+ }else{
+ pPager->xGet = getPageNormal;
+ }
+}
+
+/*
** Return true if it is necessary to write page *pPg into the sub-journal.
** A page needs to be written into the sub-journal if there exists one
** or more open savepoints for which:
@@ -53835,9 +53835,9 @@ static int pagerLockDb(Pager *pPager, int eLock){
}
/*
-** This function determines whether or not the atomic-write or
-** atomic-batch-write optimizations can be used with this pager. The
-** atomic-write optimization can be used if:
+** This function determines whether or not the atomic-write or
+** atomic-batch-write optimizations can be used with this pager. The
+** atomic-write optimization can be used if:
**
** (a) the value returned by OsDeviceCharacteristics() indicates that
** a database page may be written atomically, and
@@ -53845,38 +53845,38 @@ static int pagerLockDb(Pager *pPager, int eLock){
** to the page size.
**
** If it can be used, then the value returned is the size of the journal
-** file when it contains rollback data for exactly one page.
+** file when it contains rollback data for exactly one page.
**
-** The atomic-batch-write optimization can be used if OsDeviceCharacteristics()
-** returns a value with the SQLITE_IOCAP_BATCH_ATOMIC bit set. -1 is
-** returned in this case.
-**
-** If neither optimization can be used, 0 is returned.
+** The atomic-batch-write optimization can be used if OsDeviceCharacteristics()
+** returns a value with the SQLITE_IOCAP_BATCH_ATOMIC bit set. -1 is
+** returned in this case.
+**
+** If neither optimization can be used, 0 is returned.
*/
static int jrnlBufferSize(Pager *pPager){
assert( !MEMDB );
-#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
- || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
- int dc; /* Device characteristics */
-
- assert( isOpen(pPager->fd) );
- dc = sqlite3OsDeviceCharacteristics(pPager->fd);
-#else
- UNUSED_PARAMETER(pPager);
-#endif
-
-#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+ int dc; /* Device characteristics */
+
+ assert( isOpen(pPager->fd) );
+ dc = sqlite3OsDeviceCharacteristics(pPager->fd);
+#else
+ UNUSED_PARAMETER(pPager);
+#endif
+
+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
if( pPager->dbSize>0 && (dc&SQLITE_IOCAP_BATCH_ATOMIC) ){
- return -1;
- }
-#endif
-
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
- {
- int nSector = pPager->sectorSize;
- int szPage = pPager->pageSize;
-
+ return -1;
+ }
+#endif
+
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+ {
+ int nSector = pPager->sectorSize;
+ int szPage = pPager->pageSize;
+
assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){
@@ -53887,9 +53887,9 @@ static int jrnlBufferSize(Pager *pPager){
return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
#endif
- return 0;
-}
-
+ return 0;
+}
+
/*
** If SQLITE_CHECK_PAGES is defined then we do some sanity checking
** on the cache using a hash function. This is used for testing
@@ -53971,7 +53971,7 @@ static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u32 nSuper){
|| szJ<16
|| SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
|| len>=nSuper
- || len>szJ-16
+ || len>szJ-16
|| len==0
|| SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
|| SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
@@ -54050,7 +54050,7 @@ static i64 journalHdrOffset(Pager *pPager){
static int zeroJournalHdr(Pager *pPager, int doTruncate){
int rc = SQLITE_OK; /* Return code */
assert( isOpen(pPager->jfd) );
- assert( !sqlite3JournalIsInMemory(pPager->jfd) );
+ assert( !sqlite3JournalIsInMemory(pPager->jfd) );
if( pPager->journalOff ){
const i64 iLimit = pPager->journalSizeLimit; /* Local cache of jsl */
@@ -54431,7 +54431,7 @@ static void releaseAllSavepoints(Pager *pPager){
for(ii=0; ii<pPager->nSavepoint; ii++){
sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
}
- if( !pPager->exclusiveMode || sqlite3JournalIsInMemory(pPager->sjfd) ){
+ if( !pPager->exclusiveMode || sqlite3JournalIsInMemory(pPager->sjfd) ){
sqlite3OsClose(pPager->sjfd);
}
sqlite3_free(pPager->aSavepoint);
@@ -54536,18 +54536,18 @@ static void pager_unlock(Pager *pPager){
** it can safely move back to PAGER_OPEN state. This happens in both
** normal and exclusive-locking mode.
*/
- assert( pPager->errCode==SQLITE_OK || !MEMDB );
+ assert( pPager->errCode==SQLITE_OK || !MEMDB );
if( pPager->errCode ){
- if( pPager->tempFile==0 ){
- pager_reset(pPager);
- pPager->changeCountDone = 0;
- pPager->eState = PAGER_OPEN;
- }else{
- pPager->eState = (isOpen(pPager->jfd) ? PAGER_OPEN : PAGER_READER);
- }
- if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
+ if( pPager->tempFile==0 ){
+ pager_reset(pPager);
+ pPager->changeCountDone = 0;
+ pPager->eState = PAGER_OPEN;
+ }else{
+ pPager->eState = (isOpen(pPager->jfd) ? PAGER_OPEN : PAGER_READER);
+ }
+ if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
pPager->errCode = SQLITE_OK;
- setGetterMethod(pPager);
+ setGetterMethod(pPager);
}
pPager->journalOff = 0;
@@ -54585,7 +54585,7 @@ static int pager_error(Pager *pPager, int rc){
if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
pPager->errCode = rc;
pPager->eState = PAGER_ERROR;
- setGetterMethod(pPager);
+ setGetterMethod(pPager);
}
return rc;
}
@@ -54593,29 +54593,29 @@ static int pager_error(Pager *pPager, int rc){
static int pager_truncate(Pager *pPager, Pgno nPage);
/*
-** The write transaction open on pPager is being committed (bCommit==1)
-** or rolled back (bCommit==0).
-**
-** Return TRUE if and only if all dirty pages should be flushed to disk.
-**
-** Rules:
-**
-** * For non-TEMP databases, always sync to disk. This is necessary
-** for transactions to be durable.
-**
-** * Sync TEMP database only on a COMMIT (not a ROLLBACK) when the backing
-** file has been created already (via a spill on pagerStress()) and
-** when the number of dirty pages in memory exceeds 25% of the total
-** cache size.
-*/
-static int pagerFlushOnCommit(Pager *pPager, int bCommit){
- if( pPager->tempFile==0 ) return 1;
- if( !bCommit ) return 0;
- if( !isOpen(pPager->fd) ) return 0;
- return (sqlite3PCachePercentDirty(pPager->pPCache)>=25);
-}
-
-/*
+** The write transaction open on pPager is being committed (bCommit==1)
+** or rolled back (bCommit==0).
+**
+** Return TRUE if and only if all dirty pages should be flushed to disk.
+**
+** Rules:
+**
+** * For non-TEMP databases, always sync to disk. This is necessary
+** for transactions to be durable.
+**
+** * Sync TEMP database only on a COMMIT (not a ROLLBACK) when the backing
+** file has been created already (via a spill on pagerStress()) and
+** when the number of dirty pages in memory exceeds 25% of the total
+** cache size.
+*/
+static int pagerFlushOnCommit(Pager *pPager, int bCommit){
+ if( pPager->tempFile==0 ) return 1;
+ if( !bCommit ) return 0;
+ if( !isOpen(pPager->fd) ) return 0;
+ return (sqlite3PCachePercentDirty(pPager->pPCache)>=25);
+}
+
+/*
** This routine ends a transaction. A transaction is usually ended by
** either a COMMIT or a ROLLBACK operation. This routine may be called
** after rollback of a hot-journal, or if an error occurs while opening
@@ -54693,14 +54693,14 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){
releaseAllSavepoints(pPager);
assert( isOpen(pPager->jfd) || pPager->pInJournal==0
- || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
- );
+ || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
+ );
if( isOpen(pPager->jfd) ){
assert( !pagerUseWal(pPager) );
/* Finalize the journal file. */
- if( sqlite3JournalIsInMemory(pPager->jfd) ){
- /* assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); */
+ if( sqlite3JournalIsInMemory(pPager->jfd) ){
+ /* assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); */
sqlite3OsClose(pPager->jfd);
}else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
if( pPager->journalOff==0 ){
@@ -54726,17 +54726,17 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){
/* This branch may be executed with Pager.journalMode==MEMORY if
** a hot-journal was just rolled back. In this case the journal
** file should be closed and deleted. If this connection writes to
- ** the database file, it will do so using an in-memory journal.
+ ** the database file, it will do so using an in-memory journal.
*/
- int bDelete = !pPager->tempFile;
- assert( sqlite3JournalIsInMemory(pPager->jfd)==0 );
+ int bDelete = !pPager->tempFile;
+ assert( sqlite3JournalIsInMemory(pPager->jfd)==0 );
assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE
|| pPager->journalMode==PAGER_JOURNALMODE_MEMORY
|| pPager->journalMode==PAGER_JOURNALMODE_WAL
);
sqlite3OsClose(pPager->jfd);
if( bDelete ){
- rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync);
+ rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync);
}
}
}
@@ -54755,14 +54755,14 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){
sqlite3BitvecDestroy(pPager->pInJournal);
pPager->pInJournal = 0;
pPager->nRec = 0;
- if( rc==SQLITE_OK ){
- if( MEMDB || pagerFlushOnCommit(pPager, bCommit) ){
- sqlite3PcacheCleanAll(pPager->pPCache);
- }else{
- sqlite3PcacheClearWritable(pPager->pPCache);
- }
- sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
- }
+ if( rc==SQLITE_OK ){
+ if( MEMDB || pagerFlushOnCommit(pPager, bCommit) ){
+ sqlite3PcacheCleanAll(pPager->pPCache);
+ }else{
+ sqlite3PcacheClearWritable(pPager->pPCache);
+ }
+ sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
+ }
if( pagerUseWal(pPager) ){
/* Drop the WAL write-lock, if any. Also, if the connection was in
@@ -55015,7 +55015,7 @@ static int pager_playback_one_page(
pPg = sqlite3PagerLookup(pPager, pgno);
}
assert( pPg || !MEMDB );
- assert( pPager->eState!=PAGER_OPEN || pPg==0 || pPager->tempFile );
+ assert( pPager->eState!=PAGER_OPEN || pPg==0 || pPager->tempFile );
PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
(isMainJrnl?"main-journal":"sub-journal")
@@ -55032,15 +55032,15 @@ static int pager_playback_one_page(
i64 ofst = (pgno-1)*(i64)pPager->pageSize;
testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
assert( !pagerUseWal(pPager) );
-
- /* Write the data read from the journal back into the database file.
- ** This is usually safe even for an encrypted database - as the data
- ** was encrypted before it was written to the journal file. The exception
- ** is if the data was just read from an in-memory sub-journal. In that
- ** case it must be encrypted here before it is copied into the database
- ** file. */
+
+ /* Write the data read from the journal back into the database file.
+ ** This is usually safe even for an encrypted database - as the data
+ ** was encrypted before it was written to the journal file. The exception
+ ** is if the data was just read from an in-memory sub-journal. In that
+ ** case it must be encrypted here before it is copied into the database
+ ** file. */
rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
-
+
if( pgno>pPager->dbFileSize ){
pPager->dbFileSize = pgno;
}
@@ -55067,7 +55067,7 @@ static int pager_playback_one_page(
assert( isSavepnt );
assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
- rc = sqlite3PagerGet(pPager, pgno, &pPg, 1);
+ rc = sqlite3PagerGet(pPager, pgno, &pPg, 1);
assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
if( rc!=SQLITE_OK ) return rc;
@@ -55084,10 +55084,10 @@ static int pager_playback_one_page(
pData = pPg->pData;
memcpy(pData, (u8*)aData, pPager->pageSize);
pPager->xReiniter(pPg);
- /* It used to be that sqlite3PcacheMakeClean(pPg) was called here. But
- ** that call was dangerous and had no detectable benefit since the cache
- ** is normally cleaned by sqlite3PcacheCleanAll() after rollback and so
- ** has been removed. */
+ /* It used to be that sqlite3PcacheMakeClean(pPg) was called here. But
+ ** that call was dangerous and had no detectable benefit since the cache
+ ** is normally cleaned by sqlite3PcacheCleanAll() after rollback and so
+ ** has been removed. */
pager_set_pagehash(pPg);
/* If this was page 1, then restore the value of Pager.dbFileVers.
@@ -55160,7 +55160,7 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
*/
pSuper = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
if( !pSuper ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
pJournal = 0;
}else{
const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL);
@@ -55179,7 +55179,7 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
nSuperPtr = pVfs->mxPathname+1;
zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2);
if( !zFree ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto delsuper_out;
}
zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0;
@@ -55415,7 +55415,7 @@ static int pager_playback(Pager *pPager, int isHot){
char *zSuper = 0; /* Name of super-journal file if any */
int needPagerReset; /* True to reset page prior to first page rollback */
int nPlayback = 0; /* Total number of pages restored from journal */
- u32 savedPageSize = pPager->pageSize;
+ u32 savedPageSize = pPager->pageSize;
/* Figure out how many records are in the journal. Abort early if
** the journal is empty.
@@ -55434,7 +55434,7 @@ static int pager_playback(Pager *pPager, int isHot){
** TODO: Technically the following is an error because it assumes that
** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
- ** mxPathname is 512, which is the same as the minimum allowable value
+ ** mxPathname is 512, which is the same as the minimum allowable value
** for pageSize.
*/
zSuper = pPager->pTmpSpace;
@@ -55545,9 +55545,9 @@ static int pager_playback(Pager *pPager, int isHot){
assert( 0 );
end_playback:
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerSetPagesize(pPager, &savedPageSize, -1);
- }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerSetPagesize(pPager, &savedPageSize, -1);
+ }
/* Following a rollback, the database file should be back in its original
** state prior to the start of the transaction, so invoke the
** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
@@ -55610,7 +55610,7 @@ end_playback:
/*
-** Read the content for page pPg out of the database file (or out of
+** Read the content for page pPg out of the database file (or out of
** the WAL if that is where the most recent copy if found) into
** pPg->pData. A shared lock or greater must be held on the database
** file before this function is called.
@@ -55621,33 +55621,33 @@ end_playback:
** If an IO error occurs, then the IO error is returned to the caller.
** Otherwise, SQLITE_OK is returned.
*/
-static int readDbPage(PgHdr *pPg){
+static int readDbPage(PgHdr *pPg){
Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
int rc = SQLITE_OK; /* Return code */
-#ifndef SQLITE_OMIT_WAL
- u32 iFrame = 0; /* Frame of WAL containing pgno */
-
+#ifndef SQLITE_OMIT_WAL
+ u32 iFrame = 0; /* Frame of WAL containing pgno */
+
assert( pPager->eState>=PAGER_READER && !MEMDB );
assert( isOpen(pPager->fd) );
- if( pagerUseWal(pPager) ){
- rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
- if( rc ) return rc;
- }
+ if( pagerUseWal(pPager) ){
+ rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
+ if( rc ) return rc;
+ }
if( iFrame ){
- rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData);
+ rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData);
}else
#endif
{
- i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize;
- rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset);
+ i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize;
+ rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset);
if( rc==SQLITE_IOERR_SHORT_READ ){
rc = SQLITE_OK;
}
}
- if( pPg->pgno==1 ){
+ if( pPg->pgno==1 ){
if( rc ){
/* If the read is unsuccessful, set the dbFileVers[] to something
** that will never be a valid file version. dbFileVers[] is a copy
@@ -55669,9 +55669,9 @@ static int readDbPage(PgHdr *pPg){
}
PAGER_INCR(sqlite3_pager_readdb_count);
PAGER_INCR(pPager->nRead);
- IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno));
+ IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno));
PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
- PAGERID(pPager), pPg->pgno, pager_pagehash(pPg)));
+ PAGERID(pPager), pPg->pgno, pager_pagehash(pPg)));
return rc;
}
@@ -55723,7 +55723,7 @@ static int pagerUndoCallback(void *pCtx, Pgno iPg){
if( sqlite3PcachePageRefcount(pPg)==1 ){
sqlite3PcacheDrop(pPg);
}else{
- rc = readDbPage(pPg);
+ rc = readDbPage(pPg);
if( rc==SQLITE_OK ){
pPager->xReiniter(pPg);
}
@@ -55890,20 +55890,20 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
*/
assert( pPager->eState==PAGER_OPEN );
assert( pPager->eLock>=SHARED_LOCK );
- assert( isOpen(pPager->fd) );
- assert( pPager->tempFile==0 );
+ assert( isOpen(pPager->fd) );
+ assert( pPager->tempFile==0 );
nPage = sqlite3WalDbsize(pPager->pWal);
/* If the number of pages in the database is not available from the
- ** WAL sub-system, determine the page count based on the size of
+ ** WAL sub-system, determine the page count based on the size of
** the database file. If the size of the database file is not an
** integer multiple of the page-size, round up the result.
*/
- if( nPage==0 && ALWAYS(isOpen(pPager->fd)) ){
+ if( nPage==0 && ALWAYS(isOpen(pPager->fd)) ){
i64 n = 0; /* Size of db file in bytes */
- int rc = sqlite3OsFileSize(pPager->fd, &n);
- if( rc!=SQLITE_OK ){
- return rc;
+ int rc = sqlite3OsFileSize(pPager->fd, &n);
+ if( rc!=SQLITE_OK ){
+ return rc;
}
nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize);
}
@@ -55946,21 +55946,21 @@ static int pagerOpenWalIfPresent(Pager *pPager){
if( !pPager->tempFile ){
int isWal; /* True if WAL file exists */
- rc = sqlite3OsAccess(
- pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
- );
+ rc = sqlite3OsAccess(
+ pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
+ );
if( rc==SQLITE_OK ){
if( isWal ){
- Pgno nPage; /* Size of the database file */
-
- rc = pagerPagecount(pPager, &nPage);
- if( rc ) return rc;
- if( nPage==0 ){
- rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
- }else{
- testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
- rc = sqlite3PagerOpenWal(pPager, 0);
- }
+ Pgno nPage; /* Size of the database file */
+
+ rc = pagerPagecount(pPager, &nPage);
+ if( rc ) return rc;
+ if( nPage==0 ){
+ rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
+ }else{
+ testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
+ rc = sqlite3PagerOpenWal(pPager, 0);
+ }
}else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
pPager->journalMode = PAGER_JOURNALMODE_DELETE;
}
@@ -56019,7 +56019,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
if( pSavepoint ){
pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
if( !pDone ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
}
@@ -56115,22 +56115,22 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
}
/*
-** Change the maximum number of in-memory pages that are allowed
-** before attempting to recycle clean and unused pages.
+** Change the maximum number of in-memory pages that are allowed
+** before attempting to recycle clean and unused pages.
*/
SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
}
/*
-** Change the maximum number of in-memory pages that are allowed
-** before attempting to spill pages to journal.
-*/
-SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager *pPager, int mxPage){
- return sqlite3PcacheSetSpillsize(pPager->pPCache, mxPage);
-}
-
-/*
+** Change the maximum number of in-memory pages that are allowed
+** before attempting to spill pages to journal.
+*/
+SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager *pPager, int mxPage){
+ return sqlite3PcacheSetSpillsize(pPager->pPCache, mxPage);
+}
+
+/*
** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap.
*/
static void pagerFixMaplimit(Pager *pPager){
@@ -56140,7 +56140,7 @@ static void pagerFixMaplimit(Pager *pPager){
sqlite3_int64 sz;
sz = pPager->szMmap;
pPager->bUseFetch = (sz>0);
- setGetterMethod(pPager);
+ setGetterMethod(pPager);
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
}
#endif
@@ -56167,7 +56167,7 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
** of the database to damage due to OS crashes or power failures by
** changing the number of syncs()s when writing the journals.
-** There are four levels:
+** There are four levels:
**
** OFF sqlite3OsSync() is never called. This is the default
** for temporary and transient files.
@@ -56187,10 +56187,10 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
** assurance that the journal will not be corrupted to the
** point of causing damage to the database during rollback.
**
-** EXTRA This is like FULL except that is also syncs the directory
-** that contains the rollback journal after the rollback
-** journal is unlinked.
-**
+** EXTRA This is like FULL except that is also syncs the directory
+** that contains the rollback journal after the rollback
+** journal is unlinked.
+**
** The above is for a rollback-journal mode. For WAL mode, OFF continues
** to mean that no syncs ever occur. NORMAL means that the WAL is synced
** prior to the start of checkpoint and that the database file is synced
@@ -56198,8 +56198,8 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
** was written back into the database. But no sync operations occur for
** an ordinary commit in NORMAL mode with WAL. FULL means that the WAL
** file is synced following each commit operation, in addition to the
-** syncs associated with NORMAL. There is no difference between FULL
-** and EXTRA for WAL mode.
+** syncs associated with NORMAL. There is no difference between FULL
+** and EXTRA for WAL mode.
**
** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL. The
** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync
@@ -56218,15 +56218,15 @@ SQLITE_PRIVATE void sqlite3PagerSetFlags(
unsigned pgFlags /* Various flags */
){
unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
- if( pPager->tempFile ){
- pPager->noSync = 1;
- pPager->fullSync = 0;
- pPager->extraSync = 0;
- }else{
- pPager->noSync = level==PAGER_SYNCHRONOUS_OFF ?1:0;
- pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0;
- pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0;
- }
+ if( pPager->tempFile ){
+ pPager->noSync = 1;
+ pPager->fullSync = 0;
+ pPager->extraSync = 0;
+ }else{
+ pPager->noSync = level==PAGER_SYNCHRONOUS_OFF ?1:0;
+ pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0;
+ pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0;
+ }
if( pPager->noSync ){
pPager->syncFlags = 0;
}else if( pgFlags & PAGER_FULLFSYNC ){
@@ -56234,13 +56234,13 @@ SQLITE_PRIVATE void sqlite3PagerSetFlags(
}else{
pPager->syncFlags = SQLITE_SYNC_NORMAL;
}
- pPager->walSyncFlags = (pPager->syncFlags<<2);
+ pPager->walSyncFlags = (pPager->syncFlags<<2);
if( pPager->fullSync ){
- pPager->walSyncFlags |= pPager->syncFlags;
+ pPager->walSyncFlags |= pPager->syncFlags;
+ }
+ if( (pgFlags & PAGER_CKPT_FULLFSYNC) && !pPager->noSync ){
+ pPager->walSyncFlags |= (SQLITE_SYNC_FULL<<2);
}
- if( (pgFlags & PAGER_CKPT_FULLFSYNC) && !pPager->noSync ){
- pPager->walSyncFlags |= (SQLITE_SYNC_FULL<<2);
- }
if( pgFlags & PAGER_CACHESPILL ){
pPager->doNotSpill &= ~SPILLFLAG_OFF;
}else{
@@ -56641,7 +56641,7 @@ static int pagerSyncHotJournal(Pager *pPager){
return rc;
}
-#if SQLITE_MAX_MMAP_SIZE>0
+#if SQLITE_MAX_MMAP_SIZE>0
/*
** Obtain a reference to a memory mapped page object for page number pgno.
** The new object will use the pointer pData, obtained from xFetch().
@@ -56664,13 +56664,13 @@ static int pagerAcquireMapPage(
*ppPage = p = pPager->pMmapFreelist;
pPager->pMmapFreelist = p->pDirty;
p->pDirty = 0;
- assert( pPager->nExtra>=8 );
- memset(p->pExtra, 0, 8);
+ assert( pPager->nExtra>=8 );
+ memset(p->pExtra, 0, 8);
}else{
*ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
if( p==0 ){
sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
p->pExtra = (void *)&p[1];
p->flags = PGHDR_MMAP;
@@ -56690,7 +56690,7 @@ static int pagerAcquireMapPage(
return SQLITE_OK;
}
-#endif
+#endif
/*
** Release a reference to page pPg. pPg must have been returned by an
@@ -56757,9 +56757,9 @@ static int databaseIsUnmoved(Pager *pPager){
** a hot journal may be left in the filesystem but no error is returned
** to the caller.
*/
-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
+SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
u8 *pTmp = (u8*)pPager->pTmpSpace;
- assert( db || pagerUseWal(pPager)==0 );
+ assert( db || pagerUseWal(pPager)==0 );
assert( assert_pager_state(pPager) );
disable_simulated_io_errors();
sqlite3BeginBenignMalloc();
@@ -57013,9 +57013,9 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
/* This function is only called for rollback pagers in WRITER_DBMOD state. */
assert( !pagerUseWal(pPager) );
- assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD );
+ assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD );
assert( pPager->eLock==EXCLUSIVE_LOCK );
- assert( isOpen(pPager->fd) || pList->pDirty==0 );
+ assert( isOpen(pPager->fd) || pList->pDirty==0 );
/* If the file is a temp-file has not yet been opened, open it now. It
** is not possible for rc to be other than SQLITE_OK if this branch
@@ -57104,12 +57104,12 @@ static int openSubJournal(Pager *pPager){
if( !isOpen(pPager->sjfd) ){
const int flags = SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE
| SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE
- | SQLITE_OPEN_DELETEONCLOSE;
- int nStmtSpill = sqlite3Config.nStmtSpill;
+ | SQLITE_OPEN_DELETEONCLOSE;
+ int nStmtSpill = sqlite3Config.nStmtSpill;
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
- nStmtSpill = -1;
+ nStmtSpill = -1;
}
- rc = sqlite3JournalOpen(pPager->pVfs, 0, pPager->sjfd, flags, nStmtSpill);
+ rc = sqlite3JournalOpen(pPager->pVfs, 0, pPager->sjfd, flags, nStmtSpill);
}
return rc;
}
@@ -57146,7 +57146,7 @@ static int subjournalPage(PgHdr *pPg){
void *pData = pPg->pData;
i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
char *pData2;
- pData2 = pData;
+ pData2 = pData;
PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
rc = write32bits(pPager->sjfd, offset, pPg->pgno);
if( rc==SQLITE_OK ){
@@ -57232,12 +57232,12 @@ static int pagerStress(void *p, PgHdr *pPg){
}
}else{
-#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
- if( pPager->tempFile==0 ){
- rc = sqlite3JournalCreate(pPager->jfd);
- if( rc!=SQLITE_OK ) return pager_error(pPager, rc);
- }
-#endif
+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+ if( pPager->tempFile==0 ){
+ rc = sqlite3JournalCreate(pPager->jfd);
+ if( rc!=SQLITE_OK ) return pager_error(pPager, rc);
+ }
+#endif
/* Sync the journal file if required. */
if( pPg->flags&PGHDR_NEED_SYNC
@@ -57262,26 +57262,26 @@ static int pagerStress(void *p, PgHdr *pPg){
return pager_error(pPager, rc);
}
-/*
-** Flush all unreferenced dirty pages to disk.
-*/
-SQLITE_PRIVATE int sqlite3PagerFlush(Pager *pPager){
- int rc = pPager->errCode;
- if( !MEMDB ){
- PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
- assert( assert_pager_state(pPager) );
- while( rc==SQLITE_OK && pList ){
- PgHdr *pNext = pList->pDirty;
- if( pList->nRef==0 ){
- rc = pagerStress((void*)pPager, pList);
- }
- pList = pNext;
- }
- }
-
- return rc;
-}
-
+/*
+** Flush all unreferenced dirty pages to disk.
+*/
+SQLITE_PRIVATE int sqlite3PagerFlush(Pager *pPager){
+ int rc = pPager->errCode;
+ if( !MEMDB ){
+ PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
+ assert( assert_pager_state(pPager) );
+ while( rc==SQLITE_OK && pList ){
+ PgHdr *pNext = pList->pDirty;
+ if( pList->nRef==0 ){
+ rc = pagerStress((void*)pPager, pList);
+ }
+ pList = pNext;
+ }
+ }
+
+ return rc;
+}
+
/*
** Allocate and initialize a new Pager object and put a pointer to it
** in *ppPager. The pager should eventually be freed by passing it
@@ -57296,9 +57296,9 @@ SQLITE_PRIVATE int sqlite3PagerFlush(Pager *pPager){
**
** The nExtra parameter specifies the number of bytes of space allocated
** along with each page reference. This space is available to the user
-** via the sqlite3PagerGetExtra() API. When a new page is allocated, the
-** first 8 bytes of this space are zeroed but the remainder is uninitialized.
-** (The extra space is used by btree as the MemPage object.)
+** via the sqlite3PagerGetExtra() API. When a new page is allocated, the
+** first 8 bytes of this space are zeroed but the remainder is uninitialized.
+** (The extra space is used by btree as the MemPage object.)
**
** The flags argument is used to specify properties that affect the
** operation of the pager. It should be passed some bitwise combination
@@ -57345,8 +57345,8 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
int nUri = 0; /* Number of URI parameters */
/* Figure out how much space is required for each journal file-handle
- ** (there are two of them, the main journal and the sub-journal). */
- journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
+ ** (there are two of them, the main journal and the sub-journal). */
+ journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
/* Set the output variable to NULL in case an error occurs. */
*ppPager = 0;
@@ -57356,7 +57356,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
memDb = 1;
if( zFilename && zFilename[0] ){
zPathname = sqlite3DbStrDup(0, zFilename);
- if( zPathname==0 ) return SQLITE_NOMEM_BKPT;
+ if( zPathname==0 ) return SQLITE_NOMEM_BKPT;
nPathname = sqlite3Strlen30(zPathname);
zFilename = 0;
}
@@ -57372,7 +57372,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
nPathname = pVfs->mxPathname+1;
zPathname = sqlite3DbMallocRaw(0, nPathname*2);
if( zPathname==0 ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
@@ -57471,7 +57471,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
sqlite3DbFree(0, zPathname);
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager));
pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize);
@@ -57610,7 +57610,7 @@ act_like_temp_file:
/* Initialize the PCache object. */
if( rc==SQLITE_OK ){
nExtra = ROUND8(nExtra);
- assert( nExtra>=8 && nExtra<1000 );
+ assert( nExtra>=8 && nExtra<1000 );
rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
!memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
}
@@ -57649,14 +57649,14 @@ act_like_temp_file:
pPager->noSync = pPager->tempFile;
if( pPager->noSync ){
assert( pPager->fullSync==0 );
- assert( pPager->extraSync==0 );
+ assert( pPager->extraSync==0 );
assert( pPager->syncFlags==0 );
assert( pPager->walSyncFlags==0 );
}else{
pPager->fullSync = 1;
- pPager->extraSync = 0;
+ pPager->extraSync = 0;
pPager->syncFlags = SQLITE_SYNC_NORMAL;
- pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2);
+ pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2);
}
/* pPager->pFirst = 0; */
/* pPager->pFirstSynced = 0; */
@@ -57673,7 +57673,7 @@ act_like_temp_file:
/* pPager->xBusyHandler = 0; */
/* pPager->pBusyHandlerArg = 0; */
pPager->xReiniter = xReinit;
- setGetterMethod(pPager);
+ setGetterMethod(pPager);
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
/* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
@@ -57760,7 +57760,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){
if( rc==SQLITE_OK && !locked ){
Pgno nPage; /* Number of pages in database file */
- assert( pPager->tempFile==0 );
+ assert( pPager->tempFile==0 );
rc = pagerPagecount(pPager, &nPage);
if( rc==SQLITE_OK ){
/* If the database is zero pages in size, that means that either (1) the
@@ -57822,7 +57822,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){
/*
** This function is called to obtain a shared lock on the database file.
-** It is illegal to call sqlite3PagerGet() until after this function
+** It is illegal to call sqlite3PagerGet() until after this function
** has been successfully called. If a shared-lock is already held when
** this function is called, it is a no-op.
**
@@ -57853,17 +57853,17 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
/* This routine is only called from b-tree and only when there are no
** outstanding pages. This implies that the pager state should either
** be OPEN or READER. READER is only possible if the pager is or was in
- ** exclusive access mode. */
+ ** exclusive access mode. */
assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
assert( assert_pager_state(pPager) );
assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
- assert( pPager->errCode==SQLITE_OK );
+ assert( pPager->errCode==SQLITE_OK );
if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
int bHotJournal = 1; /* True if there exists a hot journal-file */
assert( !MEMDB );
- assert( pPager->tempFile==0 || pPager->eLock==EXCLUSIVE_LOCK );
+ assert( pPager->tempFile==0 || pPager->eLock==EXCLUSIVE_LOCK );
rc = pager_wait_on_lock(pPager, SHARED_LOCK);
if( rc!=SQLITE_OK ){
@@ -57949,7 +57949,7 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
assert( rc==SQLITE_OK );
rc = pagerSyncHotJournal(pPager);
if( rc==SQLITE_OK ){
- rc = pager_playback(pPager, !pPager->tempFile);
+ rc = pager_playback(pPager, !pPager->tempFile);
pPager->eState = PAGER_OPEN;
}
}else if( !pPager->exclusiveMode ){
@@ -57983,10 +57983,10 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
);
}
- if( !pPager->tempFile && pPager->hasHeldSharedLock ){
+ if( !pPager->tempFile && pPager->hasHeldSharedLock ){
/* The shared-lock has just been acquired then check to
** see if the database has been modified. If the database has changed,
- ** flush the cache. The hasHeldSharedLock flag prevents this from
+ ** flush the cache. The hasHeldSharedLock flag prevents this from
** occurring on the very first access to a file, in order to save a
** single unnecessary sqlite3OsRead() call at the start-up.
**
@@ -58002,10 +58002,10 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
*/
char dbFileVers[sizeof(pPager->dbFileVers)];
- IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
- rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
- if( rc!=SQLITE_OK ){
- if( rc!=SQLITE_IOERR_SHORT_READ ){
+ IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
+ rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
+ if( rc!=SQLITE_OK ){
+ if( rc!=SQLITE_IOERR_SHORT_READ ){
goto failed;
}
memset(dbFileVers, 0, sizeof(dbFileVers));
@@ -58040,7 +58040,7 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
rc = pagerBeginReadTransaction(pPager);
}
- if( pPager->tempFile==0 && pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
+ if( pPager->tempFile==0 && pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
rc = pagerPagecount(pPager, &pPager->dbSize);
}
@@ -58051,7 +58051,7 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
assert( pPager->eState==PAGER_OPEN );
}else{
pPager->eState = PAGER_READER;
- pPager->hasHeldSharedLock = 1;
+ pPager->hasHeldSharedLock = 1;
}
return rc;
}
@@ -58065,24 +58065,24 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
** nothing to rollback, so this routine is a no-op.
*/
static void pagerUnlockIfUnused(Pager *pPager){
- if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){
- assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */
+ if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){
+ assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */
pagerUnlockAndRollback(pPager);
}
}
/*
-** The page getter methods each try to acquire a reference to a
+** The page getter methods each try to acquire a reference to a
** page with page number pgno. If the requested reference is
** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
**
-** There are different implementations of the getter method depending
-** on the current state of the pager.
-**
-** getPageNormal() -- The normal getter
-** getPageError() -- Used if the pager is in an error state
-** getPageMmap() -- Used if memory-mapped I/O is enabled
-**
+** There are different implementations of the getter method depending
+** on the current state of the pager.
+**
+** getPageNormal() -- The normal getter
+** getPageError() -- Used if the pager is in an error state
+** getPageMmap() -- Used if memory-mapped I/O is enabled
+**
** If the requested page is already in the cache, it is returned.
** Otherwise, a new page object is allocated and populated with data
** read from the database file. In some cases, the pcache module may
@@ -58100,8 +58100,8 @@ static void pagerUnlockIfUnused(Pager *pPager){
** actual disk read occurs. In this case the memory image of the
** page is initialized to all zeros.
**
-** If PAGER_GET_NOCONTENT is true, it means that we do not care about
-** the contents of the page. This occurs in two scenarios:
+** If PAGER_GET_NOCONTENT is true, it means that we do not care about
+** the contents of the page. This occurs in two scenarios:
**
** a) When reading a free-list leaf page from the database, and
**
@@ -58109,8 +58109,8 @@ static void pagerUnlockIfUnused(Pager *pPager){
** a new page into the cache to be filled with the data read
** from the savepoint journal.
**
-** If PAGER_GET_NOCONTENT is true, then the data returned is zeroed instead
-** of being read from the database. Additionally, the bits corresponding
+** If PAGER_GET_NOCONTENT is true, then the data returned is zeroed instead
+** of being read from the database. Additionally, the bits corresponding
** to pgno in Pager.pInJournal (bitvec of pages already written to the
** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
** savepoints are set. This means if the page is made writable at any
@@ -58128,39 +58128,39 @@ static void pagerUnlockIfUnused(Pager *pPager){
** Since Lookup() never goes to disk, it never has to deal with locks
** or journal files.
*/
-static int getPageNormal(
+static int getPageNormal(
Pager *pPager, /* The pager open on the database file */
Pgno pgno, /* Page number to fetch */
DbPage **ppPage, /* Write a pointer to the page here */
int flags /* PAGER_GET_XXX flags */
){
int rc = SQLITE_OK;
- PgHdr *pPg;
- u8 noContent; /* True if PAGER_GET_NOCONTENT is set */
- sqlite3_pcache_page *pBase;
+ PgHdr *pPg;
+ u8 noContent; /* True if PAGER_GET_NOCONTENT is set */
+ sqlite3_pcache_page *pBase;
- assert( pPager->errCode==SQLITE_OK );
+ assert( pPager->errCode==SQLITE_OK );
assert( pPager->eState>=PAGER_READER );
assert( assert_pager_state(pPager) );
- assert( pPager->hasHeldSharedLock==1 );
+ assert( pPager->hasHeldSharedLock==1 );
- if( pgno==0 ) return SQLITE_CORRUPT_BKPT;
- pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
- if( pBase==0 ){
- pPg = 0;
- rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
- if( rc!=SQLITE_OK ) goto pager_acquire_err;
- if( pBase==0 ){
- rc = SQLITE_NOMEM_BKPT;
- goto pager_acquire_err;
+ if( pgno==0 ) return SQLITE_CORRUPT_BKPT;
+ pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
+ if( pBase==0 ){
+ pPg = 0;
+ rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
+ if( rc!=SQLITE_OK ) goto pager_acquire_err;
+ if( pBase==0 ){
+ rc = SQLITE_NOMEM_BKPT;
+ goto pager_acquire_err;
}
}
- pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
+ pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
assert( pPg==(*ppPage) );
assert( pPg->pgno==pgno );
assert( pPg->pPager==pPager || pPg->pPager==0 );
- noContent = (flags & PAGER_GET_NOCONTENT)!=0;
+ noContent = (flags & PAGER_GET_NOCONTENT)!=0;
if( pPg->pPager && !noContent ){
/* In this case the pcache already contains an initialized copy of
** the page. Return without further ado. */
@@ -58170,20 +58170,20 @@ static int getPageNormal(
}else{
/* The pager cache has created a new page. Its content needs to
- ** be initialized. But first some error checks:
- **
+ ** be initialized. But first some error checks:
+ **
** (*) obsolete. Was: maximum page number is 2^31
- ** (2) Never try to fetch the locking page
- */
+ ** (2) Never try to fetch the locking page
+ */
if( pgno==PAGER_MJ_PGNO(pPager) ){
rc = SQLITE_CORRUPT_BKPT;
goto pager_acquire_err;
}
- pPg->pPager = pPager;
-
- assert( !isOpen(pPager->fd) || !MEMDB );
- if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){
+ pPg->pPager = pPager;
+
+ assert( !isOpen(pPager->fd) || !MEMDB );
+ if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){
if( pgno>pPager->mxPgno ){
rc = SQLITE_FULL;
goto pager_acquire_err;
@@ -58209,7 +58209,7 @@ static int getPageNormal(
}else{
assert( pPg->pPager==pPager );
pPager->aStat[PAGER_STAT_MISS]++;
- rc = readDbPage(pPg);
+ rc = readDbPage(pPg);
if( rc!=SQLITE_OK ){
goto pager_acquire_err;
}
@@ -58228,102 +58228,102 @@ pager_acquire_err:
return rc;
}
-#if SQLITE_MAX_MMAP_SIZE>0
-/* The page getter for when memory-mapped I/O is enabled */
-static int getPageMMap(
- Pager *pPager, /* The pager open on the database file */
- Pgno pgno, /* Page number to fetch */
- DbPage **ppPage, /* Write a pointer to the page here */
- int flags /* PAGER_GET_XXX flags */
-){
- int rc = SQLITE_OK;
- PgHdr *pPg = 0;
- u32 iFrame = 0; /* Frame to read from WAL file */
-
- /* It is acceptable to use a read-only (mmap) page for any page except
- ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
+#if SQLITE_MAX_MMAP_SIZE>0
+/* The page getter for when memory-mapped I/O is enabled */
+static int getPageMMap(
+ Pager *pPager, /* The pager open on the database file */
+ Pgno pgno, /* Page number to fetch */
+ DbPage **ppPage, /* Write a pointer to the page here */
+ int flags /* PAGER_GET_XXX flags */
+){
+ int rc = SQLITE_OK;
+ PgHdr *pPg = 0;
+ u32 iFrame = 0; /* Frame to read from WAL file */
+
+ /* It is acceptable to use a read-only (mmap) page for any page except
+ ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
** flag was specified by the caller. And so long as the db is not a
- ** temporary or in-memory database. */
- const int bMmapOk = (pgno>1
- && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
- );
-
- assert( USEFETCH(pPager) );
-
- /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here
- ** allows the compiler optimizer to reuse the results of the "pgno>1"
- ** test in the previous statement, and avoid testing pgno==0 in the
- ** common case where pgno is large. */
- if( pgno<=1 && pgno==0 ){
- return SQLITE_CORRUPT_BKPT;
- }
- assert( pPager->eState>=PAGER_READER );
- assert( assert_pager_state(pPager) );
- assert( pPager->hasHeldSharedLock==1 );
- assert( pPager->errCode==SQLITE_OK );
-
- if( bMmapOk && pagerUseWal(pPager) ){
- rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
- if( rc!=SQLITE_OK ){
- *ppPage = 0;
- return rc;
- }
- }
- if( bMmapOk && iFrame==0 ){
- void *pData = 0;
+ ** temporary or in-memory database. */
+ const int bMmapOk = (pgno>1
+ && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
+ );
+
+ assert( USEFETCH(pPager) );
+
+ /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here
+ ** allows the compiler optimizer to reuse the results of the "pgno>1"
+ ** test in the previous statement, and avoid testing pgno==0 in the
+ ** common case where pgno is large. */
+ if( pgno<=1 && pgno==0 ){
+ return SQLITE_CORRUPT_BKPT;
+ }
+ assert( pPager->eState>=PAGER_READER );
+ assert( assert_pager_state(pPager) );
+ assert( pPager->hasHeldSharedLock==1 );
+ assert( pPager->errCode==SQLITE_OK );
+
+ if( bMmapOk && pagerUseWal(pPager) ){
+ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
+ if( rc!=SQLITE_OK ){
+ *ppPage = 0;
+ return rc;
+ }
+ }
+ if( bMmapOk && iFrame==0 ){
+ void *pData = 0;
rc = sqlite3OsFetch(pPager->fd,
- (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
- );
- if( rc==SQLITE_OK && pData ){
- if( pPager->eState>PAGER_READER || pPager->tempFile ){
- pPg = sqlite3PagerLookup(pPager, pgno);
- }
- if( pPg==0 ){
- rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
- }else{
- sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
- }
- if( pPg ){
- assert( rc==SQLITE_OK );
- *ppPage = pPg;
- return SQLITE_OK;
- }
- }
- if( rc!=SQLITE_OK ){
- *ppPage = 0;
- return rc;
- }
- }
- return getPageNormal(pPager, pgno, ppPage, flags);
-}
-#endif /* SQLITE_MAX_MMAP_SIZE>0 */
-
-/* The page getter method for when the pager is an error state */
-static int getPageError(
- Pager *pPager, /* The pager open on the database file */
- Pgno pgno, /* Page number to fetch */
- DbPage **ppPage, /* Write a pointer to the page here */
- int flags /* PAGER_GET_XXX flags */
-){
- UNUSED_PARAMETER(pgno);
- UNUSED_PARAMETER(flags);
- assert( pPager->errCode!=SQLITE_OK );
- *ppPage = 0;
- return pPager->errCode;
-}
-
-
-/* Dispatch all page fetch requests to the appropriate getter method.
-*/
-SQLITE_PRIVATE int sqlite3PagerGet(
- Pager *pPager, /* The pager open on the database file */
- Pgno pgno, /* Page number to fetch */
- DbPage **ppPage, /* Write a pointer to the page here */
- int flags /* PAGER_GET_XXX flags */
-){
- return pPager->xGet(pPager, pgno, ppPage, flags);
-}
-
+ (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
+ );
+ if( rc==SQLITE_OK && pData ){
+ if( pPager->eState>PAGER_READER || pPager->tempFile ){
+ pPg = sqlite3PagerLookup(pPager, pgno);
+ }
+ if( pPg==0 ){
+ rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
+ }else{
+ sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
+ }
+ if( pPg ){
+ assert( rc==SQLITE_OK );
+ *ppPage = pPg;
+ return SQLITE_OK;
+ }
+ }
+ if( rc!=SQLITE_OK ){
+ *ppPage = 0;
+ return rc;
+ }
+ }
+ return getPageNormal(pPager, pgno, ppPage, flags);
+}
+#endif /* SQLITE_MAX_MMAP_SIZE>0 */
+
+/* The page getter method for when the pager is an error state */
+static int getPageError(
+ Pager *pPager, /* The pager open on the database file */
+ Pgno pgno, /* Page number to fetch */
+ DbPage **ppPage, /* Write a pointer to the page here */
+ int flags /* PAGER_GET_XXX flags */
+){
+ UNUSED_PARAMETER(pgno);
+ UNUSED_PARAMETER(flags);
+ assert( pPager->errCode!=SQLITE_OK );
+ *ppPage = 0;
+ return pPager->errCode;
+}
+
+
+/* Dispatch all page fetch requests to the appropriate getter method.
+*/
+SQLITE_PRIVATE int sqlite3PagerGet(
+ Pager *pPager, /* The pager open on the database file */
+ Pgno pgno, /* Page number to fetch */
+ DbPage **ppPage, /* Write a pointer to the page here */
+ int flags /* PAGER_GET_XXX flags */
+){
+ return pPager->xGet(pPager, pgno, ppPage, flags);
+}
+
/*
** Acquire a page if it is already in the in-memory cache. Do
** not read the page from disk. Return a pointer to the page,
@@ -58341,7 +58341,7 @@ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
assert( pgno!=0 );
assert( pPager->pPCache!=0 );
pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
- assert( pPage==0 || pPager->hasHeldSharedLock );
+ assert( pPage==0 || pPager->hasHeldSharedLock );
if( pPage==0 ) return 0;
return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
}
@@ -58349,39 +58349,39 @@ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
/*
** Release a page reference.
**
-** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be
-** used if we know that the page being released is not the last page.
-** The btree layer always holds page1 open until the end, so these first
-** to routines can be used to release any page other than BtShared.pPage1.
-**
-** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine
-** checks the total number of outstanding pages and if the number of
-** pages reaches zero it drops the database lock.
+** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be
+** used if we know that the page being released is not the last page.
+** The btree layer always holds page1 open until the end, so these first
+** to routines can be used to release any page other than BtShared.pPage1.
+**
+** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine
+** checks the total number of outstanding pages and if the number of
+** pages reaches zero it drops the database lock.
*/
SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){
- TESTONLY( Pager *pPager = pPg->pPager; )
+ TESTONLY( Pager *pPager = pPg->pPager; )
assert( pPg!=0 );
if( pPg->flags & PGHDR_MMAP ){
- assert( pPg->pgno!=1 ); /* Page1 is never memory mapped */
+ assert( pPg->pgno!=1 ); /* Page1 is never memory mapped */
pagerReleaseMapPage(pPg);
}else{
sqlite3PcacheRelease(pPg);
}
- /* Do not use this routine to release the last reference to page1 */
- assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
+ /* Do not use this routine to release the last reference to page1 */
+ assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
}
SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
if( pPg ) sqlite3PagerUnrefNotNull(pPg);
}
-SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){
- Pager *pPager;
- assert( pPg!=0 );
- assert( pPg->pgno==1 );
- assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
- pPager = pPg->pPager;
- sqlite3PcacheRelease(pPg);
- pagerUnlockIfUnused(pPager);
-}
+SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){
+ Pager *pPager;
+ assert( pPg!=0 );
+ assert( pPg->pgno==1 );
+ assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
+ pPager = pPg->pPager;
+ sqlite3PcacheRelease(pPg);
+ pagerUnlockIfUnused(pPager);
+}
/*
** This function is called at the start of every write transaction.
@@ -58421,7 +58421,7 @@ static int pager_open_journal(Pager *pPager){
if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
if( pPager->pInJournal==0 ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
/* Open the journal file if it is not already open. */
@@ -58429,23 +58429,23 @@ static int pager_open_journal(Pager *pPager){
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
sqlite3MemJournalOpen(pPager->jfd);
}else{
- int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
- int nSpill;
+ int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
+ int nSpill;
- if( pPager->tempFile ){
- flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL);
- nSpill = sqlite3Config.nStmtSpill;
- }else{
- flags |= SQLITE_OPEN_MAIN_JOURNAL;
- nSpill = jrnlBufferSize(pPager);
- }
+ if( pPager->tempFile ){
+ flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL);
+ nSpill = sqlite3Config.nStmtSpill;
+ }else{
+ flags |= SQLITE_OPEN_MAIN_JOURNAL;
+ nSpill = jrnlBufferSize(pPager);
+ }
/* Verify that the database still has the same name as it did when
** it was originally opened. */
rc = databaseIsUnmoved(pPager);
if( rc==SQLITE_OK ){
- rc = sqlite3JournalOpen (
- pVfs, pPager->zJournal, pPager->jfd, flags, nSpill
+ rc = sqlite3JournalOpen (
+ pVfs, pPager->zJournal, pPager->jfd, flags, nSpill
);
}
}
@@ -58513,7 +58513,7 @@ SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory
if( rc!=SQLITE_OK ){
return rc;
}
- (void)sqlite3WalExclusiveMode(pPager->pWal, 1);
+ (void)sqlite3WalExclusiveMode(pPager->pWal, 1);
}
/* Grab the write lock on the log file. If successful, upgrade to
@@ -58753,7 +58753,7 @@ static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
PgHdr *pPage;
if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
if( pg!=PAGER_MJ_PGNO(pPager) ){
- rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
+ rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
if( rc==SQLITE_OK ){
rc = pager_write(pPage);
if( pPage->flags&PGHDR_NEED_SYNC ){
@@ -58814,10 +58814,10 @@ SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){
if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){
if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg);
return SQLITE_OK;
- }else if( pPager->errCode ){
- return pPager->errCode;
+ }else if( pPager->errCode ){
+ return pPager->errCode;
}else if( pPager->sectorSize > (u32)pPager->pageSize ){
- assert( pPager->tempFile==0 );
+ assert( pPager->tempFile==0 );
return pagerWriteLargeSector(pPg);
}else{
return pager_write(pPg);
@@ -58848,21 +58848,21 @@ SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){
**
** Tests show that this optimization can quadruple the speed of large
** DELETE operations.
-**
-** This optimization cannot be used with a temp-file, as the page may
-** have been dirty at the start of the transaction. In that case, if
+**
+** This optimization cannot be used with a temp-file, as the page may
+** have been dirty at the start of the transaction. In that case, if
** memory pressure forces page pPg out of the cache, the data does need
** to be written out to disk so that it may be read back in if the
-** current transaction is rolled back.
+** current transaction is rolled back.
*/
SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
Pager *pPager = pPg->pPager;
- if( !pPager->tempFile && (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
+ if( !pPager->tempFile && (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
pPg->flags |= PGHDR_DONT_WRITE;
pPg->flags &= ~PGHDR_WRITEABLE;
- testcase( pPg->flags & PGHDR_NEED_SYNC );
+ testcase( pPg->flags & PGHDR_NEED_SYNC );
pager_set_pagehash(pPg);
}
}
@@ -58921,7 +58921,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
assert( !pPager->tempFile && isOpen(pPager->fd) );
/* Open page 1 of the file for writing. */
- rc = sqlite3PagerGet(pPager, 1, &pPgHdr, 0);
+ rc = sqlite3PagerGet(pPager, 1, &pPgHdr, 0);
assert( pPgHdr==0 || rc==SQLITE_OK );
/* If page one was fetched successfully, and this function is not
@@ -58996,17 +58996,17 @@ SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zSuper){
** returned.
*/
SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){
- int rc = pPager->errCode;
+ int rc = pPager->errCode;
assert( assert_pager_state(pPager) );
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
assert( pPager->eState==PAGER_WRITER_CACHEMOD
|| pPager->eState==PAGER_WRITER_DBMOD
|| pPager->eState==PAGER_WRITER_LOCKED
- );
- assert( assert_pager_state(pPager) );
- if( 0==pagerUseWal(pPager) ){
- rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
- }
+ );
+ assert( assert_pager_state(pPager) );
+ if( 0==pagerUseWal(pPager) ){
+ rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
+ }
}
return rc;
}
@@ -59054,21 +59054,21 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
/* If a prior error occurred, report that error again. */
if( NEVER(pPager->errCode) ) return pPager->errCode;
- /* Provide the ability to easily simulate an I/O error during testing */
- if( sqlite3FaultSim(400) ) return SQLITE_IOERR;
-
+ /* Provide the ability to easily simulate an I/O error during testing */
+ if( sqlite3FaultSim(400) ) return SQLITE_IOERR;
+
PAGERTRACE(("DATABASE SYNC: File=%s zSuper=%s nSize=%d\n",
pPager->zFilename, zSuper, pPager->dbSize));
/* If no database changes have been made, return early. */
if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
- assert( MEMDB==0 || pPager->tempFile );
- assert( isOpen(pPager->fd) || pPager->tempFile );
- if( 0==pagerFlushOnCommit(pPager, 1) ){
+ assert( MEMDB==0 || pPager->tempFile );
+ assert( isOpen(pPager->fd) || pPager->tempFile );
+ if( 0==pagerFlushOnCommit(pPager, 1) ){
/* If this is an in-memory db, or no pages have been written to, or this
** function has already been called, it is mostly a no-op. However, any
- ** backup in progress needs to be restarted. */
+ ** backup in progress needs to be restarted. */
sqlite3BackupRestart(pPager->pBackup);
}else{
PgHdr *pList;
@@ -59078,7 +59078,7 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
if( pList==0 ){
/* Must have at least one page for the WAL commit flag.
** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
- rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0);
+ rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0);
pList = pPageOne;
pList->pDirty = 0;
}
@@ -59091,21 +59091,21 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
sqlite3PcacheCleanAll(pPager->pPCache);
}
}else{
- /* The bBatch boolean is true if the batch-atomic-write commit method
- ** should be used. No rollback journal is created if batch-atomic-write
- ** is enabled.
- */
+ /* The bBatch boolean is true if the batch-atomic-write commit method
+ ** should be used. No rollback journal is created if batch-atomic-write
+ ** is enabled.
+ */
#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
- sqlite3_file *fd = pPager->fd;
+ sqlite3_file *fd = pPager->fd;
int bBatch = zSuper==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */
- && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC)
- && !pPager->noSync
- && sqlite3JournalIsInMemory(pPager->jfd);
-#else
+ && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC)
+ && !pPager->noSync
+ && sqlite3JournalIsInMemory(pPager->jfd);
+#else
# define bBatch 0
-#endif
-
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+#endif
+
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
/* The following block updates the change-counter. Exactly how it
** does this depends on whether or not the atomic-update optimization
** was enabled at compile time, and if this transaction meets the
@@ -59129,39 +59129,39 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
** in 'direct' mode. In this case the journal file will never be
** created for this transaction.
*/
- if( bBatch==0 ){
- PgHdr *pPg;
+ if( bBatch==0 ){
+ PgHdr *pPg;
assert( isOpen(pPager->jfd)
|| pPager->journalMode==PAGER_JOURNALMODE_OFF
|| pPager->journalMode==PAGER_JOURNALMODE_WAL
- );
+ );
if( !zSuper && isOpen(pPager->jfd)
&& pPager->journalOff==jrnlBufferSize(pPager)
- && pPager->dbSize>=pPager->dbOrigSize
- && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
- ){
+ && pPager->dbSize>=pPager->dbOrigSize
+ && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
+ ){
/* Update the db file change counter via the direct-write method. The
** following call will modify the in-memory representation of page 1
** to include the updated change counter and then write page 1
** directly to the database file. Because of the atomic-write
- ** property of the host file-system, this is safe.
- */
- rc = pager_incr_changecounter(pPager, 1);
- }else{
- rc = sqlite3JournalCreate(pPager->jfd);
- if( rc==SQLITE_OK ){
- rc = pager_incr_changecounter(pPager, 0);
- }
+ ** property of the host file-system, this is safe.
+ */
+ rc = pager_incr_changecounter(pPager, 1);
+ }else{
+ rc = sqlite3JournalCreate(pPager->jfd);
+ if( rc==SQLITE_OK ){
+ rc = pager_incr_changecounter(pPager, 0);
+ }
}
}
#else /* SQLITE_ENABLE_ATOMIC_WRITE */
-#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
if( zSuper ){
- rc = sqlite3JournalCreate(pPager->jfd);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+ rc = sqlite3JournalCreate(pPager->jfd);
+ if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
assert( bBatch==0 );
- }
-#endif
+ }
+#endif
rc = pager_incr_changecounter(pPager, 0);
#endif /* !SQLITE_ENABLE_ATOMIC_WRITE */
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
@@ -59186,12 +59186,12 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
*/
rc = syncJournal(pPager, 0);
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
-
+
pList = sqlite3PcacheDirtyList(pPager->pPCache);
#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
- if( bBatch ){
- rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0);
- if( rc==SQLITE_OK ){
+ if( bBatch ){
+ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0);
+ if( rc==SQLITE_OK ){
rc = pager_write_pagelist(pPager, pList);
if( rc==SQLITE_OK ){
rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0);
@@ -59208,12 +59208,12 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
goto commit_phase_one_exit;
}
bBatch = 0;
- }else{
+ }else{
sqlite3OsClose(pPager->jfd);
- }
- }
+ }
+ }
#endif /* SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
-
+
if( bBatch==0 ){
rc = pager_write_pagelist(pPager, pList);
}
@@ -59360,7 +59360,7 @@ SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
*/
pPager->errCode = SQLITE_ABORT;
pPager->eState = PAGER_ERROR;
- setGetterMethod(pPager);
+ setGetterMethod(pPager);
return rc;
}
}else{
@@ -59389,7 +59389,7 @@ SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){
#ifdef SQLITE_DEBUG
/*
-** Return the sum of the reference counts for all pages held by pPager.
+** Return the sum of the reference counts for all pages held by pPager.
*/
SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
return sqlite3PcacheRefCount(pPager->pPCache);
@@ -59468,7 +59468,7 @@ SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, i
}
/*
-** Return true if this is an in-memory or temp-file backed pager.
+** Return true if this is an in-memory or temp-file backed pager.
*/
SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
return pPager->tempFile || pPager->memVfs;
@@ -59502,7 +59502,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
);
if( !aNew ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
pPager->aSavepoint = aNew;
@@ -59519,7 +59519,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
aNew[ii].bTruncateOnRelease = 1;
if( !aNew[ii].pInSavepoint ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
if( pagerUseWal(pPager) ){
sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
@@ -59573,11 +59573,11 @@ SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
** savepoint. If no errors occur, SQLITE_OK is returned.
*/
SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
- int rc = pPager->errCode;
+ int rc = pPager->errCode;
-#ifdef SQLITE_ENABLE_ZIPVFS
- if( op==SAVEPOINT_RELEASE ) rc = SQLITE_OK;
-#endif
+#ifdef SQLITE_ENABLE_ZIPVFS
+ if( op==SAVEPOINT_RELEASE ) rc = SQLITE_OK;
+#endif
assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
@@ -59602,7 +59602,7 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
PagerSavepoint *pRel = &pPager->aSavepoint[nNew];
if( pRel->bTruncateOnRelease && isOpen(pPager->sjfd) ){
/* Only truncate if it is an in-memory sub-journal. */
- if( sqlite3JournalIsInMemory(pPager->sjfd) ){
+ if( sqlite3JournalIsInMemory(pPager->sjfd) ){
i64 sz = (pPager->pageSize+4)*(i64)pRel->iSubRec;
rc = sqlite3OsTruncate(pPager->sjfd, sz);
assert( rc==SQLITE_OK );
@@ -59621,20 +59621,20 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
assert(rc!=SQLITE_DONE);
}
-#ifdef SQLITE_ENABLE_ZIPVFS
+#ifdef SQLITE_ENABLE_ZIPVFS
/* If the cache has been modified but the savepoint cannot be rolled
- ** back journal_mode=off, put the pager in the error state. This way,
- ** if the VFS used by this pager includes ZipVFS, the entire transaction
- ** can be rolled back at the ZipVFS level. */
+ ** back journal_mode=off, put the pager in the error state. This way,
+ ** if the VFS used by this pager includes ZipVFS, the entire transaction
+ ** can be rolled back at the ZipVFS level. */
else if(
pPager->journalMode==PAGER_JOURNALMODE_OFF
- && pPager->eState>=PAGER_WRITER_CACHEMOD
- ){
- pPager->errCode = SQLITE_ABORT;
- pPager->eState = PAGER_ERROR;
- setGetterMethod(pPager);
- }
-#endif
+ && pPager->eState>=PAGER_WRITER_CACHEMOD
+ ){
+ pPager->errCode = SQLITE_ABORT;
+ pPager->eState = PAGER_ERROR;
+ setGetterMethod(pPager);
+ }
+#endif
}
return rc;
@@ -59661,7 +59661,7 @@ SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager *pPager, int nullIfM
/*
** Return the VFS structure for the pager.
*/
-SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
+SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
return pPager->pVfs;
}
@@ -59675,22 +59675,22 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
}
/*
-** Return the file handle for the journal file (if it exists).
-** This will be either the rollback journal or the WAL file.
+** Return the file handle for the journal file (if it exists).
+** This will be either the rollback journal or the WAL file.
*/
-SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
-#if SQLITE_OMIT_WAL
- return pPager->jfd;
-#else
- return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd;
-#endif
+SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
+#if SQLITE_OMIT_WAL
+ return pPager->jfd;
+#else
+ return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd;
+#endif
}
/*
-** Return the full pathname of the journal file.
+** Return the full pathname of the journal file.
*/
-SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
- return pPager->zJournal;
+SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
+ return pPager->zJournal;
}
#ifndef SQLITE_OMIT_AUTOVACUUM
@@ -59734,8 +59734,8 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
/* In order to be able to rollback, an in-memory database must journal
** the page we are moving from.
*/
- assert( pPager->tempFile || !MEMDB );
- if( pPager->tempFile ){
+ assert( pPager->tempFile || !MEMDB );
+ if( pPager->tempFile ){
rc = sqlite3PagerWrite(pPg);
if( rc ) return rc;
}
@@ -59796,7 +59796,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
return SQLITE_CORRUPT_BKPT;
}
pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
- if( pPager->tempFile ){
+ if( pPager->tempFile ){
/* Do not discard pages from an in-memory database since we might
** need to rollback later. Just move the page out of the way. */
sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
@@ -59813,7 +59813,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
** to exist, in case the transaction needs to roll back. Use pPgOld
** as the original page since it has already been allocated.
*/
- if( pPager->tempFile && pPgOld ){
+ if( pPager->tempFile && pPgOld ){
sqlite3PcacheMove(pPgOld, origPgno);
sqlite3PagerUnrefNotNull(pPgOld);
}
@@ -59834,7 +59834,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
** the journal file twice, but that is not a problem.
*/
PgHdr *pPgHdr;
- rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0);
+ rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0);
if( rc!=SQLITE_OK ){
if( needSyncPgno<=pPager->dbOrigSize ){
assert( pPager->pTmpSpace!=0 );
@@ -60058,12 +60058,12 @@ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
** Unless this is an in-memory or temporary database, clear the pager cache.
*/
SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
- assert( MEMDB==0 || pPager->tempFile );
- if( pPager->tempFile==0 ) pager_reset(pPager);
+ assert( MEMDB==0 || pPager->tempFile );
+ if( pPager->tempFile==0 ) pager_reset(pPager);
}
#endif
-
+
#ifndef SQLITE_OMIT_WAL
/*
** This function is called when the user invokes "PRAGMA wal_checkpoint",
@@ -60072,19 +60072,19 @@ SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
**
** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
*/
-SQLITE_PRIVATE int sqlite3PagerCheckpoint(
- Pager *pPager, /* Checkpoint on this pager */
- sqlite3 *db, /* Db handle used to check for interrupts */
- int eMode, /* Type of checkpoint */
- int *pnLog, /* OUT: Final number of frames in log */
- int *pnCkpt /* OUT: Final number of checkpointed frames */
-){
+SQLITE_PRIVATE int sqlite3PagerCheckpoint(
+ Pager *pPager, /* Checkpoint on this pager */
+ sqlite3 *db, /* Db handle used to check for interrupts */
+ int eMode, /* Type of checkpoint */
+ int *pnLog, /* OUT: Final number of frames in log */
+ int *pnCkpt /* OUT: Final number of checkpointed frames */
+){
int rc = SQLITE_OK;
if( pPager->pWal ){
- rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
+ rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
pPager->pBusyHandlerArg,
- pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
+ pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
pnLog, pnCkpt
);
}
@@ -60101,7 +60101,7 @@ SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
*/
SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){
const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
- if( pPager->noLock ) return 0;
+ if( pPager->noLock ) return 0;
return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
}
@@ -60213,7 +60213,7 @@ SQLITE_PRIVATE int sqlite3PagerOpenWal(
** error (SQLITE_BUSY) is returned and the log connection is not closed.
** If successful, the EXCLUSIVE lock is not released before returning.
*/
-SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
+SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
int rc = SQLITE_OK;
assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
@@ -60241,11 +60241,11 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
if( rc==SQLITE_OK && pPager->pWal ){
rc = pagerExclusiveLock(pPager);
if( rc==SQLITE_OK ){
- rc = sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags,
+ rc = sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags,
pPager->pageSize, (u8*)pPager->pTmpSpace);
pPager->pWal = 0;
pagerFixMaplimit(pPager);
- if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
+ if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
}
}
return rc;
@@ -60277,50 +60277,50 @@ SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){
}
#endif
-#ifdef SQLITE_ENABLE_SNAPSHOT
-/*
-** If this is a WAL database, obtain a snapshot handle for the snapshot
-** currently open. Otherwise, return an error.
-*/
-SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){
- int rc = SQLITE_ERROR;
- if( pPager->pWal ){
- rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot);
- }
- return rc;
-}
-
-/*
-** If this is a WAL database, store a pointer to pSnapshot. Next time a
+#ifdef SQLITE_ENABLE_SNAPSHOT
+/*
+** If this is a WAL database, obtain a snapshot handle for the snapshot
+** currently open. Otherwise, return an error.
+*/
+SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){
+ int rc = SQLITE_ERROR;
+ if( pPager->pWal ){
+ rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot);
+ }
+ return rc;
+}
+
+/*
+** If this is a WAL database, store a pointer to pSnapshot. Next time a
** read transaction is opened, attempt to read from the snapshot it
-** identifies. If this is not a WAL database, return an error.
-*/
+** identifies. If this is not a WAL database, return an error.
+*/
SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(
Pager *pPager,
sqlite3_snapshot *pSnapshot
){
- int rc = SQLITE_OK;
- if( pPager->pWal ){
- sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
- }else{
- rc = SQLITE_ERROR;
- }
- return rc;
-}
-
-/*
+ int rc = SQLITE_OK;
+ if( pPager->pWal ){
+ sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
+ }else{
+ rc = SQLITE_ERROR;
+ }
+ return rc;
+}
+
+/*
** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this
-** is not a WAL database, return an error.
-*/
-SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager){
- int rc;
- if( pPager->pWal ){
- rc = sqlite3WalSnapshotRecover(pPager->pWal);
- }else{
- rc = SQLITE_ERROR;
- }
- return rc;
-}
+** is not a WAL database, return an error.
+*/
+SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager){
+ int rc;
+ if( pPager->pWal ){
+ rc = sqlite3WalSnapshotRecover(pPager->pWal);
+ }else{
+ rc = SQLITE_ERROR;
+ }
+ return rc;
+}
/*
** The caller currently has a read transaction open on the database.
@@ -60353,7 +60353,7 @@ SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){
sqlite3WalSnapshotUnlock(pPager->pWal);
}
-#endif /* SQLITE_ENABLE_SNAPSHOT */
+#endif /* SQLITE_ENABLE_SNAPSHOT */
#endif /* !SQLITE_OMIT_WAL */
#ifdef SQLITE_ENABLE_ZIPVFS
@@ -60508,10 +60508,10 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
** on a network filesystem. All users of the database must be able to
** share memory.
**
-** In the default unix and windows implementation, the wal-index is a mmapped
-** file whose name is the database name with a "-shm" suffix added. For that
-** reason, the wal-index is sometimes called the "shm" file.
-**
+** In the default unix and windows implementation, the wal-index is a mmapped
+** file whose name is the database name with a "-shm" suffix added. For that
+** reason, the wal-index is sometimes called the "shm" file.
+**
** The wal-index is transient. After a crash, the wal-index can (and should
** be) reconstructed from the original WAL file. In fact, the VFS is required
** to either truncate or zero the header of the wal-index when the last
@@ -60654,18 +60654,18 @@ SQLITE_PRIVATE int sqlite3WalTrace = 0;
#define WALINDEX_MAX_VERSION 3007000
/*
-** Index numbers for various locking bytes. WAL_NREADER is the number
-** of available reader locks and should be at least 3. The default
-** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5.
-**
-** Technically, the various VFSes are free to implement these locks however
-** they see fit. However, compatibility is encouraged so that VFSes can
-** interoperate. The standard implemention used on both unix and windows
-** is for the index number to indicate a byte offset into the
-** WalCkptInfo.aLock[] array in the wal-index header. In other words, all
-** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which
-** should be 120) is the location in the shm file for the first locking
-** byte.
+** Index numbers for various locking bytes. WAL_NREADER is the number
+** of available reader locks and should be at least 3. The default
+** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5.
+**
+** Technically, the various VFSes are free to implement these locks however
+** they see fit. However, compatibility is encouraged so that VFSes can
+** interoperate. The standard implemention used on both unix and windows
+** is for the index number to indicate a byte offset into the
+** WalCkptInfo.aLock[] array in the wal-index header. In other words, all
+** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which
+** should be 120) is the location in the shm file for the first locking
+** byte.
*/
#define WAL_WRITE_LOCK 0
#define WAL_ALL_BUT_WRITE 1
@@ -60685,10 +60685,10 @@ typedef struct WalCkptInfo WalCkptInfo;
** The following object holds a copy of the wal-index header content.
**
** The actual header in the wal-index consists of two copies of this
-** object followed by one instance of the WalCkptInfo object.
-** For all versions of SQLite through 3.10.0 and probably beyond,
-** the locking bytes (WalCkptInfo.aLock) start at offset 120 and
-** the total header size is 136 bytes.
+** object followed by one instance of the WalCkptInfo object.
+** For all versions of SQLite through 3.10.0 and probably beyond,
+** the locking bytes (WalCkptInfo.aLock) start at offset 120 and
+** the total header size is 136 bytes.
**
** The szPage value can be any power of 2 between 512 and 32768, inclusive.
** Or it can be 1 to represent a 65536-byte page. The latter case was
@@ -60721,16 +60721,16 @@ struct WalIndexHdr {
** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from
** mxFrame back to zero when the WAL is reset.
**
-** nBackfillAttempted is the largest value of nBackfill that a checkpoint
-** has attempted to achieve. Normally nBackfill==nBackfillAtempted, however
-** the nBackfillAttempted is set before any backfilling is done and the
-** nBackfill is only set after all backfilling completes. So if a checkpoint
-** crashes, nBackfillAttempted might be larger than nBackfill. The
-** WalIndexHdr.mxFrame must never be less than nBackfillAttempted.
-**
-** The aLock[] field is a set of bytes used for locking. These bytes should
-** never be read or written.
-**
+** nBackfillAttempted is the largest value of nBackfill that a checkpoint
+** has attempted to achieve. Normally nBackfill==nBackfillAtempted, however
+** the nBackfillAttempted is set before any backfilling is done and the
+** nBackfill is only set after all backfilling completes. So if a checkpoint
+** crashes, nBackfillAttempted might be larger than nBackfill. The
+** WalIndexHdr.mxFrame must never be less than nBackfillAttempted.
+**
+** The aLock[] field is a set of bytes used for locking. These bytes should
+** never be read or written.
+**
** There is one entry in aReadMark[] for each reader lock. If a reader
** holds read-lock K, then the value in aReadMark[K] is no greater than
** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff)
@@ -60770,9 +60770,9 @@ struct WalIndexHdr {
struct WalCkptInfo {
u32 nBackfill; /* Number of WAL frames backfilled into DB */
u32 aReadMark[WAL_NREADER]; /* Reader marks */
- u8 aLock[SQLITE_SHM_NLOCK]; /* Reserved space for locks */
- u32 nBackfillAttempted; /* WAL frames perhaps written, or maybe not */
- u32 notUsed0; /* Available for future enhancements */
+ u8 aLock[SQLITE_SHM_NLOCK]; /* Reserved space for locks */
+ u32 nBackfillAttempted; /* WAL frames perhaps written, or maybe not */
+ u32 notUsed0; /* Available for future enhancements */
};
#define READMARK_NOT_USED 0xffffffff
@@ -60846,8 +60846,8 @@ struct WalCkptInfo {
** only support mandatory file-locks, we do not read or write data
** from the region of the file on which locks are applied.
*/
-#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2+offsetof(WalCkptInfo,aLock))
-#define WALINDEX_HDR_SIZE (sizeof(WalIndexHdr)*2+sizeof(WalCkptInfo))
+#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2+offsetof(WalCkptInfo,aLock))
+#define WALINDEX_HDR_SIZE (sizeof(WalIndexHdr)*2+sizeof(WalCkptInfo))
/* Size of header before each frame in wal */
#define WAL_FRAME_HDRSIZE 24
@@ -60898,18 +60898,18 @@ struct Wal {
u8 truncateOnCommit; /* True to truncate WAL file on commit */
u8 syncHeader; /* Fsync the WAL header if true */
u8 padToSectorBoundary; /* Pad transactions out to the next sector */
- u8 bShmUnreliable; /* SHM content is read-only and unreliable */
+ u8 bShmUnreliable; /* SHM content is read-only and unreliable */
WalIndexHdr hdr; /* Wal-index header for current transaction */
- u32 minFrame; /* Ignore wal frames before this one */
- u32 iReCksum; /* On commit, recalculate checksums from here */
+ u32 minFrame; /* Ignore wal frames before this one */
+ u32 iReCksum; /* On commit, recalculate checksums from here */
const char *zWalName; /* Name of WAL file */
u32 nCkpt; /* Checkpoint sequence counter in the wal-header */
#ifdef SQLITE_DEBUG
u8 lockError; /* True if a locking error has occurred */
#endif
-#ifdef SQLITE_ENABLE_SNAPSHOT
- WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */
-#endif
+#ifdef SQLITE_ENABLE_SNAPSHOT
+ WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */
+#endif
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
sqlite3 *db;
#endif
@@ -60991,11 +60991,11 @@ struct WalIterator {
** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are
** numbered from zero.
**
-** If the wal-index is currently smaller the iPage pages then the size
-** of the wal-index might be increased, but only if it is safe to do
-** so. It is safe to enlarge the wal-index if pWal->writeLock is true
-** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
-**
+** If the wal-index is currently smaller the iPage pages then the size
+** of the wal-index might be increased, but only if it is safe to do
+** so. It is safe to enlarge the wal-index if pWal->writeLock is true
+** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
+**
** Three possible result scenarios:
**
** (1) rc==SQLITE_OK and *ppPage==Requested-Wal-Index-Page
@@ -61018,7 +61018,7 @@ static SQLITE_NOINLINE int walIndexPageRealloc(
apNew = (volatile u32 **)sqlite3Realloc((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
memset((void*)&apNew[pWal->nWiData], 0,
sizeof(u32*)*(iPage+1-pWal->nWiData));
@@ -61207,18 +61207,18 @@ static void walEncodeFrame(
assert( WAL_FRAME_HDRSIZE==24 );
sqlite3Put4byte(&aFrame[0], iPage);
sqlite3Put4byte(&aFrame[4], nTruncate);
- if( pWal->iReCksum==0 ){
- memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
+ if( pWal->iReCksum==0 ){
+ memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
- nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
- walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
- walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
+ nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
+ walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
+ walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
- sqlite3Put4byte(&aFrame[16], aCksum[0]);
- sqlite3Put4byte(&aFrame[20], aCksum[1]);
- }else{
- memset(&aFrame[8], 0, 16);
- }
+ sqlite3Put4byte(&aFrame[16], aCksum[0]);
+ sqlite3Put4byte(&aFrame[20], aCksum[1]);
+ }else{
+ memset(&aFrame[8], 0, 16);
+ }
}
/*
@@ -61321,7 +61321,7 @@ static void walUnlockShared(Wal *pWal, int lockIdx){
SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
}
-static int walLockExclusive(Wal *pWal, int lockIdx, int n){
+static int walLockExclusive(Wal *pWal, int lockIdx, int n){
int rc;
if( pWal->exclusiveMode ) return SQLITE_OK;
rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
@@ -61612,11 +61612,11 @@ static int walIndexRecover(Wal *pWal){
assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
assert( pWal->writeLock );
iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
- rc = walLockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
+ rc = walLockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
if( rc ){
return rc;
}
-
+
WALTRACE(("WAL%p: recovery begin...\n", pWal));
memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
@@ -61686,7 +61686,7 @@ static int walIndexRecover(Wal *pWal){
szFrame = szPage + WAL_FRAME_HDRSIZE;
aFrame = (u8 *)sqlite3_malloc64(szFrame + WALINDEX_PGSZ);
if( !aFrame ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto recovery_error;
}
aData = &aFrame[WAL_FRAME_HDRSIZE];
@@ -61780,7 +61780,7 @@ finished:
*/
pInfo = walCkptInfo(pWal);
pInfo->nBackfill = 0;
- pInfo->nBackfillAttempted = pWal->hdr.mxFrame;
+ pInfo->nBackfillAttempted = pWal->hdr.mxFrame;
pInfo->aReadMark[0] = 0;
for(i=1; i<WAL_NREADER; i++){
rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
@@ -61811,7 +61811,7 @@ finished:
recovery_error:
WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
- walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
+ walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
return rc;
}
@@ -61819,14 +61819,14 @@ recovery_error:
** Close an open wal-index.
*/
static void walIndexClose(Wal *pWal, int isDelete){
- if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE || pWal->bShmUnreliable ){
+ if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE || pWal->bShmUnreliable ){
int i;
for(i=0; i<pWal->nWiData; i++){
sqlite3_free((void *)pWal->apWiData[i]);
pWal->apWiData[i] = 0;
}
- }
- if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
+ }
+ if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
}
}
@@ -61895,8 +61895,8 @@ SQLITE_PRIVATE int sqlite3WalOpen(
/* In the amalgamation, the os_unix.c and os_win.c source files come before
** this source file. Verify that the #defines of the locking byte offsets
** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value.
- ** For that matter, if the lock offset ever changes from its initial design
- ** value of 120, we need to know that so there is an assert() to check it.
+ ** For that matter, if the lock offset ever changes from its initial design
+ ** value of 120, we need to know that so there is an assert() to check it.
*/
#ifdef WIN_SHM_BASE
assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET );
@@ -61910,7 +61910,7 @@ SQLITE_PRIVATE int sqlite3WalOpen(
*ppWal = 0;
pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
if( !pRet ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
pRet->pVfs = pVfs;
@@ -62175,7 +62175,7 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
+ iLast*sizeof(ht_slot);
p = (WalIterator *)sqlite3_malloc64(nByte);
if( !p ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
memset(p, 0, nByte);
p->nSegment = nSegment;
@@ -62187,7 +62187,7 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
);
if( !aTmp ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){
@@ -62325,7 +62325,7 @@ static int walBusyLock(
){
int rc;
do {
- rc = walLockExclusive(pWal, lockIdx, n);
+ rc = walLockExclusive(pWal, lockIdx, n);
}while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ){
@@ -62371,7 +62371,7 @@ static void walRestartHdr(Wal *pWal, u32 salt1){
memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
walIndexWriteHdr(pWal);
AtomicStore(&pInfo->nBackfill, 0);
- pInfo->nBackfillAttempted = 0;
+ pInfo->nBackfillAttempted = 0;
pInfo->aReadMark[1] = 0;
for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
assert( pInfo->aReadMark[0]==0 );
@@ -62410,7 +62410,7 @@ static void walRestartHdr(Wal *pWal, u32 salt1){
*/
static int walCheckpoint(
Wal *pWal, /* Wal connection */
- sqlite3 *db, /* Check for interrupts on this handle */
+ sqlite3 *db, /* Check for interrupts on this handle */
int eMode, /* One of PASSIVE, FULL or RESTART */
int (*xBusy)(void*), /* Function to call when busy */
void *pBusyArg, /* Context argument for xBusyHandler */
@@ -62473,10 +62473,10 @@ static int walCheckpoint(
){
u32 nBackfill = pInfo->nBackfill;
- pInfo->nBackfillAttempted = mxSafeFrame;
-
+ pInfo->nBackfillAttempted = mxSafeFrame;
+
/* Sync the WAL to disk */
- rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags));
+ rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags));
/* If the database may grow as a result of this checkpoint, hint
** about the eventual size of the db file to the VFS layer.
@@ -62505,9 +62505,9 @@ static int walCheckpoint(
i64 iOffset;
assert( walFramePgno(pWal, iFrame)==iDbpage );
if( AtomicLoad(&db->u1.isInterrupted) ){
- rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
- break;
- }
+ rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
+ break;
+ }
if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
continue;
}
@@ -62528,8 +62528,8 @@ static int walCheckpoint(
i64 szDb = pWal->hdr.nPage*(i64)szPage;
testcase( IS_BIG_INT(szDb) );
rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
- if( rc==SQLITE_OK ){
- rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
+ if( rc==SQLITE_OK ){
+ rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
}
}
if( rc==SQLITE_OK ){
@@ -62613,7 +62613,7 @@ static void walLimitSize(Wal *pWal, i64 nMax){
*/
SQLITE_PRIVATE int sqlite3WalClose(
Wal *pWal, /* Wal to close */
- sqlite3 *db, /* For interrupt flag */
+ sqlite3 *db, /* For interrupt flag */
int sync_flags, /* Flags to pass to OsSync() (or 0) */
int nBuf,
u8 *zBuf /* Buffer of at least nBuf bytes */
@@ -62630,14 +62630,14 @@ SQLITE_PRIVATE int sqlite3WalClose(
**
** The EXCLUSIVE lock is not released before returning.
*/
- if( zBuf!=0
- && SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE))
- ){
+ if( zBuf!=0
+ && SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE))
+ ){
if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
}
rc = sqlite3WalCheckpoint(pWal, db,
- SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
+ SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
);
if( rc==SQLITE_OK ){
int bPersist = -1;
@@ -62745,12 +62745,12 @@ static SQLITE_NO_TSAN int walIndexTryHdr(Wal *pWal, int *pChanged){
}
/*
-** This is the value that walTryBeginRead returns when it needs to
-** be retried.
-*/
-#define WAL_RETRY (-1)
-
-/*
+** This is the value that walTryBeginRead returns when it needs to
+** be retried.
+*/
+#define WAL_RETRY (-1)
+
+/*
** Read the wal-index header from the wal-index and into pWal->hdr.
** If the wal-header appears to be corrupt, try to reconstruct the
** wal-index from the WAL before returning.
@@ -62773,29 +62773,29 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
assert( pChanged );
rc = walIndexPage(pWal, 0, &page0);
if( rc!=SQLITE_OK ){
- assert( rc!=SQLITE_READONLY ); /* READONLY changed to OK in walIndexPage */
- if( rc==SQLITE_READONLY_CANTINIT ){
- /* The SQLITE_READONLY_CANTINIT return means that the shared-memory
- ** was openable but is not writable, and this thread is unable to
- ** confirm that another write-capable connection has the shared-memory
- ** open, and hence the content of the shared-memory is unreliable,
- ** since the shared-memory might be inconsistent with the WAL file
- ** and there is no writer on hand to fix it. */
- assert( page0==0 );
- assert( pWal->writeLock==0 );
- assert( pWal->readOnly & WAL_SHM_RDONLY );
- pWal->bShmUnreliable = 1;
- pWal->exclusiveMode = WAL_HEAPMEMORY_MODE;
- *pChanged = 1;
- }else{
- return rc; /* Any other non-OK return is just an error */
- }
- }else{
- /* page0 can be NULL if the SHM is zero bytes in size and pWal->writeLock
- ** is zero, which prevents the SHM from growing */
- testcase( page0!=0 );
- }
- assert( page0!=0 || pWal->writeLock==0 );
+ assert( rc!=SQLITE_READONLY ); /* READONLY changed to OK in walIndexPage */
+ if( rc==SQLITE_READONLY_CANTINIT ){
+ /* The SQLITE_READONLY_CANTINIT return means that the shared-memory
+ ** was openable but is not writable, and this thread is unable to
+ ** confirm that another write-capable connection has the shared-memory
+ ** open, and hence the content of the shared-memory is unreliable,
+ ** since the shared-memory might be inconsistent with the WAL file
+ ** and there is no writer on hand to fix it. */
+ assert( page0==0 );
+ assert( pWal->writeLock==0 );
+ assert( pWal->readOnly & WAL_SHM_RDONLY );
+ pWal->bShmUnreliable = 1;
+ pWal->exclusiveMode = WAL_HEAPMEMORY_MODE;
+ *pChanged = 1;
+ }else{
+ return rc; /* Any other non-OK return is just an error */
+ }
+ }else{
+ /* page0 can be NULL if the SHM is zero bytes in size and pWal->writeLock
+ ** is zero, which prevents the SHM from growing */
+ testcase( page0!=0 );
+ }
+ assert( page0!=0 || pWal->writeLock==0 );
/* If the first page of the wal-index has been mapped, try to read the
** wal-index header immediately, without holding any lock. This usually
@@ -62808,7 +62808,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
** with a writer. So get a WRITE lock and try again.
*/
if( badHdr ){
- if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
+ if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
walUnlockShared(pWal, WAL_WRITE_LOCK);
rc = SQLITE_READONLY_RECOVERY;
@@ -62843,194 +62843,194 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){
rc = SQLITE_CANTOPEN_BKPT;
}
- if( pWal->bShmUnreliable ){
- if( rc!=SQLITE_OK ){
- walIndexClose(pWal, 0);
- pWal->bShmUnreliable = 0;
- assert( pWal->nWiData>0 && pWal->apWiData[0]==0 );
- /* walIndexRecover() might have returned SHORT_READ if a concurrent
- ** writer truncated the WAL out from under it. If that happens, it
- ** indicates that a writer has fixed the SHM file for us, so retry */
- if( rc==SQLITE_IOERR_SHORT_READ ) rc = WAL_RETRY;
- }
- pWal->exclusiveMode = WAL_NORMAL_MODE;
- }
-
- return rc;
-}
-
-/*
-** Open a transaction in a connection where the shared-memory is read-only
-** and where we cannot verify that there is a separate write-capable connection
-** on hand to keep the shared-memory up-to-date with the WAL file.
-**
-** This can happen, for example, when the shared-memory is implemented by
-** memory-mapping a *-shm file, where a prior writer has shut down and
-** left the *-shm file on disk, and now the present connection is trying
-** to use that database but lacks write permission on the *-shm file.
-** Other scenarios are also possible, depending on the VFS implementation.
-**
-** Precondition:
-**
-** The *-wal file has been read and an appropriate wal-index has been
-** constructed in pWal->apWiData[] using heap memory instead of shared
+ if( pWal->bShmUnreliable ){
+ if( rc!=SQLITE_OK ){
+ walIndexClose(pWal, 0);
+ pWal->bShmUnreliable = 0;
+ assert( pWal->nWiData>0 && pWal->apWiData[0]==0 );
+ /* walIndexRecover() might have returned SHORT_READ if a concurrent
+ ** writer truncated the WAL out from under it. If that happens, it
+ ** indicates that a writer has fixed the SHM file for us, so retry */
+ if( rc==SQLITE_IOERR_SHORT_READ ) rc = WAL_RETRY;
+ }
+ pWal->exclusiveMode = WAL_NORMAL_MODE;
+ }
+
+ return rc;
+}
+
+/*
+** Open a transaction in a connection where the shared-memory is read-only
+** and where we cannot verify that there is a separate write-capable connection
+** on hand to keep the shared-memory up-to-date with the WAL file.
+**
+** This can happen, for example, when the shared-memory is implemented by
+** memory-mapping a *-shm file, where a prior writer has shut down and
+** left the *-shm file on disk, and now the present connection is trying
+** to use that database but lacks write permission on the *-shm file.
+** Other scenarios are also possible, depending on the VFS implementation.
+**
+** Precondition:
+**
+** The *-wal file has been read and an appropriate wal-index has been
+** constructed in pWal->apWiData[] using heap memory instead of shared
** memory.
-**
-** If this function returns SQLITE_OK, then the read transaction has
+**
+** If this function returns SQLITE_OK, then the read transaction has
** been successfully opened. In this case output variable (*pChanged)
-** is set to true before returning if the caller should discard the
+** is set to true before returning if the caller should discard the
** contents of the page cache before proceeding. Or, if it returns
** WAL_RETRY, then the heap memory wal-index has been discarded and
** the caller should retry opening the read transaction from the
** beginning (including attempting to map the *-shm file).
-**
-** If an error occurs, an SQLite error code is returned.
-*/
-static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
- i64 szWal; /* Size of wal file on disk in bytes */
- i64 iOffset; /* Current offset when reading wal file */
- u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */
- u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */
- int szFrame; /* Number of bytes in buffer aFrame[] */
- u8 *aData; /* Pointer to data part of aFrame buffer */
- volatile void *pDummy; /* Dummy argument for xShmMap */
- int rc; /* Return code */
- u32 aSaveCksum[2]; /* Saved copy of pWal->hdr.aFrameCksum */
-
- assert( pWal->bShmUnreliable );
- assert( pWal->readOnly & WAL_SHM_RDONLY );
- assert( pWal->nWiData>0 && pWal->apWiData[0] );
-
- /* Take WAL_READ_LOCK(0). This has the effect of preventing any
- ** writers from running a checkpoint, but does not stop them
- ** from running recovery. */
- rc = walLockShared(pWal, WAL_READ_LOCK(0));
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_BUSY ) rc = WAL_RETRY;
- goto begin_unreliable_shm_out;
- }
- pWal->readLock = 0;
-
- /* Check to see if a separate writer has attached to the shared-memory area,
- ** thus making the shared-memory "reliable" again. Do this by invoking
- ** the xShmMap() routine of the VFS and looking to see if the return
- ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT.
- **
- ** If the shared-memory is now "reliable" return WAL_RETRY, which will
- ** cause the heap-memory WAL-index to be discarded and the actual
- ** shared memory to be used in its place.
- **
- ** This step is important because, even though this connection is holding
- ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might
- ** have already checkpointed the WAL file and, while the current
- ** is active, wrap the WAL and start overwriting frames that this
- ** process wants to use.
- **
- ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has
- ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY
- ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations,
- ** even if some external agent does a "chmod" to make the shared-memory
- ** writable by us, until sqlite3OsShmUnmap() has been called.
- ** This is a requirement on the VFS implementation.
- */
- rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy);
- assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */
- if( rc!=SQLITE_READONLY_CANTINIT ){
- rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc);
- goto begin_unreliable_shm_out;
- }
-
- /* We reach this point only if the real shared-memory is still unreliable.
- ** Assume the in-memory WAL-index substitute is correct and load it
- ** into pWal->hdr.
- */
- memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr));
-
- /* Make sure some writer hasn't come in and changed the WAL file out
- ** from under us, then disconnected, while we were not looking.
- */
- rc = sqlite3OsFileSize(pWal->pWalFd, &szWal);
- if( rc!=SQLITE_OK ){
- goto begin_unreliable_shm_out;
- }
- if( szWal<WAL_HDRSIZE ){
- /* If the wal file is too small to contain a wal-header and the
- ** wal-index header has mxFrame==0, then it must be safe to proceed
- ** reading the database file only. However, the page cache cannot
- ** be trusted, as a read/write connection may have connected, written
- ** the db, run a checkpoint, truncated the wal file and disconnected
- ** since this client's last read transaction. */
- *pChanged = 1;
- rc = (pWal->hdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY);
- goto begin_unreliable_shm_out;
- }
-
- /* Check the salt keys at the start of the wal file still match. */
- rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
- if( rc!=SQLITE_OK ){
- goto begin_unreliable_shm_out;
- }
- if( memcmp(&pWal->hdr.aSalt, &aBuf[16], 8) ){
- /* Some writer has wrapped the WAL file while we were not looking.
- ** Return WAL_RETRY which will cause the in-memory WAL-index to be
- ** rebuilt. */
- rc = WAL_RETRY;
- goto begin_unreliable_shm_out;
- }
-
- /* Allocate a buffer to read frames into */
- szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE;
- aFrame = (u8 *)sqlite3_malloc64(szFrame);
- if( aFrame==0 ){
- rc = SQLITE_NOMEM_BKPT;
- goto begin_unreliable_shm_out;
- }
- aData = &aFrame[WAL_FRAME_HDRSIZE];
-
- /* Check to see if a complete transaction has been appended to the
- ** wal file since the heap-memory wal-index was created. If so, the
- ** heap-memory wal-index is discarded and WAL_RETRY returned to
- ** the caller. */
- aSaveCksum[0] = pWal->hdr.aFrameCksum[0];
- aSaveCksum[1] = pWal->hdr.aFrameCksum[1];
+**
+** If an error occurs, an SQLite error code is returned.
+*/
+static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
+ i64 szWal; /* Size of wal file on disk in bytes */
+ i64 iOffset; /* Current offset when reading wal file */
+ u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */
+ u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */
+ int szFrame; /* Number of bytes in buffer aFrame[] */
+ u8 *aData; /* Pointer to data part of aFrame buffer */
+ volatile void *pDummy; /* Dummy argument for xShmMap */
+ int rc; /* Return code */
+ u32 aSaveCksum[2]; /* Saved copy of pWal->hdr.aFrameCksum */
+
+ assert( pWal->bShmUnreliable );
+ assert( pWal->readOnly & WAL_SHM_RDONLY );
+ assert( pWal->nWiData>0 && pWal->apWiData[0] );
+
+ /* Take WAL_READ_LOCK(0). This has the effect of preventing any
+ ** writers from running a checkpoint, but does not stop them
+ ** from running recovery. */
+ rc = walLockShared(pWal, WAL_READ_LOCK(0));
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_BUSY ) rc = WAL_RETRY;
+ goto begin_unreliable_shm_out;
+ }
+ pWal->readLock = 0;
+
+ /* Check to see if a separate writer has attached to the shared-memory area,
+ ** thus making the shared-memory "reliable" again. Do this by invoking
+ ** the xShmMap() routine of the VFS and looking to see if the return
+ ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT.
+ **
+ ** If the shared-memory is now "reliable" return WAL_RETRY, which will
+ ** cause the heap-memory WAL-index to be discarded and the actual
+ ** shared memory to be used in its place.
+ **
+ ** This step is important because, even though this connection is holding
+ ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might
+ ** have already checkpointed the WAL file and, while the current
+ ** is active, wrap the WAL and start overwriting frames that this
+ ** process wants to use.
+ **
+ ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has
+ ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY
+ ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations,
+ ** even if some external agent does a "chmod" to make the shared-memory
+ ** writable by us, until sqlite3OsShmUnmap() has been called.
+ ** This is a requirement on the VFS implementation.
+ */
+ rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy);
+ assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */
+ if( rc!=SQLITE_READONLY_CANTINIT ){
+ rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc);
+ goto begin_unreliable_shm_out;
+ }
+
+ /* We reach this point only if the real shared-memory is still unreliable.
+ ** Assume the in-memory WAL-index substitute is correct and load it
+ ** into pWal->hdr.
+ */
+ memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr));
+
+ /* Make sure some writer hasn't come in and changed the WAL file out
+ ** from under us, then disconnected, while we were not looking.
+ */
+ rc = sqlite3OsFileSize(pWal->pWalFd, &szWal);
+ if( rc!=SQLITE_OK ){
+ goto begin_unreliable_shm_out;
+ }
+ if( szWal<WAL_HDRSIZE ){
+ /* If the wal file is too small to contain a wal-header and the
+ ** wal-index header has mxFrame==0, then it must be safe to proceed
+ ** reading the database file only. However, the page cache cannot
+ ** be trusted, as a read/write connection may have connected, written
+ ** the db, run a checkpoint, truncated the wal file and disconnected
+ ** since this client's last read transaction. */
+ *pChanged = 1;
+ rc = (pWal->hdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY);
+ goto begin_unreliable_shm_out;
+ }
+
+ /* Check the salt keys at the start of the wal file still match. */
+ rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
+ if( rc!=SQLITE_OK ){
+ goto begin_unreliable_shm_out;
+ }
+ if( memcmp(&pWal->hdr.aSalt, &aBuf[16], 8) ){
+ /* Some writer has wrapped the WAL file while we were not looking.
+ ** Return WAL_RETRY which will cause the in-memory WAL-index to be
+ ** rebuilt. */
+ rc = WAL_RETRY;
+ goto begin_unreliable_shm_out;
+ }
+
+ /* Allocate a buffer to read frames into */
+ szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE;
+ aFrame = (u8 *)sqlite3_malloc64(szFrame);
+ if( aFrame==0 ){
+ rc = SQLITE_NOMEM_BKPT;
+ goto begin_unreliable_shm_out;
+ }
+ aData = &aFrame[WAL_FRAME_HDRSIZE];
+
+ /* Check to see if a complete transaction has been appended to the
+ ** wal file since the heap-memory wal-index was created. If so, the
+ ** heap-memory wal-index is discarded and WAL_RETRY returned to
+ ** the caller. */
+ aSaveCksum[0] = pWal->hdr.aFrameCksum[0];
+ aSaveCksum[1] = pWal->hdr.aFrameCksum[1];
for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage);
iOffset+szFrame<=szWal;
- iOffset+=szFrame
- ){
- u32 pgno; /* Database page number for frame */
- u32 nTruncate; /* dbsize field from frame header */
-
- /* Read and decode the next log frame. */
- rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
- if( rc!=SQLITE_OK ) break;
- if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break;
-
- /* If nTruncate is non-zero, then a complete transaction has been
- ** appended to this wal file. Set rc to WAL_RETRY and break out of
- ** the loop. */
- if( nTruncate ){
- rc = WAL_RETRY;
- break;
- }
- }
- pWal->hdr.aFrameCksum[0] = aSaveCksum[0];
- pWal->hdr.aFrameCksum[1] = aSaveCksum[1];
-
- begin_unreliable_shm_out:
- sqlite3_free(aFrame);
- if( rc!=SQLITE_OK ){
- int i;
- for(i=0; i<pWal->nWiData; i++){
- sqlite3_free((void*)pWal->apWiData[i]);
- pWal->apWiData[i] = 0;
- }
- pWal->bShmUnreliable = 0;
- sqlite3WalEndReadTransaction(pWal);
- *pChanged = 1;
- }
- return rc;
-}
-
+ iOffset+=szFrame
+ ){
+ u32 pgno; /* Database page number for frame */
+ u32 nTruncate; /* dbsize field from frame header */
+
+ /* Read and decode the next log frame. */
+ rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
+ if( rc!=SQLITE_OK ) break;
+ if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break;
+
+ /* If nTruncate is non-zero, then a complete transaction has been
+ ** appended to this wal file. Set rc to WAL_RETRY and break out of
+ ** the loop. */
+ if( nTruncate ){
+ rc = WAL_RETRY;
+ break;
+ }
+ }
+ pWal->hdr.aFrameCksum[0] = aSaveCksum[0];
+ pWal->hdr.aFrameCksum[1] = aSaveCksum[1];
+
+ begin_unreliable_shm_out:
+ sqlite3_free(aFrame);
+ if( rc!=SQLITE_OK ){
+ int i;
+ for(i=0; i<pWal->nWiData; i++){
+ sqlite3_free((void*)pWal->apWiData[i]);
+ pWal->apWiData[i] = 0;
+ }
+ pWal->bShmUnreliable = 0;
+ sqlite3WalEndReadTransaction(pWal);
+ *pChanged = 1;
+ }
+ return rc;
+}
+
/*
** Attempt to start a read transaction. This might fail due to a race or
** other transient condition. When that happens, it returns WAL_RETRY to
@@ -63087,13 +63087,13 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
int mxI; /* Index of largest aReadMark[] value */
int i; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
- u32 mxFrame; /* Wal frame to lock to */
+ u32 mxFrame; /* Wal frame to lock to */
assert( pWal->readLock<0 ); /* Not currently locked */
- /* useWal may only be set for read/write connections */
- assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 );
-
+ /* useWal may only be set for read/write connections */
+ assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 );
+
/* Take steps to avoid spinning forever if there is a protocol error.
**
** Circumstances that cause a RETRY should only last for the briefest
@@ -63122,10 +63122,10 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
}
if( !useWal ){
- assert( rc==SQLITE_OK );
- if( pWal->bShmUnreliable==0 ){
- rc = walIndexReadHdr(pWal, pChanged);
- }
+ assert( rc==SQLITE_OK );
+ if( pWal->bShmUnreliable==0 ){
+ rc = walIndexReadHdr(pWal, pChanged);
+ }
if( rc==SQLITE_BUSY ){
/* If there is not a recovery running in another thread or process
** then convert BUSY errors to WAL_RETRY. If recovery is known to
@@ -63154,19 +63154,19 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
if( rc!=SQLITE_OK ){
return rc;
}
- else if( pWal->bShmUnreliable ){
- return walBeginShmUnreliable(pWal, pChanged);
- }
+ else if( pWal->bShmUnreliable ){
+ return walBeginShmUnreliable(pWal, pChanged);
+ }
}
- assert( pWal->nWiData>0 );
- assert( pWal->apWiData[0]!=0 );
+ assert( pWal->nWiData>0 );
+ assert( pWal->apWiData[0]!=0 );
pInfo = walCkptInfo(pWal);
if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame
-#ifdef SQLITE_ENABLE_SNAPSHOT
- && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
-#endif
- ){
+#ifdef SQLITE_ENABLE_SNAPSHOT
+ && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
+#endif
+ ){
/* The WAL has been completely backfilled (or it is empty).
** and can be safely ignored.
*/
@@ -63204,169 +63204,169 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
*/
mxReadMark = 0;
mxI = 0;
- mxFrame = pWal->hdr.mxFrame;
-#ifdef SQLITE_ENABLE_SNAPSHOT
- if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){
- mxFrame = pWal->pSnapshot->mxFrame;
- }
-#endif
+ mxFrame = pWal->hdr.mxFrame;
+#ifdef SQLITE_ENABLE_SNAPSHOT
+ if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){
+ mxFrame = pWal->pSnapshot->mxFrame;
+ }
+#endif
for(i=1; i<WAL_NREADER; i++){
u32 thisMark = AtomicLoad(pInfo->aReadMark+i);
- if( mxReadMark<=thisMark && thisMark<=mxFrame ){
+ if( mxReadMark<=thisMark && thisMark<=mxFrame ){
assert( thisMark!=READMARK_NOT_USED );
mxReadMark = thisMark;
mxI = i;
}
}
- if( (pWal->readOnly & WAL_SHM_RDONLY)==0
- && (mxReadMark<mxFrame || mxI==0)
- ){
- for(i=1; i<WAL_NREADER; i++){
- rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
- if( rc==SQLITE_OK ){
+ if( (pWal->readOnly & WAL_SHM_RDONLY)==0
+ && (mxReadMark<mxFrame || mxI==0)
+ ){
+ for(i=1; i<WAL_NREADER; i++){
+ rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
+ if( rc==SQLITE_OK ){
AtomicStore(pInfo->aReadMark+i,mxFrame);
mxReadMark = mxFrame;
- mxI = i;
- walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
- break;
- }else if( rc!=SQLITE_BUSY ){
- return rc;
- }
- }
- }
- if( mxI==0 ){
- assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
- return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT;
- }
-
- rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
- if( rc ){
- return rc==SQLITE_BUSY ? WAL_RETRY : rc;
- }
- /* Now that the read-lock has been obtained, check that neither the
- ** value in the aReadMark[] array or the contents of the wal-index
- ** header have changed.
- **
- ** It is necessary to check that the wal-index header did not change
- ** between the time it was read and when the shared-lock was obtained
- ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility
- ** that the log file may have been wrapped by a writer, or that frames
- ** that occur later in the log than pWal->hdr.mxFrame may have been
- ** copied into the database by a checkpointer. If either of these things
- ** happened, then reading the database with the current value of
- ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
- ** instead.
- **
- ** Before checking that the live wal-index header has not changed
- ** since it was read, set Wal.minFrame to the first frame in the wal
- ** file that has not yet been checkpointed. This client will not need
- ** to read any frames earlier than minFrame from the wal file - they
- ** can be safely read directly from the database file.
- **
+ mxI = i;
+ walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
+ break;
+ }else if( rc!=SQLITE_BUSY ){
+ return rc;
+ }
+ }
+ }
+ if( mxI==0 ){
+ assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
+ return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT;
+ }
+
+ rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
+ if( rc ){
+ return rc==SQLITE_BUSY ? WAL_RETRY : rc;
+ }
+ /* Now that the read-lock has been obtained, check that neither the
+ ** value in the aReadMark[] array or the contents of the wal-index
+ ** header have changed.
+ **
+ ** It is necessary to check that the wal-index header did not change
+ ** between the time it was read and when the shared-lock was obtained
+ ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility
+ ** that the log file may have been wrapped by a writer, or that frames
+ ** that occur later in the log than pWal->hdr.mxFrame may have been
+ ** copied into the database by a checkpointer. If either of these things
+ ** happened, then reading the database with the current value of
+ ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
+ ** instead.
+ **
+ ** Before checking that the live wal-index header has not changed
+ ** since it was read, set Wal.minFrame to the first frame in the wal
+ ** file that has not yet been checkpointed. This client will not need
+ ** to read any frames earlier than minFrame from the wal file - they
+ ** can be safely read directly from the database file.
+ **
** Because a ShmBarrier() call is made between taking the copy of
- ** nBackfill and checking that the wal-header in shared-memory still
+ ** nBackfill and checking that the wal-header in shared-memory still
** matches the one cached in pWal->hdr, it is guaranteed that the
- ** checkpointer that set nBackfill was not working with a wal-index
- ** header newer than that cached in pWal->hdr. If it were, that could
- ** cause a problem. The checkpointer could omit to checkpoint
- ** a version of page X that lies before pWal->minFrame (call that version
- ** A) on the basis that there is a newer version (version B) of the same
- ** page later in the wal file. But if version B happens to like past
- ** frame pWal->hdr.mxFrame - then the client would incorrectly assume
- ** that it can read version A from the database file. However, since
- ** we can guarantee that the checkpointer that set nBackfill could not
- ** see any pages past pWal->hdr.mxFrame, this problem does not come up.
- */
+ ** checkpointer that set nBackfill was not working with a wal-index
+ ** header newer than that cached in pWal->hdr. If it were, that could
+ ** cause a problem. The checkpointer could omit to checkpoint
+ ** a version of page X that lies before pWal->minFrame (call that version
+ ** A) on the basis that there is a newer version (version B) of the same
+ ** page later in the wal file. But if version B happens to like past
+ ** frame pWal->hdr.mxFrame - then the client would incorrectly assume
+ ** that it can read version A from the database file. However, since
+ ** we can guarantee that the checkpointer that set nBackfill could not
+ ** see any pages past pWal->hdr.mxFrame, this problem does not come up.
+ */
pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1;
- walShmBarrier(pWal);
+ walShmBarrier(pWal);
if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark
- || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
- ){
- walUnlockShared(pWal, WAL_READ_LOCK(mxI));
- return WAL_RETRY;
- }else{
- assert( mxReadMark<=pWal->hdr.mxFrame );
- pWal->readLock = (i16)mxI;
- }
- return rc;
-}
-
-#ifdef SQLITE_ENABLE_SNAPSHOT
-/*
+ || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
+ ){
+ walUnlockShared(pWal, WAL_READ_LOCK(mxI));
+ return WAL_RETRY;
+ }else{
+ assert( mxReadMark<=pWal->hdr.mxFrame );
+ pWal->readLock = (i16)mxI;
+ }
+ return rc;
+}
+
+#ifdef SQLITE_ENABLE_SNAPSHOT
+/*
** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted
-** variable so that older snapshots can be accessed. To do this, loop
+** variable so that older snapshots can be accessed. To do this, loop
** through all wal frames from nBackfillAttempted to (nBackfill+1),
-** comparing their content to the corresponding page with the database
-** file, if any. Set nBackfillAttempted to the frame number of the
-** first frame for which the wal file content matches the db file.
-**
+** comparing their content to the corresponding page with the database
+** file, if any. Set nBackfillAttempted to the frame number of the
+** first frame for which the wal file content matches the db file.
+**
** This is only really safe if the file-system is such that any page
** writes made by earlier checkpointers were atomic operations, which
-** is not always true. It is also possible that nBackfillAttempted
-** may be left set to a value larger than expected, if a wal frame
-** contains content that duplicate of an earlier version of the same
-** page.
-**
-** SQLITE_OK is returned if successful, or an SQLite error code if an
-** error occurs. It is not an error if nBackfillAttempted cannot be
-** decreased at all.
-*/
-SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){
- int rc;
-
- assert( pWal->readLock>=0 );
- rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
- if( rc==SQLITE_OK ){
- volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
- int szPage = (int)pWal->szPage;
- i64 szDb; /* Size of db file in bytes */
-
- rc = sqlite3OsFileSize(pWal->pDbFd, &szDb);
- if( rc==SQLITE_OK ){
- void *pBuf1 = sqlite3_malloc(szPage);
- void *pBuf2 = sqlite3_malloc(szPage);
- if( pBuf1==0 || pBuf2==0 ){
- rc = SQLITE_NOMEM;
- }else{
- u32 i = pInfo->nBackfillAttempted;
+** is not always true. It is also possible that nBackfillAttempted
+** may be left set to a value larger than expected, if a wal frame
+** contains content that duplicate of an earlier version of the same
+** page.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code if an
+** error occurs. It is not an error if nBackfillAttempted cannot be
+** decreased at all.
+*/
+SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){
+ int rc;
+
+ assert( pWal->readLock>=0 );
+ rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
+ if( rc==SQLITE_OK ){
+ volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
+ int szPage = (int)pWal->szPage;
+ i64 szDb; /* Size of db file in bytes */
+
+ rc = sqlite3OsFileSize(pWal->pDbFd, &szDb);
+ if( rc==SQLITE_OK ){
+ void *pBuf1 = sqlite3_malloc(szPage);
+ void *pBuf2 = sqlite3_malloc(szPage);
+ if( pBuf1==0 || pBuf2==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ u32 i = pInfo->nBackfillAttempted;
for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){
WalHashLoc sLoc; /* Hash table location */
- u32 pgno; /* Page number in db file */
- i64 iDbOff; /* Offset of db file entry */
- i64 iWalOff; /* Offset of wal file entry */
-
+ u32 pgno; /* Page number in db file */
+ i64 iDbOff; /* Offset of db file entry */
+ i64 iWalOff; /* Offset of wal file entry */
+
rc = walHashGet(pWal, walFramePage(i), &sLoc);
- if( rc!=SQLITE_OK ) break;
+ if( rc!=SQLITE_OK ) break;
assert( i - sLoc.iZero - 1 >=0 );
pgno = sLoc.aPgno[i-sLoc.iZero-1];
- iDbOff = (i64)(pgno-1) * szPage;
-
- if( iDbOff+szPage<=szDb ){
- iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
- rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
-
- if( rc==SQLITE_OK ){
- rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff);
- }
-
- if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){
- break;
- }
- }
-
- pInfo->nBackfillAttempted = i-1;
- }
- }
-
- sqlite3_free(pBuf1);
- sqlite3_free(pBuf2);
- }
- walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
- }
-
- return rc;
-}
-#endif /* SQLITE_ENABLE_SNAPSHOT */
+ iDbOff = (i64)(pgno-1) * szPage;
+
+ if( iDbOff+szPage<=szDb ){
+ iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
+ rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff);
+ }
+
+ if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){
+ break;
+ }
+ }
+
+ pInfo->nBackfillAttempted = i-1;
+ }
+ }
+
+ sqlite3_free(pBuf1);
+ sqlite3_free(pBuf2);
+ }
+ walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
+ }
+
+ return rc;
+}
+#endif /* SQLITE_ENABLE_SNAPSHOT */
/*
** Begin a read transaction on the database.
@@ -63385,9 +63385,9 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){
SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
int rc; /* Return code */
int cnt = 0; /* Number of TryBeginRead attempts */
-#ifdef SQLITE_ENABLE_SNAPSHOT
- int bChanged = 0;
- WalIndexHdr *pSnapshot = pWal->pSnapshot;
+#ifdef SQLITE_ENABLE_SNAPSHOT
+ int bChanged = 0;
+ WalIndexHdr *pSnapshot = pWal->pSnapshot;
#endif
assert( pWal->ckptLock==0 );
@@ -63414,9 +63414,9 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
return rc;
}
pWal->ckptLock = 1;
- }
-#endif
-
+ }
+#endif
+
do{
rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
}while( rc==WAL_RETRY );
@@ -63424,28 +63424,28 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
testcase( (rc&0xff)==SQLITE_IOERR );
testcase( rc==SQLITE_PROTOCOL );
testcase( rc==SQLITE_OK );
-
-#ifdef SQLITE_ENABLE_SNAPSHOT
- if( rc==SQLITE_OK ){
- if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
- /* At this point the client has a lock on an aReadMark[] slot holding
- ** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr
- ** is populated with the wal-index header corresponding to the head
- ** of the wal file. Verify that pSnapshot is still valid before
- ** continuing. Reasons why pSnapshot might no longer be valid:
- **
- ** (1) The WAL file has been reset since the snapshot was taken.
- ** In this case, the salt will have changed.
- **
- ** (2) A checkpoint as been attempted that wrote frames past
- ** pSnapshot->mxFrame into the database file. Note that the
- ** checkpoint need not have completed for this to cause problems.
- */
- volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
-
- assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
- assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
-
+
+#ifdef SQLITE_ENABLE_SNAPSHOT
+ if( rc==SQLITE_OK ){
+ if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
+ /* At this point the client has a lock on an aReadMark[] slot holding
+ ** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr
+ ** is populated with the wal-index header corresponding to the head
+ ** of the wal file. Verify that pSnapshot is still valid before
+ ** continuing. Reasons why pSnapshot might no longer be valid:
+ **
+ ** (1) The WAL file has been reset since the snapshot was taken.
+ ** In this case, the salt will have changed.
+ **
+ ** (2) A checkpoint as been attempted that wrote frames past
+ ** pSnapshot->mxFrame into the database file. Note that the
+ ** checkpoint need not have completed for this to cause problems.
+ */
+ volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
+
+ assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
+ assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
+
/* Check that the wal file has not been wrapped. Assuming that it has
** not, also check that no checkpointer has attempted to checkpoint any
** frames beyond pSnapshot->mxFrame. If either of these conditions are
@@ -63460,8 +63460,8 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
*pChanged = bChanged;
}else{
rc = SQLITE_ERROR_SNAPSHOT;
- }
-
+ }
+
/* A client using a non-current snapshot may not ignore any frames
** from the start of the wal file. This is because, for a system
** where (minFrame < iSnapshot < maxFrame), a checkpointer may
@@ -63469,12 +63469,12 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
** the file because there exists a frame after iSnapshot that
** is the same database page. */
pWal->minFrame = 1;
-
- if( rc!=SQLITE_OK ){
- sqlite3WalEndReadTransaction(pWal);
- }
- }
- }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3WalEndReadTransaction(pWal);
+ }
+ }
+ }
/* Release the shared CKPT lock obtained above. */
if( pWal->ckptLock ){
@@ -63482,7 +63482,7 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
walUnlockShared(pWal, WAL_CKPT_LOCK);
pWal->ckptLock = 0;
}
-#endif
+#endif
return rc;
}
@@ -63514,7 +63514,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
u32 iRead = 0; /* If !=0, WAL frame to return data from */
u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */
int iHash; /* Used to loop through N hash tables */
- int iMinHash;
+ int iMinHash;
/* This routine is only be called from within a read transaction. */
assert( pWal->readLock>=0 || pWal->lockError );
@@ -63525,7 +63525,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
** then the WAL is ignored by the reader so return early, as if the
** WAL were empty.
*/
- if( iLast==0 || (pWal->readLock==0 && pWal->bShmUnreliable==0) ){
+ if( iLast==0 || (pWal->readLock==0 && pWal->bShmUnreliable==0) ){
*piRead = 0;
return SQLITE_OK;
}
@@ -63555,7 +63555,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
** This condition filters out entries that were added to the hash
** table after the current read-transaction had started.
*/
- iMinHash = walFramePage(pWal->minFrame);
+ iMinHash = walFramePage(pWal->minFrame);
for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
WalHashLoc sLoc; /* Hash table location */
int iKey; /* Hash slot index */
@@ -63590,8 +63590,8 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
{
u32 iRead2 = 0;
u32 iTest;
- assert( pWal->bShmUnreliable || pWal->minFrame>0 );
- for(iTest=iLast; iTest>=pWal->minFrame && iTest>0; iTest--){
+ assert( pWal->bShmUnreliable || pWal->minFrame>0 );
+ for(iTest=iLast; iTest>=pWal->minFrame && iTest>0; iTest--){
if( walFramePgno(pWal, iTest)==pgno ){
iRead2 = iTest;
break;
@@ -63667,7 +63667,7 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
/* Cannot start a write transaction without first holding a read
** transaction. */
assert( pWal->readLock>=0 );
- assert( pWal->writeLock==0 && pWal->iReCksum==0 );
+ assert( pWal->writeLock==0 && pWal->iReCksum==0 );
if( pWal->readOnly ){
return SQLITE_READONLY;
@@ -63676,7 +63676,7 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
/* Only one writer allowed at a time. Get the write lock. Return
** SQLITE_BUSY if unable.
*/
- rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
+ rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
if( rc ){
return rc;
}
@@ -63703,7 +63703,7 @@ SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){
if( pWal->writeLock ){
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
pWal->writeLock = 0;
- pWal->iReCksum = 0;
+ pWal->iReCksum = 0;
pWal->truncateOnCommit = 0;
}
return SQLITE_OK;
@@ -63822,7 +63822,7 @@ static int walRestartLog(Wal *pWal){
if( pInfo->nBackfill>0 ){
u32 salt1;
sqlite3_randomness(4, &salt1);
- rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
+ rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
if( rc==SQLITE_OK ){
/* If all readers are using WAL_READ_LOCK(0) (in other words if no
** readers are currently using the WAL), then the transactions
@@ -63889,8 +63889,8 @@ static int walWriteToLog(
iOffset += iFirstAmt;
iAmt -= iFirstAmt;
pContent = (void*)(iFirstAmt + (char*)pContent);
- assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 );
- rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags));
+ assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 );
+ rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags));
if( iAmt==0 || rc ) return rc;
}
rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
@@ -63918,59 +63918,59 @@ static int walWriteOneFrame(
return rc;
}
-/*
-** This function is called as part of committing a transaction within which
-** one or more frames have been overwritten. It updates the checksums for
-** all frames written to the wal file by the current transaction starting
-** with the earliest to have been overwritten.
-**
-** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
-*/
-static int walRewriteChecksums(Wal *pWal, u32 iLast){
- const int szPage = pWal->szPage;/* Database page size */
- int rc = SQLITE_OK; /* Return code */
- u8 *aBuf; /* Buffer to load data from wal file into */
- u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-headers in */
- u32 iRead; /* Next frame to read from wal file */
- i64 iCksumOff;
-
- aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
- if( aBuf==0 ) return SQLITE_NOMEM_BKPT;
-
- /* Find the checksum values to use as input for the recalculating the
- ** first checksum. If the first frame is frame 1 (implying that the current
- ** transaction restarted the wal file), these values must be read from the
- ** wal-file header. Otherwise, read them from the frame header of the
- ** previous frame. */
- assert( pWal->iReCksum>0 );
- if( pWal->iReCksum==1 ){
- iCksumOff = 24;
- }else{
- iCksumOff = walFrameOffset(pWal->iReCksum-1, szPage) + 16;
- }
- rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff);
- pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf);
- pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]);
-
- iRead = pWal->iReCksum;
- pWal->iReCksum = 0;
- for(; rc==SQLITE_OK && iRead<=iLast; iRead++){
- i64 iOff = walFrameOffset(iRead, szPage);
- rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff);
- if( rc==SQLITE_OK ){
- u32 iPgno, nDbSize;
- iPgno = sqlite3Get4byte(aBuf);
- nDbSize = sqlite3Get4byte(&aBuf[4]);
-
- walEncodeFrame(pWal, iPgno, nDbSize, &aBuf[WAL_FRAME_HDRSIZE], aFrame);
- rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOff);
- }
- }
-
- sqlite3_free(aBuf);
- return rc;
-}
-
+/*
+** This function is called as part of committing a transaction within which
+** one or more frames have been overwritten. It updates the checksums for
+** all frames written to the wal file by the current transaction starting
+** with the earliest to have been overwritten.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+static int walRewriteChecksums(Wal *pWal, u32 iLast){
+ const int szPage = pWal->szPage;/* Database page size */
+ int rc = SQLITE_OK; /* Return code */
+ u8 *aBuf; /* Buffer to load data from wal file into */
+ u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-headers in */
+ u32 iRead; /* Next frame to read from wal file */
+ i64 iCksumOff;
+
+ aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
+ if( aBuf==0 ) return SQLITE_NOMEM_BKPT;
+
+ /* Find the checksum values to use as input for the recalculating the
+ ** first checksum. If the first frame is frame 1 (implying that the current
+ ** transaction restarted the wal file), these values must be read from the
+ ** wal-file header. Otherwise, read them from the frame header of the
+ ** previous frame. */
+ assert( pWal->iReCksum>0 );
+ if( pWal->iReCksum==1 ){
+ iCksumOff = 24;
+ }else{
+ iCksumOff = walFrameOffset(pWal->iReCksum-1, szPage) + 16;
+ }
+ rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff);
+ pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf);
+ pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]);
+
+ iRead = pWal->iReCksum;
+ pWal->iReCksum = 0;
+ for(; rc==SQLITE_OK && iRead<=iLast; iRead++){
+ i64 iOff = walFrameOffset(iRead, szPage);
+ rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff);
+ if( rc==SQLITE_OK ){
+ u32 iPgno, nDbSize;
+ iPgno = sqlite3Get4byte(aBuf);
+ nDbSize = sqlite3Get4byte(&aBuf[4]);
+
+ walEncodeFrame(pWal, iPgno, nDbSize, &aBuf[WAL_FRAME_HDRSIZE], aFrame);
+ rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOff);
+ }
+ }
+
+ sqlite3_free(aBuf);
+ return rc;
+}
+
/*
** Write a set of frames to the log. The caller must hold the write-lock
** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
@@ -63991,8 +63991,8 @@ SQLITE_PRIVATE int sqlite3WalFrames(
int szFrame; /* The size of a single frame */
i64 iOffset; /* Next byte to write in WAL file */
WalWriter w; /* The writer */
- u32 iFirst = 0; /* First frame that may be overwritten */
- WalIndexHdr *pLive; /* Pointer to shared header */
+ u32 iFirst = 0; /* First frame that may be overwritten */
+ WalIndexHdr *pLive; /* Pointer to shared header */
assert( pList );
assert( pWal->writeLock );
@@ -64008,11 +64008,11 @@ SQLITE_PRIVATE int sqlite3WalFrames(
}
#endif
- pLive = (WalIndexHdr*)walIndexHdr(pWal);
- if( memcmp(&pWal->hdr, (void *)pLive, sizeof(WalIndexHdr))!=0 ){
- iFirst = pLive->mxFrame+1;
- }
-
+ pLive = (WalIndexHdr*)walIndexHdr(pWal);
+ if( memcmp(&pWal->hdr, (void *)pLive, sizeof(WalIndexHdr))!=0 ){
+ iFirst = pLive->mxFrame+1;
+ }
+
/* See if it is possible to write these frames into the start of the
** log file, instead of appending to it at pWal->hdr.mxFrame.
*/
@@ -64056,10 +64056,10 @@ SQLITE_PRIVATE int sqlite3WalFrames(
** an out-of-order write following a WAL restart could result in
** database corruption. See the ticket:
**
- ** https://sqlite.org/src/info/ff5be73dee
+ ** https://sqlite.org/src/info/ff5be73dee
*/
- if( pWal->syncHeader ){
- rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags));
+ if( pWal->syncHeader ){
+ rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags));
if( rc ) return rc;
}
}
@@ -64077,29 +64077,29 @@ SQLITE_PRIVATE int sqlite3WalFrames(
/* Write all frames into the log file exactly once */
for(p=pList; p; p=p->pDirty){
int nDbSize; /* 0 normally. Positive == commit flag */
-
- /* Check if this page has already been written into the wal file by
- ** the current transaction. If so, overwrite the existing frame and
+
+ /* Check if this page has already been written into the wal file by
+ ** the current transaction. If so, overwrite the existing frame and
** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that
- ** checksums must be recomputed when the transaction is committed. */
- if( iFirst && (p->pDirty || isCommit==0) ){
- u32 iWrite = 0;
- VVA_ONLY(rc =) sqlite3WalFindFrame(pWal, p->pgno, &iWrite);
- assert( rc==SQLITE_OK || iWrite==0 );
- if( iWrite>=iFirst ){
- i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE;
- void *pData;
- if( pWal->iReCksum==0 || iWrite<pWal->iReCksum ){
- pWal->iReCksum = iWrite;
- }
- pData = p->pData;
- rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff);
- if( rc ) return rc;
- p->flags &= ~PGHDR_WAL_APPEND;
- continue;
- }
- }
-
+ ** checksums must be recomputed when the transaction is committed. */
+ if( iFirst && (p->pDirty || isCommit==0) ){
+ u32 iWrite = 0;
+ VVA_ONLY(rc =) sqlite3WalFindFrame(pWal, p->pgno, &iWrite);
+ assert( rc==SQLITE_OK || iWrite==0 );
+ if( iWrite>=iFirst ){
+ i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE;
+ void *pData;
+ if( pWal->iReCksum==0 || iWrite<pWal->iReCksum ){
+ pWal->iReCksum = iWrite;
+ }
+ pData = p->pData;
+ rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff);
+ if( rc ) return rc;
+ p->flags &= ~PGHDR_WAL_APPEND;
+ continue;
+ }
+ }
+
iFrame++;
assert( iOffset==walFrameOffset(iFrame, szPage) );
nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
@@ -64107,15 +64107,15 @@ SQLITE_PRIVATE int sqlite3WalFrames(
if( rc ) return rc;
pLast = p;
iOffset += szFrame;
- p->flags |= PGHDR_WAL_APPEND;
+ p->flags |= PGHDR_WAL_APPEND;
+ }
+
+ /* Recalculate checksums within the wal file if required. */
+ if( isCommit && pWal->iReCksum ){
+ rc = walRewriteChecksums(pWal, iFrame);
+ if( rc ) return rc;
}
- /* Recalculate checksums within the wal file if required. */
- if( isCommit && pWal->iReCksum ){
- rc = walRewriteChecksums(pWal, iFrame);
- if( rc ) return rc;
- }
-
/* If this is the end of a transaction, then we might need to pad
** the transaction and/or sync the WAL file.
**
@@ -64130,13 +64130,13 @@ SQLITE_PRIVATE int sqlite3WalFrames(
** sector boundary is synced; the part of the last frame that extends
** past the sector boundary is written after the sync.
*/
- if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){
- int bSync = 1;
+ if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){
+ int bSync = 1;
if( pWal->padToSectorBoundary ){
int sectorSize = sqlite3SectorSize(pWal->pWalFd);
w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
- bSync = (w.iSyncPoint==iOffset);
- testcase( bSync );
+ bSync = (w.iSyncPoint==iOffset);
+ testcase( bSync );
while( iOffset<w.iSyncPoint ){
rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
if( rc ) return rc;
@@ -64145,10 +64145,10 @@ SQLITE_PRIVATE int sqlite3WalFrames(
assert( pLast!=0 );
}
}
- if( bSync ){
- assert( rc==SQLITE_OK );
- rc = sqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags));
- }
+ if( bSync ){
+ assert( rc==SQLITE_OK );
+ rc = sqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags));
+ }
}
/* If this frame set completes the first transaction in the WAL and
@@ -64171,7 +64171,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(
*/
iFrame = pWal->hdr.mxFrame;
for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
- if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue;
+ if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue;
iFrame++;
rc = walIndexAppend(pWal, iFrame, p->pgno);
}
@@ -64215,7 +64215,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(
*/
SQLITE_PRIVATE int sqlite3WalCheckpoint(
Wal *pWal, /* Wal connection */
- sqlite3 *db, /* Check this handle's interrupt flag */
+ sqlite3 *db, /* Check this handle's interrupt flag */
int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */
int (*xBusy)(void*), /* Function to call when busy */
void *pBusyArg, /* Context argument for xBusyHandler */
@@ -64253,7 +64253,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
** it will not be invoked in this case.
*/
- rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
+ rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
testcase( rc==SQLITE_BUSY );
testcase( rc!=SQLITE_OK && xBusy2!=0 );
if( rc==SQLITE_OK ){
@@ -64293,11 +64293,11 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
/* Copy data from the log to the database file. */
if( rc==SQLITE_OK ){
-
+
if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
rc = SQLITE_CORRUPT_BKPT;
}else{
- rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
+ rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
}
/* If no error occurred, set the output variables. */
@@ -64386,24 +64386,24 @@ SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){
assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) );
if( op==0 ){
- if( pWal->exclusiveMode!=WAL_NORMAL_MODE ){
- pWal->exclusiveMode = WAL_NORMAL_MODE;
+ if( pWal->exclusiveMode!=WAL_NORMAL_MODE ){
+ pWal->exclusiveMode = WAL_NORMAL_MODE;
if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){
- pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
+ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
}
- rc = pWal->exclusiveMode==WAL_NORMAL_MODE;
+ rc = pWal->exclusiveMode==WAL_NORMAL_MODE;
}else{
/* Already in locking_mode=NORMAL */
rc = 0;
}
}else if( op>0 ){
- assert( pWal->exclusiveMode==WAL_NORMAL_MODE );
+ assert( pWal->exclusiveMode==WAL_NORMAL_MODE );
assert( pWal->readLock>=0 );
walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
- pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
+ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
rc = 1;
}else{
- rc = pWal->exclusiveMode==WAL_NORMAL_MODE;
+ rc = pWal->exclusiveMode==WAL_NORMAL_MODE;
}
return rc;
}
@@ -64417,58 +64417,58 @@ SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){
return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
}
-#ifdef SQLITE_ENABLE_SNAPSHOT
-/* Create a snapshot object. The content of a snapshot is opaque to
-** every other subsystem, so the WAL module can put whatever it needs
-** in the object.
-*/
-SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
- int rc = SQLITE_OK;
- WalIndexHdr *pRet;
- static const u32 aZero[4] = { 0, 0, 0, 0 };
-
- assert( pWal->readLock>=0 && pWal->writeLock==0 );
-
- if( memcmp(&pWal->hdr.aFrameCksum[0],aZero,16)==0 ){
- *ppSnapshot = 0;
- return SQLITE_ERROR;
- }
- pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr));
- if( pRet==0 ){
- rc = SQLITE_NOMEM_BKPT;
- }else{
- memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr));
- *ppSnapshot = (sqlite3_snapshot*)pRet;
- }
-
- return rc;
-}
-
-/* Try to open on pSnapshot when the next read-transaction starts
-*/
+#ifdef SQLITE_ENABLE_SNAPSHOT
+/* Create a snapshot object. The content of a snapshot is opaque to
+** every other subsystem, so the WAL module can put whatever it needs
+** in the object.
+*/
+SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
+ int rc = SQLITE_OK;
+ WalIndexHdr *pRet;
+ static const u32 aZero[4] = { 0, 0, 0, 0 };
+
+ assert( pWal->readLock>=0 && pWal->writeLock==0 );
+
+ if( memcmp(&pWal->hdr.aFrameCksum[0],aZero,16)==0 ){
+ *ppSnapshot = 0;
+ return SQLITE_ERROR;
+ }
+ pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr));
+ if( pRet==0 ){
+ rc = SQLITE_NOMEM_BKPT;
+ }else{
+ memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr));
+ *ppSnapshot = (sqlite3_snapshot*)pRet;
+ }
+
+ return rc;
+}
+
+/* Try to open on pSnapshot when the next read-transaction starts
+*/
SQLITE_PRIVATE void sqlite3WalSnapshotOpen(
Wal *pWal,
sqlite3_snapshot *pSnapshot
){
- pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
-}
-
-/*
-** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
-** p1 is older than p2 and zero if p1 and p2 are the same snapshot.
-*/
-SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){
- WalIndexHdr *pHdr1 = (WalIndexHdr*)p1;
- WalIndexHdr *pHdr2 = (WalIndexHdr*)p2;
-
- /* aSalt[0] is a copy of the value stored in the wal file header. It
- ** is incremented each time the wal file is restarted. */
- if( pHdr1->aSalt[0]<pHdr2->aSalt[0] ) return -1;
- if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1;
- if( pHdr1->mxFrame<pHdr2->mxFrame ) return -1;
- if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1;
- return 0;
-}
+ pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
+}
+
+/*
+** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
+** p1 is older than p2 and zero if p1 and p2 are the same snapshot.
+*/
+SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){
+ WalIndexHdr *pHdr1 = (WalIndexHdr*)p1;
+ WalIndexHdr *pHdr2 = (WalIndexHdr*)p2;
+
+ /* aSalt[0] is a copy of the value stored in the wal file header. It
+ ** is incremented each time the wal file is restarted. */
+ if( pHdr1->aSalt[0]<pHdr2->aSalt[0] ) return -1;
+ if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1;
+ if( pHdr1->mxFrame<pHdr2->mxFrame ) return -1;
+ if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1;
+ return 0;
+}
/*
** The caller currently has a read transaction open on the database.
@@ -64506,8 +64506,8 @@ SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal){
}
-#endif /* SQLITE_ENABLE_SNAPSHOT */
-
+#endif /* SQLITE_ENABLE_SNAPSHOT */
+
#ifdef SQLITE_ENABLE_ZIPVFS
/*
** If the argument is not NULL, it points to a Wal object that holds a
@@ -64520,12 +64520,12 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
}
#endif
-/* Return the sqlite3_file object for the WAL file
-*/
-SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){
- return pWal->pWalFd;
-}
-
+/* Return the sqlite3_file object for the WAL file
+*/
+SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){
+ return pWal->pWalFd;
+}
+
#endif /* #ifndef SQLITE_OMIT_WAL */
/************** End of wal.c *************************************************/
@@ -64810,13 +64810,13 @@ typedef struct CellInfo CellInfo;
#define PTF_LEAF 0x08
/*
-** An instance of this object stores information about each a single database
-** page that has been loaded into memory. The information in this object
-** is derived from the raw on-disk page content.
+** An instance of this object stores information about each a single database
+** page that has been loaded into memory. The information in this object
+** is derived from the raw on-disk page content.
**
-** As each database page is loaded into memory, the pager allocats an
-** instance of this object and zeros the first 8 bytes. (This is the
-** "extra" information associated with each page of the pager.)
+** As each database page is loaded into memory, the pager allocats an
+** instance of this object and zeros the first 8 bytes. (This is the
+** "extra" information associated with each page of the pager.)
**
** Access to all fields of this structure is controlled by the mutex
** stored in MemPage.pBt->mutex.
@@ -64825,23 +64825,23 @@ struct MemPage {
u8 isInit; /* True if previously initialized. MUST BE FIRST! */
u8 intKey; /* True if table b-trees. False for index b-trees */
u8 intKeyLeaf; /* True if the leaf of an intKey table */
- Pgno pgno; /* Page number for this page */
- /* Only the first 8 bytes (above) are zeroed by pager.c when a new page
- ** is allocated. All fields that follow must be initialized before use */
+ Pgno pgno; /* Page number for this page */
+ /* Only the first 8 bytes (above) are zeroed by pager.c when a new page
+ ** is allocated. All fields that follow must be initialized before use */
u8 leaf; /* True if a leaf page */
u8 hdrOffset; /* 100 for page 1. 0 otherwise */
u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
u8 max1bytePayload; /* min(maxLocal,127) */
- u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
+ u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */
u16 cellOffset; /* Index in aData of first cell pointer */
int nFree; /* Number of free bytes on the page. -1 for unknown */
u16 nCell; /* Number of cells on this page, local and ovfl */
u16 maskPage; /* Mask for page offset */
- u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th
+ u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th
** non-overflow cell */
- u8 *apOvfl[4]; /* Pointers to the body of overflow cells */
+ u8 *apOvfl[4]; /* Pointers to the body of overflow cells */
BtShared *pBt; /* Pointer to BtShared that this page is part of */
u8 *aData; /* Pointer to disk image of the page data */
u8 *aDataEnd; /* One byte past the end of usable data */
@@ -65014,12 +65014,12 @@ struct BtShared {
#define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */
#define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */
#define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */
-#define BTS_OVERWRITE 0x0008 /* Overwrite deleted content with zeros */
-#define BTS_FAST_SECURE 0x000c /* Combination of the previous two */
-#define BTS_INITIALLY_EMPTY 0x0010 /* Database was empty at trans start */
-#define BTS_NO_WAL 0x0020 /* Do not open write-ahead-log files */
-#define BTS_EXCLUSIVE 0x0040 /* pWriter has an exclusive lock */
-#define BTS_PENDING 0x0080 /* Waiting for read-locks to clear */
+#define BTS_OVERWRITE 0x0008 /* Overwrite deleted content with zeros */
+#define BTS_FAST_SECURE 0x000c /* Combination of the previous two */
+#define BTS_INITIALLY_EMPTY 0x0010 /* Database was empty at trans start */
+#define BTS_NO_WAL 0x0020 /* Do not open write-ahead-log files */
+#define BTS_EXCLUSIVE 0x0040 /* pWriter has an exclusive lock */
+#define BTS_PENDING 0x0080 /* Waiting for read-locks to clear */
/*
** An instance of the following structure is used to hold information
@@ -65072,10 +65072,10 @@ struct CellInfo {
** FAULT skipNext holds the cursor fault error code.
*/
struct BtCursor {
- u8 eState; /* One of the CURSOR_XXX constants (see below) */
- u8 curFlags; /* zero or more BTCF_* flags defined below */
- u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */
- u8 hints; /* As configured by CursorSetHints() */
+ u8 eState; /* One of the CURSOR_XXX constants (see below) */
+ u8 curFlags; /* zero or more BTCF_* flags defined below */
+ u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */
+ u8 hints; /* As configured by CursorSetHints() */
int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
** Error code if eState==CURSOR_FAULT */
Btree *pBtree; /* The Btree to which this cursor belongs */
@@ -65092,11 +65092,11 @@ struct BtCursor {
Pgno pgnoRoot; /* The root page of this tree */
i8 iPage; /* Index of current page in apPage */
u8 curIntKey; /* Value of apPage[0]->intKey */
- u16 ix; /* Current index for apPage[iPage] */
- u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */
- struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */
- MemPage *pPage; /* Current page */
- MemPage *apPage[BTCURSOR_MAX_DEPTH-1]; /* Stack of parents of current page */
+ u16 ix; /* Current index for apPage[iPage] */
+ u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */
+ struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */
+ MemPage *pPage; /* Current page */
+ MemPage *apPage[BTCURSOR_MAX_DEPTH-1]; /* Stack of parents of current page */
};
/*
@@ -65273,7 +65273,7 @@ struct IntegrityCk {
# define get2byteAligned(x) (*(u16*)(x))
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000
# define get2byteAligned(x) __builtin_bswap16(*(u16*)(x))
-#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
# define get2byteAligned(x) _byteswap_ushort(*(u16*)(x))
#else
# define get2byteAligned(x) ((x)[0]<<8 | (x)[1])
@@ -65448,24 +65448,24 @@ SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){
** two or more btrees in common both try to lock all their btrees
** at the same instant.
*/
-static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){
+static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){
int i;
- int skipOk = 1;
+ int skipOk = 1;
Btree *p;
assert( sqlite3_mutex_held(db->mutex) );
for(i=0; i<db->nDb; i++){
p = db->aDb[i].pBt;
- if( p && p->sharable ){
- sqlite3BtreeEnter(p);
- skipOk = 0;
- }
+ if( p && p->sharable ){
+ sqlite3BtreeEnter(p);
+ skipOk = 0;
+ }
}
db->noSharedCache = skipOk;
}
-SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
+SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
if( db->noSharedCache==0 ) btreeEnterAll(db);
-}
-static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){
+}
+static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){
int i;
Btree *p;
assert( sqlite3_mutex_held(db->mutex) );
@@ -65474,7 +65474,7 @@ static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){
if( p ) sqlite3BtreeLeave(p);
}
}
-SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
+SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
if( db->noSharedCache==0 ) btreeLeaveAll(db);
}
@@ -65551,25 +65551,25 @@ SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
}
}
#endif /* if SQLITE_THREADSAFE */
-
-#ifndef SQLITE_OMIT_INCRBLOB
-/*
+
+#ifndef SQLITE_OMIT_INCRBLOB
+/*
** Enter a mutex on a Btree given a cursor owned by that Btree.
-**
+**
** These entry points are used by incremental I/O only. Enter() is required
** any time OMIT_SHARED_CACHE is not defined, regardless of whether or not
-** the build is threadsafe. Leave() is only required by threadsafe builds.
-*/
-SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor *pCur){
- sqlite3BtreeEnter(pCur->pBtree);
-}
-# if SQLITE_THREADSAFE
-SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){
- sqlite3BtreeLeave(pCur->pBtree);
-}
-# endif
-#endif /* ifndef SQLITE_OMIT_INCRBLOB */
-
+** the build is threadsafe. Leave() is only required by threadsafe builds.
+*/
+SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor *pCur){
+ sqlite3BtreeEnter(pCur->pBtree);
+}
+# if SQLITE_THREADSAFE
+SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){
+ sqlite3BtreeLeave(pCur->pBtree);
+}
+# endif
+#endif /* ifndef SQLITE_OMIT_INCRBLOB */
+
#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */
/************** End of btmutex.c *********************************************/
@@ -65662,7 +65662,7 @@ static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
** The shared cache setting effects only future calls to
** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
*/
-SQLITE_API int sqlite3_enable_shared_cache(int enable){
+SQLITE_API int sqlite3_enable_shared_cache(int enable){
sqlite3GlobalConfig.sharedCacheEnabled = enable;
return SQLITE_OK;
}
@@ -65689,7 +65689,7 @@ SQLITE_API int sqlite3_enable_shared_cache(int enable){
#endif
#ifdef SQLITE_DEBUG
-/*
+/*
** Return and reset the seek counter for a Btree object.
*/
SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){
@@ -65700,33 +65700,33 @@ SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){
#endif
/*
-** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single
-** (MemPage*) as an argument. The (MemPage*) must not be NULL.
-**
-** If SQLITE_DEBUG is not defined, then this macro is equivalent to
-** SQLITE_CORRUPT_BKPT. Or, if SQLITE_DEBUG is set, then the log message
-** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented
-** with the page number and filename associated with the (MemPage*).
-*/
-#ifdef SQLITE_DEBUG
-int corruptPageError(int lineno, MemPage *p){
- char *zMsg;
- sqlite3BeginBenignMalloc();
- zMsg = sqlite3_mprintf("database corruption page %d of %s",
- (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
- );
- sqlite3EndBenignMalloc();
- if( zMsg ){
- sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
- }
- sqlite3_free(zMsg);
- return SQLITE_CORRUPT_BKPT;
-}
-# define SQLITE_CORRUPT_PAGE(pMemPage) corruptPageError(__LINE__, pMemPage)
-#else
-# define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno)
-#endif
-
+** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single
+** (MemPage*) as an argument. The (MemPage*) must not be NULL.
+**
+** If SQLITE_DEBUG is not defined, then this macro is equivalent to
+** SQLITE_CORRUPT_BKPT. Or, if SQLITE_DEBUG is set, then the log message
+** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented
+** with the page number and filename associated with the (MemPage*).
+*/
+#ifdef SQLITE_DEBUG
+int corruptPageError(int lineno, MemPage *p){
+ char *zMsg;
+ sqlite3BeginBenignMalloc();
+ zMsg = sqlite3_mprintf("database corruption page %d of %s",
+ (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
+ );
+ sqlite3EndBenignMalloc();
+ if( zMsg ){
+ sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
+ }
+ sqlite3_free(zMsg);
+ return SQLITE_CORRUPT_BKPT;
+}
+# define SQLITE_CORRUPT_PAGE(pMemPage) corruptPageError(__LINE__, pMemPage)
+#else
+# define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno)
+#endif
+
#ifndef SQLITE_OMIT_SHARED_CACHE
#ifdef SQLITE_DEBUG
@@ -65767,7 +65767,7 @@ static int hasSharedCacheTableLock(
** Return true immediately.
*/
if( (pBtree->sharable==0)
- || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommit))
+ || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommit))
){
return 1;
}
@@ -65846,7 +65846,7 @@ static int hasReadConflicts(Btree *pBtree, Pgno iRoot){
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
if( p->pgnoRoot==iRoot
&& p->pBtree!=pBtree
- && 0==(p->pBtree->db->flags & SQLITE_ReadUncommit)
+ && 0==(p->pBtree->db->flags & SQLITE_ReadUncommit)
){
return 1;
}
@@ -65868,7 +65868,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){
assert( sqlite3BtreeHoldsMutex(p) );
assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
assert( p->db!=0 );
- assert( !(p->db->flags&SQLITE_ReadUncommit)||eLock==WRITE_LOCK||iTab==1 );
+ assert( !(p->db->flags&SQLITE_ReadUncommit)||eLock==WRITE_LOCK||iTab==1 );
/* If requesting a write-lock, then the Btree must have an open write
** transaction on this file. And, obviously, for this to be so there
@@ -65946,7 +65946,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
** obtain a read-lock using this function. The only read-lock obtained
** by a connection in read-uncommitted mode is on the sqlite_schema
** table, and that lock is obtained in BtreeBeginTrans(). */
- assert( 0==(p->db->flags&SQLITE_ReadUncommit) || eLock==WRITE_LOCK );
+ assert( 0==(p->db->flags&SQLITE_ReadUncommit) || eLock==WRITE_LOCK );
/* This function should only be called on a sharable b-tree after it
** has been determined that no other b-tree holds a conflicting lock. */
@@ -65967,7 +65967,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
if( !pLock ){
pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock));
if( !pLock ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
pLock->iTable = iTable;
pLock->pBtree = p;
@@ -66056,9 +66056,9 @@ static void downgradeAllSharedCacheTableLocks(Btree *p){
#endif /* SQLITE_OMIT_SHARED_CACHE */
-static void releasePage(MemPage *pPage); /* Forward reference */
-static void releasePageOne(MemPage *pPage); /* Forward reference */
-static void releasePageNotNull(MemPage *pPage); /* Forward reference */
+static void releasePage(MemPage *pPage); /* Forward reference */
+static void releasePageOne(MemPage *pPage); /* Forward reference */
+static void releasePageNotNull(MemPage *pPage); /* Forward reference */
/*
***** This routine is used inside of assert() only ****
@@ -66069,19 +66069,19 @@ static void releasePageNotNull(MemPage *pPage); /* Forward reference */
static int cursorHoldsMutex(BtCursor *p){
return sqlite3_mutex_held(p->pBt->mutex);
}
-
-/* Verify that the cursor and the BtShared agree about what is the current
+
+/* Verify that the cursor and the BtShared agree about what is the current
** database connetion. This is important in shared-cache mode. If the database
-** connection pointers get out-of-sync, it is possible for routines like
-** btreeInitPage() to reference an stale connection pointer that references a
-** a connection that has already closed. This routine is used inside assert()
-** statements only and for the purpose of double-checking that the btree code
-** does keep the database connection pointers up-to-date.
-*/
-static int cursorOwnsBtShared(BtCursor *p){
- assert( cursorHoldsMutex(p) );
- return (p->pBtree->db==p->pBt->db);
-}
+** connection pointers get out-of-sync, it is possible for routines like
+** btreeInitPage() to reference an stale connection pointer that references a
+** a connection that has already closed. This routine is used inside assert()
+** statements only and for the purpose of double-checking that the btree code
+** does keep the database connection pointers up-to-date.
+*/
+static int cursorOwnsBtShared(BtCursor *p){
+ assert( cursorHoldsMutex(p) );
+ return (p->pBtree->db==p->pBt->db);
+}
#endif
/*
@@ -66118,7 +66118,7 @@ static void invalidateAllOverflowCache(BtShared *pBt){
*/
static void invalidateIncrblobCursors(
Btree *pBtree, /* The database file to check */
- Pgno pgnoRoot, /* The table that might be changing */
+ Pgno pgnoRoot, /* The table that might be changing */
i64 iRow, /* The rowid that might be changing */
int isClearTable /* True if all rows are being deleted */
){
@@ -66129,7 +66129,7 @@ static void invalidateIncrblobCursors(
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
if( (p->curFlags & BTCF_Incrblob)!=0 ){
pBtree->hasIncrblobCur = 1;
- if( p->pgnoRoot==pgnoRoot && (isClearTable || p->info.nKey==iRow) ){
+ if( p->pgnoRoot==pgnoRoot && (isClearTable || p->info.nKey==iRow) ){
p->eState = CURSOR_INVALID;
}
}
@@ -66138,7 +66138,7 @@ static void invalidateIncrblobCursors(
#else
/* Stub function when INCRBLOB is omitted */
- #define invalidateIncrblobCursors(w,x,y,z)
+ #define invalidateIncrblobCursors(w,x,y,z)
#endif /* SQLITE_OMIT_INCRBLOB */
/*
@@ -66182,7 +66182,7 @@ static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
assert( pgno<=pBt->nPage );
pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage);
if( !pBt->pHasContent ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
}
if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){
@@ -66217,63 +66217,63 @@ static void btreeClearHasContent(BtShared *pBt){
*/
static void btreeReleaseAllCursorPages(BtCursor *pCur){
int i;
- if( pCur->iPage>=0 ){
- for(i=0; i<pCur->iPage; i++){
- releasePageNotNull(pCur->apPage[i]);
- }
- releasePageNotNull(pCur->pPage);
- pCur->iPage = -1;
+ if( pCur->iPage>=0 ){
+ for(i=0; i<pCur->iPage; i++){
+ releasePageNotNull(pCur->apPage[i]);
+ }
+ releasePageNotNull(pCur->pPage);
+ pCur->iPage = -1;
}
}
-/*
-** The cursor passed as the only argument must point to a valid entry
-** when this function is called (i.e. have eState==CURSOR_VALID). This
-** function saves the current cursor key in variables pCur->nKey and
+/*
+** The cursor passed as the only argument must point to a valid entry
+** when this function is called (i.e. have eState==CURSOR_VALID). This
+** function saves the current cursor key in variables pCur->nKey and
** pCur->pKey. SQLITE_OK is returned if successful or an SQLite error
-** code otherwise.
-**
-** If the cursor is open on an intkey table, then the integer key
-** (the rowid) is stored in pCur->nKey and pCur->pKey is left set to
+** code otherwise.
+**
+** If the cursor is open on an intkey table, then the integer key
+** (the rowid) is stored in pCur->nKey and pCur->pKey is left set to
** NULL. If the cursor is open on a non-intkey table, then pCur->pKey is
** set to point to a malloced buffer pCur->nKey bytes in size containing
-** the key.
-*/
-static int saveCursorKey(BtCursor *pCur){
- int rc = SQLITE_OK;
- assert( CURSOR_VALID==pCur->eState );
- assert( 0==pCur->pKey );
- assert( cursorHoldsMutex(pCur) );
-
- if( pCur->curIntKey ){
- /* Only the rowid is required for a table btree */
- pCur->nKey = sqlite3BtreeIntegerKey(pCur);
- }else{
+** the key.
+*/
+static int saveCursorKey(BtCursor *pCur){
+ int rc = SQLITE_OK;
+ assert( CURSOR_VALID==pCur->eState );
+ assert( 0==pCur->pKey );
+ assert( cursorHoldsMutex(pCur) );
+
+ if( pCur->curIntKey ){
+ /* Only the rowid is required for a table btree */
+ pCur->nKey = sqlite3BtreeIntegerKey(pCur);
+ }else{
/* For an index btree, save the complete key content. It is possible
** that the current key is corrupt. In that case, it is possible that
** the sqlite3VdbeRecordUnpack() function may overread the buffer by
** up to the size of 1 varint plus 1 8-byte value when the cursor
** position is restored. Hence the 17 bytes of padding allocated
** below. */
- void *pKey;
- pCur->nKey = sqlite3BtreePayloadSize(pCur);
+ void *pKey;
+ pCur->nKey = sqlite3BtreePayloadSize(pCur);
pKey = sqlite3Malloc( pCur->nKey + 9 + 8 );
- if( pKey ){
- rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey);
- if( rc==SQLITE_OK ){
+ if( pKey ){
+ rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey);
+ if( rc==SQLITE_OK ){
memset(((u8*)pKey)+pCur->nKey, 0, 9+8);
- pCur->pKey = pKey;
- }else{
- sqlite3_free(pKey);
- }
- }else{
- rc = SQLITE_NOMEM_BKPT;
- }
- }
- assert( !pCur->curIntKey || !pCur->pKey );
- return rc;
-}
-
+ pCur->pKey = pKey;
+ }else{
+ sqlite3_free(pKey);
+ }
+ }else{
+ rc = SQLITE_NOMEM_BKPT;
+ }
+ }
+ assert( !pCur->curIntKey || !pCur->pKey );
+ return rc;
+}
+
/*
** Save the current cursor position in the variables BtCursor.nKey
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
@@ -66297,13 +66297,13 @@ static int saveCursorPosition(BtCursor *pCur){
pCur->skipNext = 0;
}
- rc = saveCursorKey(pCur);
+ rc = saveCursorKey(pCur);
if( rc==SQLITE_OK ){
btreeReleaseAllCursorPages(pCur);
pCur->eState = CURSOR_REQUIRESEEK;
}
- pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl|BTCF_AtLast);
+ pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl|BTCF_AtLast);
return rc;
}
@@ -66361,7 +66361,7 @@ static int SQLITE_NOINLINE saveCursorsOnList(
return rc;
}
}else{
- testcase( p->iPage>=0 );
+ testcase( p->iPage>=0 );
btreeReleaseAllCursorPages(p);
}
}
@@ -66399,10 +66399,10 @@ static int btreeMoveto(
KeyInfo *pKeyInfo = pCur->pKeyInfo;
assert( nKey==(i64)(int)nKey );
pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
- if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
+ if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey);
if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){
- rc = SQLITE_CORRUPT_BKPT;
+ rc = SQLITE_CORRUPT_BKPT;
}else{
rc = sqlite3BtreeIndexMoveto(pCur, pIdxKey, pRes);
}
@@ -66424,7 +66424,7 @@ static int btreeMoveto(
static int btreeRestoreCursorPosition(BtCursor *pCur){
int rc;
int skipNext = 0;
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState>=CURSOR_REQUIRESEEK );
if( pCur->eState==CURSOR_FAULT ){
return pCur->skipNext;
@@ -66473,17 +66473,17 @@ SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
}
/*
-** Return a pointer to a fake BtCursor object that will always answer
-** false to the sqlite3BtreeCursorHasMoved() routine above. The fake
-** cursor returned must not be used with any other Btree interface.
-*/
-SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void){
- static u8 fakeCursor = CURSOR_VALID;
- assert( offsetof(BtCursor, eState)==0 );
- return (BtCursor*)&fakeCursor;
-}
-
-/*
+** Return a pointer to a fake BtCursor object that will always answer
+** false to the sqlite3BtreeCursorHasMoved() routine above. The fake
+** cursor returned must not be used with any other Btree interface.
+*/
+SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void){
+ static u8 fakeCursor = CURSOR_VALID;
+ assert( offsetof(BtCursor, eState)==0 );
+ return (BtCursor*)&fakeCursor;
+}
+
+/*
** This routine restores a cursor back to its original position after it
** has been moved by some outside activity (such as a btree rebalance or
** a row having been deleted out from under the cursor).
@@ -66514,26 +66514,26 @@ SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow)
return SQLITE_OK;
}
-#ifdef SQLITE_ENABLE_CURSOR_HINTS
-/*
-** Provide hints to the cursor. The particular hint given (and the type
-** and number of the varargs parameters) is determined by the eHintType
-** parameter. See the definitions of the BTREE_HINT_* macros for details.
-*/
-SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){
- /* Used only by system that substitute their own storage engine */
-}
-#endif
-
-/*
-** Provide flag hints to the cursor.
-*/
-SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){
- assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 );
- pCur->hints = x;
-}
-
-
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+/*
+** Provide hints to the cursor. The particular hint given (and the type
+** and number of the varargs parameters) is determined by the eHintType
+** parameter. See the definitions of the BTREE_HINT_* macros for details.
+*/
+SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){
+ /* Used only by system that substitute their own storage engine */
+}
+#endif
+
+/*
+** Provide flag hints to the cursor.
+*/
+SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){
+ assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 );
+ pCur->hints = x;
+}
+
+
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Given a page number of a regular database page, return the page
@@ -66587,7 +66587,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
return;
}
iPtrmap = PTRMAP_PAGENO(pBt, key);
- rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
+ rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
if( rc!=SQLITE_OK ){
*pRC = rc;
return;
@@ -66637,7 +66637,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
assert( sqlite3_mutex_held(pBt->mutex) );
iPtrmap = PTRMAP_PAGENO(pBt, key);
- rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
+ rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
if( rc!=0 ){
return rc;
}
@@ -66654,7 +66654,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
sqlite3PagerUnref(pDbPage);
- if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_PGNO(iPtrmap);
+ if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_PGNO(iPtrmap);
return SQLITE_OK;
}
@@ -66714,7 +66714,7 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow(
}else{
pInfo->nLocal = (u16)minLocal;
}
- pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4;
+ pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4;
}
/*
@@ -66982,7 +66982,7 @@ static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
if( *pRC ) return;
assert( pCell!=0 );
pPage->xParseCell(pPage, pCell, &info);
- if( info.nLocal<info.nPayload ){
+ if( info.nLocal<info.nPayload ){
Pgno ovfl;
if( SQLITE_WITHIN(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){
testcase( pSrc!=pPage );
@@ -66997,18 +66997,18 @@ static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
/*
-** Defragment the page given. This routine reorganizes cells within the
-** page so that there are no free-blocks on the free-block list.
+** Defragment the page given. This routine reorganizes cells within the
+** page so that there are no free-blocks on the free-block list.
+**
+** Parameter nMaxFrag is the maximum amount of fragmented space that may be
+** present in the page after this routine returns.
**
-** Parameter nMaxFrag is the maximum amount of fragmented space that may be
-** present in the page after this routine returns.
-**
** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
** b-tree page so that there are no freeblocks or fragment bytes, all
** unused bytes are contained in the unallocated space region, and all
** cells are packed tightly at the end of the page.
*/
-static int defragmentPage(MemPage *pPage, int nMaxFrag){
+static int defragmentPage(MemPage *pPage, int nMaxFrag){
int i; /* Loop counter */
int pc; /* Address of the i-th cell */
int hdr; /* Offset to the page header */
@@ -67035,52 +67035,52 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
cellOffset = pPage->cellOffset;
nCell = pPage->nCell;
assert( nCell==get2byte(&data[hdr+3]) || CORRUPT_DB );
- iCellFirst = cellOffset + 2*nCell;
+ iCellFirst = cellOffset + 2*nCell;
usableSize = pPage->pBt->usableSize;
-
- /* This block handles pages with two or fewer free blocks and nMaxFrag
- ** or fewer fragmented bytes. In this case it is faster to move the
- ** two (or one) blocks of cells using memmove() and add the required
+
+ /* This block handles pages with two or fewer free blocks and nMaxFrag
+ ** or fewer fragmented bytes. In this case it is faster to move the
+ ** two (or one) blocks of cells using memmove() and add the required
** offsets to each pointer in the cell-pointer array than it is to
- ** reconstruct the entire page. */
- if( (int)data[hdr+7]<=nMaxFrag ){
- int iFree = get2byte(&data[hdr+1]);
+ ** reconstruct the entire page. */
+ if( (int)data[hdr+7]<=nMaxFrag ){
+ int iFree = get2byte(&data[hdr+1]);
if( iFree>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
- if( iFree ){
- int iFree2 = get2byte(&data[iFree]);
+ if( iFree ){
+ int iFree2 = get2byte(&data[iFree]);
if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
- if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
- u8 *pEnd = &data[cellOffset + nCell*2];
- u8 *pAddr;
- int sz2 = 0;
- int sz = get2byte(&data[iFree+2]);
- int top = get2byte(&data[hdr+5]);
- if( top>=iFree ){
- return SQLITE_CORRUPT_PAGE(pPage);
- }
- if( iFree2 ){
+ if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
+ u8 *pEnd = &data[cellOffset + nCell*2];
+ u8 *pAddr;
+ int sz2 = 0;
+ int sz = get2byte(&data[iFree+2]);
+ int top = get2byte(&data[hdr+5]);
+ if( top>=iFree ){
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
+ if( iFree2 ){
if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
- sz2 = get2byte(&data[iFree2+2]);
+ sz2 = get2byte(&data[iFree2+2]);
if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
- memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
- sz += sz2;
+ memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
+ sz += sz2;
}else if( NEVER(iFree+sz>usableSize) ){
return SQLITE_CORRUPT_PAGE(pPage);
- }
-
- cbrk = top+sz;
- assert( cbrk+(iFree-top) <= usableSize );
- memmove(&data[cbrk], &data[top], iFree-top);
- for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){
- pc = get2byte(pAddr);
- if( pc<iFree ){ put2byte(pAddr, pc+sz); }
- else if( pc<iFree2 ){ put2byte(pAddr, pc+sz2); }
- }
- goto defragment_out;
- }
- }
- }
-
+ }
+
+ cbrk = top+sz;
+ assert( cbrk+(iFree-top) <= usableSize );
+ memmove(&data[cbrk], &data[top], iFree-top);
+ for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){
+ pc = get2byte(pAddr);
+ if( pc<iFree ){ put2byte(pAddr, pc+sz); }
+ else if( pc<iFree2 ){ put2byte(pAddr, pc+sz2); }
+ }
+ goto defragment_out;
+ }
+ }
+ }
+
cbrk = usableSize;
iCellLast = usableSize - 4;
iCellStart = get2byte(&data[hdr+5]);
@@ -67094,13 +67094,13 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
** if PRAGMA cell_size_check=ON.
*/
if( pc<iCellStart || pc>iCellLast ){
- return SQLITE_CORRUPT_PAGE(pPage);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
assert( pc>=iCellStart && pc<=iCellLast );
size = pPage->xCellSize(pPage, &src[pc]);
cbrk -= size;
if( cbrk<iCellStart || pc+size>usableSize ){
- return SQLITE_CORRUPT_PAGE(pPage);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
assert( cbrk+size<=usableSize && cbrk>=iCellStart );
testcase( cbrk+size==usableSize );
@@ -67114,13 +67114,13 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
}
memcpy(&data[cbrk], &src[pc], size);
}
- data[hdr+7] = 0;
-
- defragment_out:
+ data[hdr+7] = 0;
+
+ defragment_out:
assert( pPage->nFree>=0 );
- if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
- return SQLITE_CORRUPT_PAGE(pPage);
- }
+ if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
assert( cbrk>=iCellFirst );
put2byte(&data[hdr+5], cbrk);
data[hdr+1] = 0;
@@ -67191,11 +67191,11 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
}
return 0;
}
- }
+ }
if( pc>maxPC+nByte-4 ){
/* The free slot chain extends off the end of the page */
- *pRc = SQLITE_CORRUPT_PAGE(pPg);
- }
+ *pRc = SQLITE_CORRUPT_PAGE(pPg);
+ }
return 0;
}
@@ -67241,7 +67241,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
if( top==0 && pPage->pBt->usableSize==65536 ){
top = 65536;
}else{
- return SQLITE_CORRUPT_PAGE(pPage);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
}
@@ -67275,10 +67275,10 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
if( gap+2+nByte>top ){
assert( pPage->nCell>0 || CORRUPT_DB );
assert( pPage->nFree>=0 );
- rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte)));
+ rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte)));
if( rc ) return rc;
top = get2byteNotZero(&data[hdr+5]);
- assert( gap+2+nByte<=top );
+ assert( gap+2+nByte<=top );
}
@@ -67314,7 +67314,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
u8 hdr; /* Page header size. 0 or 100 */
u8 nFrag = 0; /* Reduction in fragmentation */
u16 iOrigSize = iSize; /* Original value of iSize */
- u16 x; /* Offset to cell content area */
+ u16 x; /* Offset to cell content area */
u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
unsigned char *data = pPage->aData; /* Page content */
@@ -67324,7 +67324,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
assert( iSize>=4 ); /* Minimum cell size is 4 */
- assert( iStart<=pPage->pBt->usableSize-4 );
+ assert( iStart<=pPage->pBt->usableSize-4 );
/* The list of freeblocks must be in ascending order. Find the
** spot on the list where iStart should be inserted.
@@ -67334,16 +67334,16 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
if( data[iPtr+1]==0 && data[iPtr]==0 ){
iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */
}else{
- while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){
- if( iFreeBlk<iPtr+4 ){
+ while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){
+ if( iFreeBlk<iPtr+4 ){
if( iFreeBlk==0 ) break; /* TH3: corrupt082.100 */
- return SQLITE_CORRUPT_PAGE(pPage);
- }
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
iPtr = iFreeBlk;
}
if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */
- return SQLITE_CORRUPT_PAGE(pPage);
- }
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
assert( iFreeBlk>iPtr || iFreeBlk==0 );
/* At this point:
@@ -67354,11 +67354,11 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
*/
if( iFreeBlk && iEnd+3>=iFreeBlk ){
nFrag = iFreeBlk - iEnd;
- if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage);
+ if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage);
iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
- if( iEnd > pPage->pBt->usableSize ){
- return SQLITE_CORRUPT_PAGE(pPage);
- }
+ if( iEnd > pPage->pBt->usableSize ){
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
iSize = iEnd - iStart;
iFreeBlk = get2byte(&data[iFreeBlk]);
}
@@ -67370,17 +67370,17 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
if( iPtr>hdr+1 ){
int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
if( iPtrEnd+3>=iStart ){
- if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PAGE(pPage);
+ if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PAGE(pPage);
nFrag += iStart - iPtrEnd;
iSize = iEnd - iPtr;
iStart = iPtr;
}
}
- if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
+ if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
data[hdr+7] -= nFrag;
}
- x = get2byte(&data[hdr+5]);
- if( iStart<=x ){
+ x = get2byte(&data[hdr+5]);
+ if( iStart<=x ){
/* The new freeblock is at the beginning of the cell content area,
** so just extend the cell content area rather than create another
** freelist entry */
@@ -67392,13 +67392,13 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
/* Insert the new freeblock into the freelist */
put2byte(&data[iPtr], iStart);
}
- if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
- /* Overwrite deleted information with zeros when the secure_delete
- ** option is enabled */
- memset(&data[iStart], 0, iSize);
- }
- put2byte(&data[iStart], iFreeBlk);
- put2byte(&data[iStart+2], iSize);
+ if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
+ /* Overwrite deleted information with zeros when the secure_delete
+ ** option is enabled */
+ memset(&data[iStart], 0, iSize);
+ }
+ put2byte(&data[iStart], iFreeBlk);
+ put2byte(&data[iStart+2], iSize);
pPage->nFree += iOrigSize;
return SQLITE_OK;
}
@@ -67426,11 +67426,11 @@ static int decodeFlags(MemPage *pPage, int flagByte){
pPage->xCellSize = cellSizePtr;
pBt = pPage->pBt;
if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
- /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
- ** interior table b-tree page. */
+ /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
+ ** interior table b-tree page. */
assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
- /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a
- ** leaf table b-tree page. */
+ /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a
+ ** leaf table b-tree page. */
assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
pPage->intKey = 1;
if( pPage->leaf ){
@@ -67444,11 +67444,11 @@ static int decodeFlags(MemPage *pPage, int flagByte){
pPage->maxLocal = pBt->maxLeaf;
pPage->minLocal = pBt->minLeaf;
}else if( flagByte==PTF_ZERODATA ){
- /* EVIDENCE-OF: R-43316-37308 A value of 2 (0x02) means the page is an
- ** interior index b-tree page. */
+ /* EVIDENCE-OF: R-43316-37308 A value of 2 (0x02) means the page is an
+ ** interior index b-tree page. */
assert( (PTF_ZERODATA)==2 );
- /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a
- ** leaf index b-tree page. */
+ /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a
+ ** leaf index b-tree page. */
assert( (PTF_ZERODATA|PTF_LEAF)==10 );
pPage->intKey = 0;
pPage->intKeyLeaf = 0;
@@ -67458,7 +67458,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){
}else{
/* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
** an error. */
- return SQLITE_CORRUPT_PAGE(pPage);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
pPage->max1bytePayload = pBt->max1bytePayload;
return SQLITE_OK;
@@ -67469,14 +67469,14 @@ static int decodeFlags(MemPage *pPage, int flagByte){
** in the pPage->nFree field.
*/
static int btreeComputeFreeSpace(MemPage *pPage){
- int pc; /* Address of a freeblock within pPage->aData[] */
- u8 hdr; /* Offset to beginning of page header */
- u8 *data; /* Equal to pPage->aData */
- int usableSize; /* Amount of usable space on each page */
- int nFree; /* Number of unused bytes on the page */
- int top; /* First byte of the cell content area */
- int iCellFirst; /* First allowable cell or freeblock offset */
- int iCellLast; /* Last possible cell or freeblock offset */
+ int pc; /* Address of a freeblock within pPage->aData[] */
+ u8 hdr; /* Offset to beginning of page header */
+ u8 *data; /* Equal to pPage->aData */
+ int usableSize; /* Amount of usable space on each page */
+ int nFree; /* Number of unused bytes on the page */
+ int top; /* First byte of the cell content area */
+ int iCellFirst; /* First allowable cell or freeblock offset */
+ int iCellLast; /* Last possible cell or freeblock offset */
assert( pPage->pBt!=0 );
assert( pPage->pBt->db!=0 );
@@ -67488,61 +67488,61 @@ static int btreeComputeFreeSpace(MemPage *pPage){
assert( pPage->nFree<0 );
usableSize = pPage->pBt->usableSize;
- hdr = pPage->hdrOffset;
- data = pPage->aData;
- /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
- ** the start of the cell content area. A zero value for this integer is
- ** interpreted as 65536. */
- top = get2byteNotZero(&data[hdr+5]);
+ hdr = pPage->hdrOffset;
+ data = pPage->aData;
+ /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
+ ** the start of the cell content area. A zero value for this integer is
+ ** interpreted as 65536. */
+ top = get2byteNotZero(&data[hdr+5]);
iCellFirst = hdr + 8 + pPage->childPtrSize + 2*pPage->nCell;
- iCellLast = usableSize - 4;
-
- /* Compute the total free space on the page
- ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
- ** start of the first freeblock on the page, or is zero if there are no
- ** freeblocks. */
- pc = get2byte(&data[hdr+1]);
- nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */
- if( pc>0 ){
- u32 next, size;
+ iCellLast = usableSize - 4;
+
+ /* Compute the total free space on the page
+ ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
+ ** start of the first freeblock on the page, or is zero if there are no
+ ** freeblocks. */
+ pc = get2byte(&data[hdr+1]);
+ nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */
+ if( pc>0 ){
+ u32 next, size;
if( pc<top ){
- /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
- ** always be at least one cell before the first freeblock.
- */
+ /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
+ ** always be at least one cell before the first freeblock.
+ */
return SQLITE_CORRUPT_PAGE(pPage);
- }
- while( 1 ){
- if( pc>iCellLast ){
- /* Freeblock off the end of the page */
- return SQLITE_CORRUPT_PAGE(pPage);
+ }
+ while( 1 ){
+ if( pc>iCellLast ){
+ /* Freeblock off the end of the page */
+ return SQLITE_CORRUPT_PAGE(pPage);
}
next = get2byte(&data[pc]);
size = get2byte(&data[pc+2]);
nFree = nFree + size;
- if( next<=pc+size+3 ) break;
+ if( next<=pc+size+3 ) break;
pc = next;
}
- if( next>0 ){
- /* Freeblock not in ascending order */
- return SQLITE_CORRUPT_PAGE(pPage);
- }
- if( pc+size>(unsigned int)usableSize ){
- /* Last freeblock extends past page end */
- return SQLITE_CORRUPT_PAGE(pPage);
- }
- }
-
- /* At this point, nFree contains the sum of the offset to the start
- ** of the cell-content area plus the number of free bytes within
- ** the cell-content area. If this is greater than the usable-size
- ** of the page, then the page must be corrupted. This check also
- ** serves to verify that the offset to the start of the cell-content
- ** area, according to the page header, lies within the page.
- */
+ if( next>0 ){
+ /* Freeblock not in ascending order */
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
+ if( pc+size>(unsigned int)usableSize ){
+ /* Last freeblock extends past page end */
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
+ }
+
+ /* At this point, nFree contains the sum of the offset to the start
+ ** of the cell-content area plus the number of free bytes within
+ ** the cell-content area. If this is greater than the usable-size
+ ** of the page, then the page must be corrupted. This check also
+ ** serves to verify that the offset to the start of the cell-content
+ ** area, according to the page header, lies within the page.
+ */
if( nFree>usableSize || nFree<iCellFirst ){
- return SQLITE_CORRUPT_PAGE(pPage);
- }
- pPage->nFree = (u16)(nFree - iCellFirst);
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
+ pPage->nFree = (u16)(nFree - iCellFirst);
return SQLITE_OK;
}
@@ -67633,7 +67633,7 @@ static int btreeInitPage(MemPage *pPage){
|| get2byteNotZero(&data[5])==(int)pBt->usableSize
|| CORRUPT_DB );
pPage->nFree = -1; /* Indicate that this value is yet uncomputed */
- pPage->isInit = 1;
+ pPage->isInit = 1;
if( pBt->db->flags & SQLITE_CellSizeCk ){
return btreeCellSizeCheck(pPage);
}
@@ -67655,7 +67655,7 @@ static void zeroPage(MemPage *pPage, int flags){
assert( sqlite3PagerGetData(pPage->pDbPage) == data );
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( sqlite3_mutex_held(pBt->mutex) );
- if( pBt->btsFlags & BTS_FAST_SECURE ){
+ if( pBt->btsFlags & BTS_FAST_SECURE ){
memset(&data[hdr], 0, pBt->usableSize - hdr);
}
data[hdr] = (char)flags;
@@ -67683,14 +67683,14 @@ static void zeroPage(MemPage *pPage, int flags){
*/
static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){
MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
- if( pgno!=pPage->pgno ){
- pPage->aData = sqlite3PagerGetData(pDbPage);
- pPage->pDbPage = pDbPage;
- pPage->pBt = pBt;
- pPage->pgno = pgno;
- pPage->hdrOffset = pgno==1 ? 100 : 0;
- }
- assert( pPage->aData==sqlite3PagerGetData(pDbPage) );
+ if( pgno!=pPage->pgno ){
+ pPage->aData = sqlite3PagerGetData(pDbPage);
+ pPage->pDbPage = pDbPage;
+ pPage->pBt = pBt;
+ pPage->pgno = pgno;
+ pPage->hdrOffset = pgno==1 ? 100 : 0;
+ }
+ assert( pPage->aData==sqlite3PagerGetData(pDbPage) );
return pPage;
}
@@ -67716,7 +67716,7 @@ static int btreeGetPage(
assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY );
assert( sqlite3_mutex_held(pBt->mutex) );
- rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
+ rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
if( rc ) return rc;
*ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
return SQLITE_OK;
@@ -67772,7 +67772,7 @@ static int getAndInitPage(
int rc;
DbPage *pDbPage;
assert( sqlite3_mutex_held(pBt->mutex) );
- assert( pCur==0 || ppPage==&pCur->pPage );
+ assert( pCur==0 || ppPage==&pCur->pPage );
assert( pCur==0 || bReadOnly==pCur->curPagerFlags );
assert( pCur==0 || pCur->iPage>0 );
@@ -67780,25 +67780,25 @@ static int getAndInitPage(
rc = SQLITE_CORRUPT_BKPT;
goto getAndInitPage_error1;
}
- rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly);
+ rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly);
if( rc ){
goto getAndInitPage_error1;
}
- *ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
+ *ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
if( (*ppPage)->isInit==0 ){
- btreePageFromDbPage(pDbPage, pgno, pBt);
+ btreePageFromDbPage(pDbPage, pgno, pBt);
rc = btreeInitPage(*ppPage);
if( rc!=SQLITE_OK ){
goto getAndInitPage_error2;
}
}
- assert( (*ppPage)->pgno==pgno );
- assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
+ assert( (*ppPage)->pgno==pgno );
+ assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
/* If obtaining a child page for a cursor, we must verify that the page is
** compatible with the root page. */
- if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
- rc = SQLITE_CORRUPT_PGNO(pgno);
+ if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
+ rc = SQLITE_CORRUPT_PGNO(pgno);
goto getAndInitPage_error2;
}
return SQLITE_OK;
@@ -67806,10 +67806,10 @@ static int getAndInitPage(
getAndInitPage_error2:
releasePage(*ppPage);
getAndInitPage_error1:
- if( pCur ){
- pCur->iPage--;
- pCur->pPage = pCur->apPage[pCur->iPage];
- }
+ if( pCur ){
+ pCur->iPage--;
+ pCur->pPage = pCur->apPage[pCur->iPage];
+ }
testcase( pgno==0 );
assert( pgno!=0 || rc==SQLITE_CORRUPT );
return rc;
@@ -67818,8 +67818,8 @@ getAndInitPage_error1:
/*
** Release a MemPage. This should be called once for each prior
** call to btreeGetPage.
-**
-** Page1 is a special case and must be released using releasePageOne().
+**
+** Page1 is a special case and must be released using releasePageOne().
*/
static void releasePageNotNull(MemPage *pPage){
assert( pPage->aData );
@@ -67833,16 +67833,16 @@ static void releasePageNotNull(MemPage *pPage){
static void releasePage(MemPage *pPage){
if( pPage ) releasePageNotNull(pPage);
}
-static void releasePageOne(MemPage *pPage){
- assert( pPage!=0 );
- assert( pPage->aData );
- assert( pPage->pBt );
- assert( pPage->pDbPage!=0 );
- assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
- assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- sqlite3PagerUnrefPageOne(pPage->pDbPage);
-}
+static void releasePageOne(MemPage *pPage){
+ assert( pPage!=0 );
+ assert( pPage->aData );
+ assert( pPage->pBt );
+ assert( pPage->pDbPage!=0 );
+ assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
+ assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
+ assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+ sqlite3PagerUnrefPageOne(pPage->pDbPage);
+}
/*
** Get an unused page.
@@ -67980,7 +67980,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
}
p = sqlite3MallocZero(sizeof(Btree));
if( !p ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
p->inTrans = TRANS_NONE;
p->db = db;
@@ -68004,7 +68004,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
p->sharable = 1;
if( !zFullPathname ){
sqlite3_free(p);
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
if( isMemdb ){
memcpy(zFullPathname, zFilename, nFilename);
@@ -68076,11 +68076,11 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
pBt = sqlite3MallocZero( sizeof(*pBt) );
if( pBt==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto btree_open_out;
}
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
- sizeof(MemPage), flags, vfsFlags, pageReinit);
+ sizeof(MemPage), flags, vfsFlags, pageReinit);
if( rc==SQLITE_OK ){
sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap);
rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
@@ -68096,10 +68096,10 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
pBt->pCursor = 0;
pBt->pPage1 = 0;
if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY;
-#if defined(SQLITE_SECURE_DELETE)
+#if defined(SQLITE_SECURE_DELETE)
pBt->btsFlags |= BTS_SECURE_DELETE;
-#elif defined(SQLITE_FAST_SECURE_DELETE)
- pBt->btsFlags |= BTS_OVERWRITE;
+#elif defined(SQLITE_FAST_SECURE_DELETE)
+ pBt->btsFlags |= BTS_OVERWRITE;
#endif
/* EVIDENCE-OF: R-51873-39618 The page size for a database file is
** determined by the 2-byte integer located at an offset of 16 bytes from
@@ -68140,14 +68140,14 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
/* Add the new BtShared object to the linked list sharable BtShareds.
*/
- pBt->nRef = 1;
+ pBt->nRef = 1;
if( p->sharable ){
MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);)
if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
if( pBt->mutex==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto btree_open_out;
}
}
@@ -68170,12 +68170,12 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
for(i=0; i<db->nDb; i++){
if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){
while( pSib->pPrev ){ pSib = pSib->pPrev; }
- if( (uptr)p->pBt<(uptr)pSib->pBt ){
+ if( (uptr)p->pBt<(uptr)pSib->pBt ){
p->pNext = pSib;
p->pPrev = 0;
pSib->pPrev = p;
}else{
- while( pSib->pNext && (uptr)pSib->pNext->pBt<(uptr)p->pBt ){
+ while( pSib->pNext && (uptr)pSib->pNext->pBt<(uptr)p->pBt ){
pSib = pSib->pNext;
}
p->pNext = pSib->pNext;
@@ -68195,14 +68195,14 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
btree_open_out:
if( rc!=SQLITE_OK ){
if( pBt && pBt->pPager ){
- sqlite3PagerClose(pBt->pPager, 0);
+ sqlite3PagerClose(pBt->pPager, 0);
}
sqlite3_free(pBt);
sqlite3_free(p);
*ppBtree = 0;
}else{
- sqlite3_file *pFile;
-
+ sqlite3_file *pFile;
+
/* If the B-Tree was successfully opened, set the pager-cache size to the
** default value. Except, when opening on an existing shared pager-cache,
** do not change the pager-cache size.
@@ -68210,17 +68210,17 @@ btree_open_out:
if( sqlite3BtreeSchema(p, 0, 0)==0 ){
sqlite3BtreeSetCacheSize(p, SQLITE_DEFAULT_CACHE_SIZE);
}
-
- pFile = sqlite3PagerFile(pBt->pPager);
- if( pFile->pMethods ){
- sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db);
- }
+
+ pFile = sqlite3PagerFile(pBt->pPager);
+ if( pFile->pMethods ){
+ sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db);
+ }
}
if( mutexOpen ){
assert( sqlite3_mutex_held(mutexOpen) );
sqlite3_mutex_leave(mutexOpen);
}
- assert( rc!=SQLITE_OK || sqlite3BtreeConnectionCount(*ppBtree)>0 );
+ assert( rc!=SQLITE_OK || sqlite3BtreeConnectionCount(*ppBtree)>0 );
return rc;
}
@@ -68348,7 +68348,7 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
** Clean out and delete the BtShared object.
*/
assert( !pBt->pCursor );
- sqlite3PagerClose(pBt->pPager, p->db);
+ sqlite3PagerClose(pBt->pPager, p->db);
if( pBt->xFreeSchema && pBt->pSchema ){
pBt->xFreeSchema(pBt->pSchema);
}
@@ -68369,11 +68369,11 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
}
/*
-** Change the "soft" limit on the number of pages in the cache.
-** Unused and unmodified pages will be recycled when the number of
-** pages in the cache exceeds this soft limit. But the size of the
-** cache is allowed to grow larger than this limit if it contains
-** dirty pages or pages still in active use.
+** Change the "soft" limit on the number of pages in the cache.
+** Unused and unmodified pages will be recycled when the number of
+** pages in the cache exceeds this soft limit. But the size of the
+** cache is allowed to grow larger than this limit if it contains
+** dirty pages or pages still in active use.
*/
SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
BtShared *pBt = p->pBt;
@@ -68384,26 +68384,26 @@ SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
return SQLITE_OK;
}
-/*
-** Change the "spill" limit on the number of pages in the cache.
-** If the number of pages exceeds this limit during a write transaction,
-** the pager might attempt to "spill" pages to the journal early in
-** order to free up memory.
-**
-** The value returned is the current spill size. If zero is passed
-** as an argument, no changes are made to the spill size setting, so
-** using mxPage of 0 is a way to query the current spill size.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree *p, int mxPage){
- BtShared *pBt = p->pBt;
- int res;
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- res = sqlite3PagerSetSpillsize(pBt->pPager, mxPage);
- sqlite3BtreeLeave(p);
- return res;
-}
-
+/*
+** Change the "spill" limit on the number of pages in the cache.
+** If the number of pages exceeds this limit during a write transaction,
+** the pager might attempt to "spill" pages to the journal early in
+** order to free up memory.
+**
+** The value returned is the current spill size. If zero is passed
+** as an argument, no changes are made to the spill size setting, so
+** using mxPage of 0 is a way to query the current spill size.
+*/
+SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree *p, int mxPage){
+ BtShared *pBt = p->pBt;
+ int res;
+ assert( sqlite3_mutex_held(p->db->mutex) );
+ sqlite3BtreeEnter(p);
+ res = sqlite3PagerSetSpillsize(pBt->pPager, mxPage);
+ sqlite3BtreeLeave(p);
+ return res;
+}
+
#if SQLITE_MAX_MMAP_SIZE>0
/*
** Change the limit on the amount of the database file that may be
@@ -68548,34 +68548,34 @@ SQLITE_PRIVATE Pgno sqlite3BtreeMaxPageCount(Btree *p, Pgno mxPage){
}
/*
-** Change the values for the BTS_SECURE_DELETE and BTS_OVERWRITE flags:
-**
-** newFlag==0 Both BTS_SECURE_DELETE and BTS_OVERWRITE are cleared
-** newFlag==1 BTS_SECURE_DELETE set and BTS_OVERWRITE is cleared
-** newFlag==2 BTS_SECURE_DELETE cleared and BTS_OVERWRITE is set
-** newFlag==(-1) No changes
-**
-** This routine acts as a query if newFlag is less than zero
-**
-** With BTS_OVERWRITE set, deleted content is overwritten by zeros, but
-** freelist leaf pages are not written back to the database. Thus in-page
-** deleted content is cleared, but freelist deleted content is not.
-**
-** With BTS_SECURE_DELETE, operation is like BTS_OVERWRITE with the addition
-** that freelist leaf pages are written back into the database, increasing
-** the amount of disk I/O.
+** Change the values for the BTS_SECURE_DELETE and BTS_OVERWRITE flags:
+**
+** newFlag==0 Both BTS_SECURE_DELETE and BTS_OVERWRITE are cleared
+** newFlag==1 BTS_SECURE_DELETE set and BTS_OVERWRITE is cleared
+** newFlag==2 BTS_SECURE_DELETE cleared and BTS_OVERWRITE is set
+** newFlag==(-1) No changes
+**
+** This routine acts as a query if newFlag is less than zero
+**
+** With BTS_OVERWRITE set, deleted content is overwritten by zeros, but
+** freelist leaf pages are not written back to the database. Thus in-page
+** deleted content is cleared, but freelist deleted content is not.
+**
+** With BTS_SECURE_DELETE, operation is like BTS_OVERWRITE with the addition
+** that freelist leaf pages are written back into the database, increasing
+** the amount of disk I/O.
*/
SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){
int b;
if( p==0 ) return 0;
sqlite3BtreeEnter(p);
- assert( BTS_OVERWRITE==BTS_SECURE_DELETE*2 );
- assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) );
+ assert( BTS_OVERWRITE==BTS_SECURE_DELETE*2 );
+ assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) );
if( newFlag>=0 ){
- p->pBt->btsFlags &= ~BTS_FAST_SECURE;
- p->pBt->btsFlags |= BTS_SECURE_DELETE*newFlag;
- }
- b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE;
+ p->pBt->btsFlags &= ~BTS_FAST_SECURE;
+ p->pBt->btsFlags |= BTS_SECURE_DELETE*newFlag;
+ }
+ b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE;
sqlite3BtreeLeave(p);
return b;
}
@@ -68626,32 +68626,32 @@ SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){
#endif
}
-/*
-** If the user has not set the safety-level for this database connection
-** using "PRAGMA synchronous", and if the safety-level is not already
-** set to the value passed to this function as the second parameter,
-** set it so.
-*/
-#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS \
- && !defined(SQLITE_OMIT_WAL)
-static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){
- sqlite3 *db;
- Db *pDb;
- if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){
- while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; }
+/*
+** If the user has not set the safety-level for this database connection
+** using "PRAGMA synchronous", and if the safety-level is not already
+** set to the value passed to this function as the second parameter,
+** set it so.
+*/
+#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS \
+ && !defined(SQLITE_OMIT_WAL)
+static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){
+ sqlite3 *db;
+ Db *pDb;
+ if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){
+ while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; }
if( pDb->bSyncSet==0
&& pDb->safety_level!=safety_level
&& pDb!=&db->aDb[1]
- ){
- pDb->safety_level = safety_level;
- sqlite3PagerSetFlags(pBt->pPager,
- pDb->safety_level | (db->flags & PAGER_FLAGS_MASK));
- }
- }
-}
-#else
-# define setDefaultSyncFlag(pBt,safety_level)
-#endif
+ ){
+ pDb->safety_level = safety_level;
+ sqlite3PagerSetFlags(pBt->pPager,
+ pDb->safety_level | (db->flags & PAGER_FLAGS_MASK));
+ }
+ }
+}
+#else
+# define setDefaultSyncFlag(pBt,safety_level)
+#endif
/* Forward declaration */
static int newDatabase(BtShared*);
@@ -68730,16 +68730,16 @@ static int lockBtree(BtShared *pBt){
rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen);
if( rc!=SQLITE_OK ){
goto page1_init_failed;
- }else{
- setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1);
- if( isOpen==0 ){
- releasePageOne(pPage1);
- return SQLITE_OK;
- }
+ }else{
+ setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1);
+ if( isOpen==0 ){
+ releasePageOne(pPage1);
+ return SQLITE_OK;
+ }
}
rc = SQLITE_NOTADB;
- }else{
- setDefaultSyncFlag(pBt, SQLITE_DEFAULT_SYNCHRONOUS+1);
+ }else{
+ setDefaultSyncFlag(pBt, SQLITE_DEFAULT_SYNCHRONOUS+1);
}
#endif
@@ -68781,7 +68781,7 @@ static int lockBtree(BtShared *pBt){
** zero and return SQLITE_OK. The caller will call this function
** again with the correct page-size.
*/
- releasePageOne(pPage1);
+ releasePageOne(pPage1);
pBt->usableSize = usableSize;
pBt->pageSize = pageSize;
freeTempSpace(pBt);
@@ -68835,7 +68835,7 @@ static int lockBtree(BtShared *pBt){
return SQLITE_OK;
page1_init_failed:
- releasePageOne(pPage1);
+ releasePageOne(pPage1);
pBt->pPage1 = 0;
return rc;
}
@@ -68880,7 +68880,7 @@ static void unlockBtreeIfUnused(BtShared *pBt){
assert( pPage1->aData );
assert( sqlite3PagerRefcount(pBt->pPager)==1 );
pBt->pPage1 = 0;
- releasePageOne(pPage1);
+ releasePageOne(pPage1);
}
}
@@ -69007,30 +69007,30 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVers
}
#ifndef SQLITE_OMIT_SHARED_CACHE
- {
- sqlite3 *pBlock = 0;
+ {
+ sqlite3 *pBlock = 0;
/* If another database handle has already opened a write transaction
- ** on this shared-btree structure and a second write transaction is
- ** requested, return SQLITE_LOCKED.
- */
- if( (wrflag && pBt->inTransaction==TRANS_WRITE)
- || (pBt->btsFlags & BTS_PENDING)!=0
- ){
- pBlock = pBt->pWriter->db;
- }else if( wrflag>1 ){
- BtLock *pIter;
- for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
- if( pIter->pBtree!=p ){
- pBlock = pIter->pBtree->db;
- break;
- }
- }
- }
- if( pBlock ){
- sqlite3ConnectionBlocked(p->db, pBlock);
- rc = SQLITE_LOCKED_SHAREDCACHE;
- goto trans_begun;
- }
+ ** on this shared-btree structure and a second write transaction is
+ ** requested, return SQLITE_LOCKED.
+ */
+ if( (wrflag && pBt->inTransaction==TRANS_WRITE)
+ || (pBt->btsFlags & BTS_PENDING)!=0
+ ){
+ pBlock = pBt->pWriter->db;
+ }else if( wrflag>1 ){
+ BtLock *pIter;
+ for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
+ if( pIter->pBtree!=p ){
+ pBlock = pIter->pBtree->db;
+ break;
+ }
+ }
+ }
+ if( pBlock ){
+ sqlite3ConnectionBlocked(p->db, pBlock);
+ rc = SQLITE_LOCKED_SHAREDCACHE;
+ goto trans_begun;
+ }
}
#endif
@@ -69165,8 +69165,8 @@ static int setChildPtrmaps(MemPage *pPage){
Pgno pgno = pPage->pgno;
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- rc = pPage->isInit ? SQLITE_OK : btreeInitPage(pPage);
- if( rc!=SQLITE_OK ) return rc;
+ rc = pPage->isInit ? SQLITE_OK : btreeInitPage(pPage);
+ if( rc!=SQLITE_OK ) return rc;
nCell = pPage->nCell;
for(i=0; i<nCell; i++){
@@ -69208,7 +69208,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
if( eType==PTRMAP_OVERFLOW2 ){
/* The pointer is always the first 4 bytes of the page in this case. */
if( get4byte(pPage->aData)!=iFrom ){
- return SQLITE_CORRUPT_PAGE(pPage);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
put4byte(pPage->aData, iTo);
}else{
@@ -69216,7 +69216,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
int nCell;
int rc;
- rc = pPage->isInit ? SQLITE_OK : btreeInitPage(pPage);
+ rc = pPage->isInit ? SQLITE_OK : btreeInitPage(pPage);
if( rc ) return rc;
nCell = pPage->nCell;
@@ -69225,14 +69225,14 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
if( eType==PTRMAP_OVERFLOW1 ){
CellInfo info;
pPage->xParseCell(pPage, pCell, &info);
- if( info.nLocal<info.nPayload ){
- if( pCell+info.nSize > pPage->aData+pPage->pBt->usableSize ){
- return SQLITE_CORRUPT_PAGE(pPage);
- }
- if( iFrom==get4byte(pCell+info.nSize-4) ){
- put4byte(pCell+info.nSize-4, iTo);
- break;
- }
+ if( info.nLocal<info.nPayload ){
+ if( pCell+info.nSize > pPage->aData+pPage->pBt->usableSize ){
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
+ if( iFrom==get4byte(pCell+info.nSize-4) ){
+ put4byte(pCell+info.nSize-4, iTo);
+ break;
+ }
}
}else{
if( get4byte(pCell)==iFrom ){
@@ -69245,7 +69245,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
if( i==nCell ){
if( eType!=PTRMAP_BTREE ||
get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
- return SQLITE_CORRUPT_PAGE(pPage);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
}
@@ -69806,7 +69806,7 @@ SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int wr
p->eState = CURSOR_FAULT;
p->skipNext = errCode;
}
- btreeReleaseAllCursorPages(p);
+ btreeReleaseAllCursorPages(p);
}
sqlite3BtreeLeave(pBtree);
}
@@ -69871,7 +69871,7 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
** sure pPage1->aData is set correctly. */
if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
btreeSetNPage(pBt, pPage1);
- releasePageOne(pPage1);
+ releasePageOne(pPage1);
}
assert( countValidCursors(pBt, 1)==0 );
pBt->inTransaction = TRANS_READ;
@@ -69939,13 +69939,13 @@ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) );
sqlite3BtreeEnter(p);
- if( op==SAVEPOINT_ROLLBACK ){
- rc = saveAllCursors(pBt, 0, 0);
- }
+ if( op==SAVEPOINT_ROLLBACK ){
+ rc = saveAllCursors(pBt, 0, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint);
+ }
if( rc==SQLITE_OK ){
- rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint);
- }
- if( rc==SQLITE_OK ){
if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){
pBt->nPage = 0;
}
@@ -69968,13 +69968,13 @@ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
** on the database already. If a write-cursor is requested, then
** the caller is assumed to have an open write transaction.
**
-** If the BTREE_WRCSR bit of wrFlag is clear, then the cursor can only
-** be used for reading. If the BTREE_WRCSR bit is set, then the cursor
-** can be used for reading or for writing if other conditions for writing
-** are also met. These are the conditions that must be met in order
-** for writing to be allowed:
+** If the BTREE_WRCSR bit of wrFlag is clear, then the cursor can only
+** be used for reading. If the BTREE_WRCSR bit is set, then the cursor
+** can be used for reading or for writing if other conditions for writing
+** are also met. These are the conditions that must be met in order
+** for writing to be allowed:
**
-** 1: The cursor must have been opened with wrFlag containing BTREE_WRCSR
+** 1: The cursor must have been opened with wrFlag containing BTREE_WRCSR
**
** 2: Other database connections that share the same pager cache
** but which are not in the READ_UNCOMMITTED state may not have
@@ -69986,16 +69986,16 @@ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
**
** 4: There must be an active transaction.
**
-** The BTREE_FORDELETE bit of wrFlag may optionally be set if BTREE_WRCSR
-** is set. If FORDELETE is set, that is a hint to the implementation that
-** this cursor will only be used to seek to and delete entries of an index
-** as part of a larger DELETE statement. The FORDELETE hint is not used by
+** The BTREE_FORDELETE bit of wrFlag may optionally be set if BTREE_WRCSR
+** is set. If FORDELETE is set, that is a hint to the implementation that
+** this cursor will only be used to seek to and delete entries of an index
+** as part of a larger DELETE statement. The FORDELETE hint is not used by
** this implementation. But in a hypothetical alternative storage engine
-** in which index entries are automatically deleted when corresponding table
-** rows are deleted, the FORDELETE flag is a hint that all SEEK and DELETE
+** in which index entries are automatically deleted when corresponding table
+** rows are deleted, the FORDELETE flag is a hint that all SEEK and DELETE
** operations on this cursor can be no-ops and all READ operations can
-** return a null row (2-bytes: 0x01 0x00).
-**
+** return a null row (2-bytes: 0x01 0x00).
+**
** No checking is done to make sure that page iTable really is the
** root page of a b-tree. If it is not, then the cursor acquired
** will not work correctly.
@@ -70017,7 +70017,7 @@ static int btreeCursor(
assert( wrFlag==0
|| wrFlag==BTREE_WRCSR
|| wrFlag==(BTREE_WRCSR|BTREE_FORDELETE)
- );
+ );
/* The following assert statements verify that if this is a sharable
** b-tree database, the connection is holding the required table locks,
@@ -70035,7 +70035,7 @@ static int btreeCursor(
if( wrFlag ){
allocateTempSpace(pBt);
- if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
+ if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
}
if( iTable<=1 ){
if( iTable<1 ){
@@ -70053,7 +70053,7 @@ static int btreeCursor(
pCur->pKeyInfo = pKeyInfo;
pCur->pBtree = p;
pCur->pBt = pBt;
- pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0;
+ pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0;
pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY;
/* If there are two or more cursors on the same btree, then all such
** cursors *must* have the BTCF_Multiple flag set. */
@@ -70141,10 +70141,10 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
pPrev = pPrev->pNext;
}while( ALWAYS(pPrev) );
}
- btreeReleaseAllCursorPages(pCur);
+ btreeReleaseAllCursorPages(pCur);
unlockBtreeIfUnused(pBt);
sqlite3_free(pCur->aOverflow);
- sqlite3_free(pCur->pKey);
+ sqlite3_free(pCur->pKey);
if( (pBt->openFlags & BTREE_SINGLE) && pBt->pCursor==0 ){
/* Since the BtShared is not sharable, there is no need to
** worry about the missing sqlite3BtreeLeave() call here. */
@@ -70178,7 +70178,7 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
static void assertCellInfo(BtCursor *pCur){
CellInfo info;
memset(&info, 0, sizeof(info));
- btreeParseCell(pCur->pPage, pCur->ix, &info);
+ btreeParseCell(pCur->pPage, pCur->ix, &info);
assert( CORRUPT_DB || cellInfoEqual(&info, &pCur->info) );
}
#else
@@ -70187,7 +70187,7 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){
if( pCur->info.nSize==0 ){
pCur->curFlags |= BTCF_ValidNKey;
- btreeParseCell(pCur->pPage,pCur->ix,&pCur->info);
+ btreeParseCell(pCur->pPage,pCur->ix,&pCur->info);
}else{
assertCellInfo(pCur);
}
@@ -70203,23 +70203,23 @@ SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){
return pCur && pCur->eState==CURSOR_VALID;
}
#endif /* NDEBUG */
-SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor *pCur){
- assert( pCur!=0 );
- return pCur->eState==CURSOR_VALID;
-}
+SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor *pCur){
+ assert( pCur!=0 );
+ return pCur->eState==CURSOR_VALID;
+}
/*
-** Return the value of the integer key or "rowid" for a table btree.
-** This routine is only valid for a cursor that is pointing into a
-** ordinary table btree. If the cursor points to an index btree or
-** is invalid, the result of this routine is undefined.
+** Return the value of the integer key or "rowid" for a table btree.
+** This routine is only valid for a cursor that is pointing into a
+** ordinary table btree. If the cursor points to an index btree or
+** is invalid, the result of this routine is undefined.
*/
-SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor *pCur){
+SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor *pCur){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
- assert( pCur->curIntKey );
+ assert( pCur->curIntKey );
getCellInfo(pCur);
- return pCur->info.nKey;
+ return pCur->info.nKey;
}
/*
@@ -70234,34 +70234,34 @@ SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor *pCur){
pCur->curFlags &= ~BTCF_Pinned;
}
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
-/*
-** Return the offset into the database file for the start of the
-** payload to which the cursor is pointing.
-*/
-SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- getCellInfo(pCur);
- return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) +
- (i64)(pCur->info.pPayload - pCur->pPage->aData);
-}
-#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
-
-/*
-** Return the number of bytes of payload for the entry that pCur is
-** currently pointing to. For table btrees, this will be the amount
-** of data. For index btrees, this will be the size of the key.
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+/*
+** Return the offset into the database file for the start of the
+** payload to which the cursor is pointing.
+*/
+SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){
+ assert( cursorHoldsMutex(pCur) );
+ assert( pCur->eState==CURSOR_VALID );
+ getCellInfo(pCur);
+ return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) +
+ (i64)(pCur->info.pPayload - pCur->pPage->aData);
+}
+#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
+
+/*
+** Return the number of bytes of payload for the entry that pCur is
+** currently pointing to. For table btrees, this will be the amount
+** of data. For index btrees, this will be the size of the key.
**
** The caller must guarantee that the cursor is pointing to a non-NULL
** valid entry. In other words, the calling procedure must guarantee
** that the cursor has Cursor.eState==CURSOR_VALID.
*/
-SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){
+SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
getCellInfo(pCur);
- return pCur->info.nPayload;
+ return pCur->info.nPayload;
}
/*
@@ -70405,13 +70405,13 @@ static int copyPayload(
** The content being read or written might appear on the main page
** or be scattered out on multiple overflow pages.
**
-** If the current cursor entry uses one or more overflow pages
-** this function may allocate space for and lazily populate
+** If the current cursor entry uses one or more overflow pages
+** this function may allocate space for and lazily populate
** the overflow page-list cache array (BtCursor.aOverflow).
** Subsequent calls use this cache to make seeking to the supplied offset
** more efficient.
**
-** Once an overflow page-list cache has been allocated, it must be
+** Once an overflow page-list cache has been allocated, it must be
** invalidated if some other cursor writes to the same table, or if
** the cursor is moved to a different row. Additionally, in auto-vacuum
** mode, the following events may invalidate an overflow page-list cache.
@@ -70430,14 +70430,14 @@ static int accessPayload(
unsigned char *aPayload;
int rc = SQLITE_OK;
int iIdx = 0;
- MemPage *pPage = pCur->pPage; /* Btree page of current entry */
+ MemPage *pPage = pCur->pPage; /* Btree page of current entry */
BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
#ifdef SQLITE_DIRECT_OVERFLOW_READ
- unsigned char * const pBufStart = pBuf; /* Start of original out buffer */
+ unsigned char * const pBufStart = pBuf; /* Start of original out buffer */
#endif
assert( pPage );
- assert( eOp==0 || eOp==1 );
+ assert( eOp==0 || eOp==1 );
assert( pCur->eState==CURSOR_VALID );
if( pCur->ix>=pPage->nCell ){
return SQLITE_CORRUPT_PAGE(pPage);
@@ -70448,14 +70448,14 @@ static int accessPayload(
aPayload = pCur->info.pPayload;
assert( offset+amt <= pCur->info.nPayload );
- assert( aPayload > pPage->aData );
- if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){
- /* Trying to read or write past the end of the data is an error. The
- ** conditional above is really:
- ** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
- ** but is recast into its current form to avoid integer overflow problems
- */
- return SQLITE_CORRUPT_PAGE(pPage);
+ assert( aPayload > pPage->aData );
+ if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){
+ /* Trying to read or write past the end of the data is an error. The
+ ** conditional above is really:
+ ** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
+ ** but is recast into its current form to avoid integer overflow problems
+ */
+ return SQLITE_CORRUPT_PAGE(pPage);
}
/* Check if data must be read/written to/from the btree page itself. */
@@ -70464,7 +70464,7 @@ static int accessPayload(
if( a+offset>pCur->info.nLocal ){
a = pCur->info.nLocal - offset;
}
- rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage);
+ rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage);
offset = 0;
pBuf += a;
amt -= a;
@@ -70486,7 +70486,7 @@ static int accessPayload(
** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array
** means "not yet known" (the cache is lazily populated).
*/
- if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){
+ if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){
int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
if( pCur->aOverflow==0
|| nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow)
@@ -70495,33 +70495,33 @@ static int accessPayload(
pCur->aOverflow, nOvfl*2*sizeof(Pgno)
);
if( aNew==0 ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}else{
pCur->aOverflow = aNew;
}
}
- memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
- pCur->curFlags |= BTCF_ValidOvfl;
- }else{
- /* If the overflow page-list cache has been allocated and the
- ** entry for the first required overflow page is valid, skip
- ** directly to it.
- */
- if( pCur->aOverflow[offset/ovflSize] ){
- iIdx = (offset/ovflSize);
- nextPage = pCur->aOverflow[iIdx];
- offset = (offset%ovflSize);
+ memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
+ pCur->curFlags |= BTCF_ValidOvfl;
+ }else{
+ /* If the overflow page-list cache has been allocated and the
+ ** entry for the first required overflow page is valid, skip
+ ** directly to it.
+ */
+ if( pCur->aOverflow[offset/ovflSize] ){
+ iIdx = (offset/ovflSize);
+ nextPage = pCur->aOverflow[iIdx];
+ offset = (offset%ovflSize);
}
}
- assert( rc==SQLITE_OK && amt>0 );
- while( nextPage ){
+ assert( rc==SQLITE_OK && amt>0 );
+ while( nextPage ){
/* If required, populate the overflow page-list cache. */
if( nextPage > pBt->nPage ) return SQLITE_CORRUPT_BKPT;
- assert( pCur->aOverflow[iIdx]==0
- || pCur->aOverflow[iIdx]==nextPage
- || CORRUPT_DB );
- pCur->aOverflow[iIdx] = nextPage;
+ assert( pCur->aOverflow[iIdx]==0
+ || pCur->aOverflow[iIdx]==nextPage
+ || CORRUPT_DB );
+ pCur->aOverflow[iIdx] = nextPage;
if( offset>=ovflSize ){
/* The only reason to read this page is to obtain the page
@@ -70553,23 +70553,23 @@ static int accessPayload(
** 1) this is a read operation, and
** 2) data is required from the start of this overflow page, and
** 3) there are no dirty pages in the page-cache
- ** 4) the database is file-backed, and
- ** 5) the page is not in the WAL file
+ ** 4) the database is file-backed, and
+ ** 5) the page is not in the WAL file
** 6) at least 4 bytes have already been read into the output buffer
**
** then data can be read directly from the database file into the
** output buffer, bypassing the page-cache altogether. This speeds
** up loading large records that span many overflow pages.
*/
- if( eOp==0 /* (1) */
+ if( eOp==0 /* (1) */
&& offset==0 /* (2) */
&& sqlite3PagerDirectReadOk(pBt->pPager, nextPage) /* (3,4,5) */
- && &pBuf[-4]>=pBufStart /* (6) */
+ && &pBuf[-4]>=pBufStart /* (6) */
){
sqlite3_file *fd = sqlite3PagerFile(pBt->pPager);
u8 aSave[4];
u8 *aWrite = &pBuf[-4];
- assert( aWrite>=pBufStart ); /* due to (6) */
+ assert( aWrite>=pBufStart ); /* due to (6) */
memcpy(aSave, aWrite, 4);
rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT;
@@ -70580,86 +70580,86 @@ static int accessPayload(
{
DbPage *pDbPage;
- rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage,
- (eOp==0 ? PAGER_GET_READONLY : 0)
+ rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage,
+ (eOp==0 ? PAGER_GET_READONLY : 0)
);
if( rc==SQLITE_OK ){
aPayload = sqlite3PagerGetData(pDbPage);
nextPage = get4byte(aPayload);
- rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
+ rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
sqlite3PagerUnref(pDbPage);
offset = 0;
}
}
amt -= a;
- if( amt==0 ) return rc;
+ if( amt==0 ) return rc;
pBuf += a;
}
- if( rc ) break;
- iIdx++;
+ if( rc ) break;
+ iIdx++;
}
}
if( rc==SQLITE_OK && amt>0 ){
- /* Overflow chain ends prematurely */
- return SQLITE_CORRUPT_PAGE(pPage);
+ /* Overflow chain ends prematurely */
+ return SQLITE_CORRUPT_PAGE(pPage);
}
return rc;
}
/*
-** Read part of the payload for the row at which that cursor pCur is currently
-** pointing. "amt" bytes will be transferred into pBuf[]. The transfer
+** Read part of the payload for the row at which that cursor pCur is currently
+** pointing. "amt" bytes will be transferred into pBuf[]. The transfer
** begins at "offset".
**
-** pCur can be pointing to either a table or an index b-tree.
-** If pointing to a table btree, then the content section is read. If
-** pCur is pointing to an index b-tree then the key section is read.
+** pCur can be pointing to either a table or an index b-tree.
+** If pointing to a table btree, then the content section is read. If
+** pCur is pointing to an index b-tree then the key section is read.
+**
+** For sqlite3BtreePayload(), the caller must ensure that pCur is pointing
+** to a valid row in the table. For sqlite3BtreePayloadChecked(), the
+** cursor might be invalid or might need to be restored before being read.
**
-** For sqlite3BtreePayload(), the caller must ensure that pCur is pointing
-** to a valid row in the table. For sqlite3BtreePayloadChecked(), the
-** cursor might be invalid or might need to be restored before being read.
-**
** Return SQLITE_OK on success or an error code if anything goes
** wrong. An error is returned if "offset+amt" is larger than
** the available payload.
*/
-SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
+SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage>=0 && pCur->pPage );
+ assert( pCur->iPage>=0 && pCur->pPage );
return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
}
/*
-** This variant of sqlite3BtreePayload() works even if the cursor has not
-** in the CURSOR_VALID state. It is only used by the sqlite3_blob_read()
-** interface.
+** This variant of sqlite3BtreePayload() works even if the cursor has not
+** in the CURSOR_VALID state. It is only used by the sqlite3_blob_read()
+** interface.
*/
-#ifndef SQLITE_OMIT_INCRBLOB
-static SQLITE_NOINLINE int accessPayloadChecked(
- BtCursor *pCur,
- u32 offset,
- u32 amt,
- void *pBuf
-){
+#ifndef SQLITE_OMIT_INCRBLOB
+static SQLITE_NOINLINE int accessPayloadChecked(
+ BtCursor *pCur,
+ u32 offset,
+ u32 amt,
+ void *pBuf
+){
int rc;
if ( pCur->eState==CURSOR_INVALID ){
return SQLITE_ABORT;
}
- assert( cursorOwnsBtShared(pCur) );
- rc = btreeRestoreCursorPosition(pCur);
- return rc ? rc : accessPayload(pCur, offset, amt, pBuf, 0);
-}
-SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
- if( pCur->eState==CURSOR_VALID ){
- assert( cursorOwnsBtShared(pCur) );
- return accessPayload(pCur, offset, amt, pBuf, 0);
- }else{
- return accessPayloadChecked(pCur, offset, amt, pBuf);
+ assert( cursorOwnsBtShared(pCur) );
+ rc = btreeRestoreCursorPosition(pCur);
+ return rc ? rc : accessPayload(pCur, offset, amt, pBuf, 0);
+}
+SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
+ if( pCur->eState==CURSOR_VALID ){
+ assert( cursorOwnsBtShared(pCur) );
+ return accessPayload(pCur, offset, amt, pBuf, 0);
+ }else{
+ return accessPayloadChecked(pCur, offset, amt, pBuf);
}
}
-#endif /* SQLITE_OMIT_INCRBLOB */
+#endif /* SQLITE_OMIT_INCRBLOB */
/*
** Return a pointer to payload information from the entry that the
@@ -70684,23 +70684,23 @@ static const void *fetchPayload(
BtCursor *pCur, /* Cursor pointing to entry to read from */
u32 *pAmt /* Write the number of available bytes here */
){
- int amt;
- assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage);
+ int amt;
+ assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage);
assert( pCur->eState==CURSOR_VALID );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( pCur->ix<pCur->pPage->nCell || CORRUPT_DB );
assert( pCur->info.nSize>0 );
- assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
- assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB);
- amt = pCur->info.nLocal;
- if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){
- /* There is too little space on the page for the expected amount
- ** of local content. Database must be corrupt. */
- assert( CORRUPT_DB );
- amt = MAX(0, (int)(pCur->pPage->aDataEnd - pCur->info.pPayload));
- }
- *pAmt = (u32)amt;
+ assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
+ assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB);
+ amt = pCur->info.nLocal;
+ if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){
+ /* There is too little space on the page for the expected amount
+ ** of local content. Database must be corrupt. */
+ assert( CORRUPT_DB );
+ amt = MAX(0, (int)(pCur->pPage->aDataEnd - pCur->info.pPayload));
+ }
+ *pAmt = (u32)amt;
return (void*)pCur->info.pPayload;
}
@@ -70719,7 +70719,7 @@ static const void *fetchPayload(
** These routines is used to get quick access to key and data
** in the common case where no overflow pages are used.
*/
-SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){
+SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){
return fetchPayload(pCur, pAmt);
}
@@ -70736,7 +70736,7 @@ SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){
static int moveToChild(BtCursor *pCur, u32 newPgno){
BtShared *pBt = pCur->pBt;
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
assert( pCur->iPage>=0 );
@@ -70745,14 +70745,14 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
}
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
- pCur->aiIdx[pCur->iPage] = pCur->ix;
- pCur->apPage[pCur->iPage] = pCur->pPage;
- pCur->ix = 0;
+ pCur->aiIdx[pCur->iPage] = pCur->ix;
+ pCur->apPage[pCur->iPage] = pCur->pPage;
+ pCur->ix = 0;
pCur->iPage++;
- return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags);
+ return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags);
}
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/*
** Page pParent is an internal (non-leaf) tree page. This function
** asserts that page number iChild is the left-child if the iIdx'th
@@ -70783,23 +70783,23 @@ static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){
** the largest cell index.
*/
static void moveToParent(BtCursor *pCur){
- MemPage *pLeaf;
- assert( cursorOwnsBtShared(pCur) );
+ MemPage *pLeaf;
+ assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->iPage>0 );
- assert( pCur->pPage );
+ assert( pCur->pPage );
assertParentIndex(
pCur->apPage[pCur->iPage-1],
pCur->aiIdx[pCur->iPage-1],
- pCur->pPage->pgno
+ pCur->pPage->pgno
);
testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
- pCur->ix = pCur->aiIdx[pCur->iPage-1];
- pLeaf = pCur->pPage;
- pCur->pPage = pCur->apPage[--pCur->iPage];
- releasePageNotNull(pLeaf);
+ pCur->ix = pCur->aiIdx[pCur->iPage-1];
+ pLeaf = pCur->pPage;
+ pCur->pPage = pCur->apPage[--pCur->iPage];
+ releasePageNotNull(pLeaf);
}
/*
@@ -70811,9 +70811,9 @@ static void moveToParent(BtCursor *pCur){
** single child page. This can only happen with the table rooted at page 1.
**
** If the b-tree structure is empty, the cursor state is set to
-** CURSOR_INVALID and this routine returns SQLITE_EMPTY. Otherwise,
-** the cursor is set to point to the first cell located on the root
-** (or virtual root) page and the cursor state is set to CURSOR_VALID.
+** CURSOR_INVALID and this routine returns SQLITE_EMPTY. Otherwise,
+** the cursor is set to point to the first cell located on the root
+** (or virtual root) page and the cursor state is set to CURSOR_VALID.
**
** If this function returns successfully, it may be assumed that the
** page-header flags indicate that the [virtual] root-page is the expected
@@ -70827,44 +70827,44 @@ static int moveToRoot(BtCursor *pCur){
MemPage *pRoot;
int rc = SQLITE_OK;
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
assert( CURSOR_VALID < CURSOR_REQUIRESEEK );
assert( CURSOR_FAULT > CURSOR_REQUIRESEEK );
- assert( pCur->eState < CURSOR_REQUIRESEEK || pCur->iPage<0 );
- assert( pCur->pgnoRoot>0 || pCur->iPage<0 );
+ assert( pCur->eState < CURSOR_REQUIRESEEK || pCur->iPage<0 );
+ assert( pCur->pgnoRoot>0 || pCur->iPage<0 );
if( pCur->iPage>=0 ){
- if( pCur->iPage ){
- releasePageNotNull(pCur->pPage);
- while( --pCur->iPage ){
- releasePageNotNull(pCur->apPage[pCur->iPage]);
- }
- pCur->pPage = pCur->apPage[0];
- goto skip_init;
+ if( pCur->iPage ){
+ releasePageNotNull(pCur->pPage);
+ while( --pCur->iPage ){
+ releasePageNotNull(pCur->apPage[pCur->iPage]);
+ }
+ pCur->pPage = pCur->apPage[0];
+ goto skip_init;
}
}else if( pCur->pgnoRoot==0 ){
pCur->eState = CURSOR_INVALID;
- return SQLITE_EMPTY;
+ return SQLITE_EMPTY;
}else{
assert( pCur->iPage==(-1) );
- if( pCur->eState>=CURSOR_REQUIRESEEK ){
- if( pCur->eState==CURSOR_FAULT ){
- assert( pCur->skipNext!=SQLITE_OK );
- return pCur->skipNext;
- }
- sqlite3BtreeClearCursor(pCur);
- }
- rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage,
+ if( pCur->eState>=CURSOR_REQUIRESEEK ){
+ if( pCur->eState==CURSOR_FAULT ){
+ assert( pCur->skipNext!=SQLITE_OK );
+ return pCur->skipNext;
+ }
+ sqlite3BtreeClearCursor(pCur);
+ }
+ rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage,
0, pCur->curPagerFlags);
if( rc!=SQLITE_OK ){
pCur->eState = CURSOR_INVALID;
return rc;
}
pCur->iPage = 0;
- pCur->curIntKey = pCur->pPage->intKey;
+ pCur->curIntKey = pCur->pPage->intKey;
}
- pRoot = pCur->pPage;
+ pRoot = pCur->pPage;
assert( pRoot->pgno==pCur->pgnoRoot );
/* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
@@ -70879,15 +70879,15 @@ static int moveToRoot(BtCursor *pCur){
** (or the freelist). */
assert( pRoot->intKey==1 || pRoot->intKey==0 );
if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
- return SQLITE_CORRUPT_PAGE(pCur->pPage);
+ return SQLITE_CORRUPT_PAGE(pCur->pPage);
}
skip_init:
- pCur->ix = 0;
+ pCur->ix = 0;
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
- pRoot = pCur->pPage;
+ pRoot = pCur->pPage;
if( pRoot->nCell>0 ){
pCur->eState = CURSOR_VALID;
}else if( !pRoot->leaf ){
@@ -70898,7 +70898,7 @@ skip_init:
rc = moveToChild(pCur, subpage);
}else{
pCur->eState = CURSOR_INVALID;
- rc = SQLITE_EMPTY;
+ rc = SQLITE_EMPTY;
}
return rc;
}
@@ -70915,11 +70915,11 @@ static int moveToLeftmost(BtCursor *pCur){
int rc = SQLITE_OK;
MemPage *pPage;
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState==CURSOR_VALID );
- while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){
- assert( pCur->ix<pPage->nCell );
- pgno = get4byte(findCell(pPage, pCur->ix));
+ while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){
+ assert( pCur->ix<pPage->nCell );
+ pgno = get4byte(findCell(pPage, pCur->ix));
rc = moveToChild(pCur, pgno);
}
return rc;
@@ -70940,15 +70940,15 @@ static int moveToRightmost(BtCursor *pCur){
int rc = SQLITE_OK;
MemPage *pPage = 0;
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState==CURSOR_VALID );
- while( !(pPage = pCur->pPage)->leaf ){
+ while( !(pPage = pCur->pPage)->leaf ){
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- pCur->ix = pPage->nCell;
+ pCur->ix = pPage->nCell;
rc = moveToChild(pCur, pgno);
if( rc ) return rc;
}
- pCur->ix = pPage->nCell-1;
+ pCur->ix = pPage->nCell-1;
assert( pCur->info.nSize==0 );
assert( (pCur->curFlags & BTCF_ValidNKey)==0 );
return SQLITE_OK;
@@ -70961,17 +70961,17 @@ static int moveToRightmost(BtCursor *pCur){
SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
int rc;
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
rc = moveToRoot(pCur);
if( rc==SQLITE_OK ){
- assert( pCur->pPage->nCell>0 );
- *pRes = 0;
- rc = moveToLeftmost(pCur);
- }else if( rc==SQLITE_EMPTY ){
- assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
- *pRes = 1;
- rc = SQLITE_OK;
+ assert( pCur->pPage->nCell>0 );
+ *pRes = 0;
+ rc = moveToLeftmost(pCur);
+ }else if( rc==SQLITE_EMPTY ){
+ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
+ *pRes = 1;
+ rc = SQLITE_OK;
}
return rc;
}
@@ -70983,7 +70983,7 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
int rc;
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
/* If the cursor already points to the last entry, this is a no-op. */
@@ -70998,7 +70998,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
assert( pCur->ix==pCur->pPage->nCell-1 || CORRUPT_DB );
testcase( pCur->ix!=pCur->pPage->nCell-1 );
/* ^-- dbsqlfuzz b92b72e4de80b5140c30ab71372ca719b8feb618 */
- assert( pCur->pPage->leaf );
+ assert( pCur->pPage->leaf );
#endif
*pRes = 0;
return SQLITE_OK;
@@ -71006,18 +71006,18 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
rc = moveToRoot(pCur);
if( rc==SQLITE_OK ){
- assert( pCur->eState==CURSOR_VALID );
- *pRes = 0;
- rc = moveToRightmost(pCur);
- if( rc==SQLITE_OK ){
- pCur->curFlags |= BTCF_AtLast;
+ assert( pCur->eState==CURSOR_VALID );
+ *pRes = 0;
+ rc = moveToRightmost(pCur);
+ if( rc==SQLITE_OK ){
+ pCur->curFlags |= BTCF_AtLast;
}else{
- pCur->curFlags &= ~BTCF_AtLast;
+ pCur->curFlags &= ~BTCF_AtLast;
}
- }else if( rc==SQLITE_EMPTY ){
- assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
- *pRes = 1;
- rc = SQLITE_OK;
+ }else if( rc==SQLITE_EMPTY ){
+ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
+ *pRes = 1;
+ rc = SQLITE_OK;
}
return rc;
}
@@ -71053,7 +71053,7 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto(
){
int rc;
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( pRes );
assert( pCur->pKeyInfo==0 );
@@ -71066,27 +71066,27 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto(
*pRes = 0;
return SQLITE_OK;
}
- if( pCur->info.nKey<intKey ){
- if( (pCur->curFlags & BTCF_AtLast)!=0 ){
- *pRes = -1;
- return SQLITE_OK;
- }
- /* If the requested key is one more than the previous key, then
- ** try to get there using sqlite3BtreeNext() rather than a full
- ** binary search. This is an optimization only. The correct answer
- ** is still obtained without this case, only a little more slowely */
+ if( pCur->info.nKey<intKey ){
+ if( (pCur->curFlags & BTCF_AtLast)!=0 ){
+ *pRes = -1;
+ return SQLITE_OK;
+ }
+ /* If the requested key is one more than the previous key, then
+ ** try to get there using sqlite3BtreeNext() rather than a full
+ ** binary search. This is an optimization only. The correct answer
+ ** is still obtained without this case, only a little more slowely */
if( pCur->info.nKey+1==intKey ){
- *pRes = 0;
- rc = sqlite3BtreeNext(pCur, 0);
- if( rc==SQLITE_OK ){
- getCellInfo(pCur);
- if( pCur->info.nKey==intKey ){
- return SQLITE_OK;
- }
+ *pRes = 0;
+ rc = sqlite3BtreeNext(pCur, 0);
+ if( rc==SQLITE_OK ){
+ getCellInfo(pCur);
+ if( pCur->info.nKey==intKey ){
+ return SQLITE_OK;
+ }
}else if( rc!=SQLITE_DONE ){
- return rc;
- }
- }
+ return rc;
+ }
+ }
}
}
@@ -71096,24 +71096,24 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto(
rc = moveToRoot(pCur);
if( rc ){
- if( rc==SQLITE_EMPTY ){
- assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
- *pRes = -1;
- return SQLITE_OK;
- }
+ if( rc==SQLITE_EMPTY ){
+ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
+ *pRes = -1;
+ return SQLITE_OK;
+ }
return rc;
}
- assert( pCur->pPage );
- assert( pCur->pPage->isInit );
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->pPage->nCell > 0 );
- assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey );
+ assert( pCur->pPage );
+ assert( pCur->pPage->isInit );
+ assert( pCur->eState==CURSOR_VALID );
+ assert( pCur->pPage->nCell > 0 );
+ assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey );
assert( pCur->curIntKey );
for(;;){
int lwr, upr, idx, c;
Pgno chldPg;
- MemPage *pPage = pCur->pPage;
+ MemPage *pPage = pCur->pPage;
u8 *pCell; /* Pointer to current cell in pPage */
/* pPage->nCell must be greater than zero. If this is the root-page
@@ -71128,7 +71128,7 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto(
upr = pPage->nCell-1;
assert( biasRight==0 || biasRight==1 );
idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
- pCur->ix = (u16)idx;
+ pCur->ix = (u16)idx;
for(;;){
i64 nCellKey;
pCell = findCellPastPtr(pPage, idx);
@@ -71359,8 +71359,8 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto(
assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
assert( pPage->isInit );
if( pPage->leaf ){
- assert( pCur->ix<pCur->pPage->nCell );
- pCur->ix = (u16)idx;
+ assert( pCur->ix<pCur->pPage->nCell );
+ pCur->ix = (u16)idx;
*pRes = c;
rc = SQLITE_OK;
goto moveto_index_finish;
@@ -71370,13 +71370,13 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto(
}else{
chldPg = get4byte(findCell(pPage, lwr));
}
- pCur->ix = (u16)lwr;
+ pCur->ix = (u16)lwr;
rc = moveToChild(pCur, chldPg);
if( rc ) break;
}
moveto_index_finish:
pCur->info.nSize = 0;
- assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
+ assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
return rc;
}
@@ -71397,56 +71397,56 @@ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){
}
/*
-** Return an estimate for the number of rows in the table that pCur is
+** Return an estimate for the number of rows in the table that pCur is
** pointing to. Return a negative number if no estimate is currently
-** available.
-*/
-SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){
- i64 n;
- u8 i;
-
- assert( cursorOwnsBtShared(pCur) );
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
-
- /* Currently this interface is only called by the OP_IfSmaller
- ** opcode, and it that case the cursor will always be valid and
- ** will always point to a leaf node. */
- if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1;
- if( NEVER(pCur->pPage->leaf==0) ) return -1;
-
- n = pCur->pPage->nCell;
- for(i=0; i<pCur->iPage; i++){
- n *= pCur->apPage[i]->nCell;
- }
- return n;
-}
-
-/*
+** available.
+*/
+SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){
+ i64 n;
+ u8 i;
+
+ assert( cursorOwnsBtShared(pCur) );
+ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
+
+ /* Currently this interface is only called by the OP_IfSmaller
+ ** opcode, and it that case the cursor will always be valid and
+ ** will always point to a leaf node. */
+ if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1;
+ if( NEVER(pCur->pPage->leaf==0) ) return -1;
+
+ n = pCur->pPage->nCell;
+ for(i=0; i<pCur->iPage; i++){
+ n *= pCur->apPage[i]->nCell;
+ }
+ return n;
+}
+
+/*
** Advance the cursor to the next entry in the database.
-** Return value:
+** Return value:
+**
+** SQLITE_OK success
+** SQLITE_DONE cursor is already pointing at the last element
+** otherwise some kind of error occurred
**
-** SQLITE_OK success
-** SQLITE_DONE cursor is already pointing at the last element
-** otherwise some kind of error occurred
-**
** The main entry point is sqlite3BtreeNext(). That routine is optimized
** for the common case of merely incrementing the cell counter BtCursor.aiIdx
** to the next cell on the current page. The (slower) btreeNext() helper
** routine is called when it is necessary to move to a different page or
** to restore the cursor.
**
-** If bit 0x01 of the F argument in sqlite3BtreeNext(C,F) is 1, then the
-** cursor corresponds to an SQL index and this routine could have been
-** skipped if the SQL index had been a unique index. The F argument
-** is a hint to the implement. SQLite btree implementation does not use
-** this hint, but COMDB2 does.
+** If bit 0x01 of the F argument in sqlite3BtreeNext(C,F) is 1, then the
+** cursor corresponds to an SQL index and this routine could have been
+** skipped if the SQL index had been a unique index. The F argument
+** is a hint to the implement. SQLite btree implementation does not use
+** this hint, but COMDB2 does.
*/
-static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
+static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
int rc;
int idx;
MemPage *pPage;
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
if( pCur->eState!=CURSOR_VALID ){
assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
rc = restoreCursorPosition(pCur);
@@ -71454,7 +71454,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
return rc;
}
if( CURSOR_INVALID==pCur->eState ){
- return SQLITE_DONE;
+ return SQLITE_DONE;
}
if( pCur->eState==CURSOR_SKIPNEXT ){
pCur->eState = CURSOR_VALID;
@@ -71462,8 +71462,8 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
}
}
- pPage = pCur->pPage;
- idx = ++pCur->ix;
+ pPage = pCur->pPage;
+ idx = ++pCur->ix;
if( !pPage->isInit || sqlite3FaultSim(412) ){
/* The only known way for this to happen is for there to be a
** recursive SQL function that does a DELETE operation as part of a
@@ -71484,13 +71484,13 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
do{
if( pCur->iPage==0 ){
pCur->eState = CURSOR_INVALID;
- return SQLITE_DONE;
+ return SQLITE_DONE;
}
moveToParent(pCur);
- pPage = pCur->pPage;
- }while( pCur->ix>=pPage->nCell );
+ pPage = pCur->pPage;
+ }while( pCur->ix>=pPage->nCell );
if( pPage->intKey ){
- return sqlite3BtreeNext(pCur, 0);
+ return sqlite3BtreeNext(pCur, 0);
}else{
return SQLITE_OK;
}
@@ -71501,18 +71501,18 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
return moveToLeftmost(pCur);
}
}
-SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){
+SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){
MemPage *pPage;
- UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */
- assert( cursorOwnsBtShared(pCur) );
- assert( flags==0 || flags==1 );
+ UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */
+ assert( cursorOwnsBtShared(pCur) );
+ assert( flags==0 || flags==1 );
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
- if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur);
- pPage = pCur->pPage;
- if( (++pCur->ix)>=pPage->nCell ){
- pCur->ix--;
- return btreeNext(pCur);
+ if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur);
+ pPage = pCur->pPage;
+ if( (++pCur->ix)>=pPage->nCell ){
+ pCur->ix--;
+ return btreeNext(pCur);
}
if( pPage->leaf ){
return SQLITE_OK;
@@ -71522,30 +71522,30 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){
}
/*
-** Step the cursor to the back to the previous entry in the database.
-** Return values:
+** Step the cursor to the back to the previous entry in the database.
+** Return values:
+**
+** SQLITE_OK success
+** SQLITE_DONE the cursor is already on the first element of the table
+** otherwise some kind of error occurred
**
-** SQLITE_OK success
-** SQLITE_DONE the cursor is already on the first element of the table
-** otherwise some kind of error occurred
-**
** The main entry point is sqlite3BtreePrevious(). That routine is optimized
** for the common case of merely decrementing the cell counter BtCursor.aiIdx
** to the previous cell on the current page. The (slower) btreePrevious()
** helper routine is called when it is necessary to move to a different page
** or to restore the cursor.
**
-** If bit 0x01 of the F argument to sqlite3BtreePrevious(C,F) is 1, then
-** the cursor corresponds to an SQL index and this routine could have been
-** skipped if the SQL index had been a unique index. The F argument is a
-** hint to the implement. The native SQLite btree implementation does not
-** use this hint, but COMDB2 does.
+** If bit 0x01 of the F argument to sqlite3BtreePrevious(C,F) is 1, then
+** the cursor corresponds to an SQL index and this routine could have been
+** skipped if the SQL index had been a unique index. The F argument is a
+** hint to the implement. The native SQLite btree implementation does not
+** use this hint, but COMDB2 does.
*/
-static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
+static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
int rc;
MemPage *pPage;
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
assert( pCur->info.nSize==0 );
if( pCur->eState!=CURSOR_VALID ){
@@ -71554,7 +71554,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
return rc;
}
if( CURSOR_INVALID==pCur->eState ){
- return SQLITE_DONE;
+ return SQLITE_DONE;
}
if( CURSOR_SKIPNEXT==pCur->eState ){
pCur->eState = CURSOR_VALID;
@@ -71562,47 +71562,47 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
}
}
- pPage = pCur->pPage;
+ pPage = pCur->pPage;
assert( pPage->isInit );
if( !pPage->leaf ){
- int idx = pCur->ix;
+ int idx = pCur->ix;
rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
if( rc ) return rc;
rc = moveToRightmost(pCur);
}else{
- while( pCur->ix==0 ){
+ while( pCur->ix==0 ){
if( pCur->iPage==0 ){
pCur->eState = CURSOR_INVALID;
- return SQLITE_DONE;
+ return SQLITE_DONE;
}
moveToParent(pCur);
}
assert( pCur->info.nSize==0 );
- assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 );
+ assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 );
- pCur->ix--;
- pPage = pCur->pPage;
+ pCur->ix--;
+ pPage = pCur->pPage;
if( pPage->intKey && !pPage->leaf ){
- rc = sqlite3BtreePrevious(pCur, 0);
+ rc = sqlite3BtreePrevious(pCur, 0);
}else{
rc = SQLITE_OK;
}
}
return rc;
}
-SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int flags){
- assert( cursorOwnsBtShared(pCur) );
- assert( flags==0 || flags==1 );
- UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */
+SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int flags){
+ assert( cursorOwnsBtShared(pCur) );
+ assert( flags==0 || flags==1 );
+ UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
pCur->info.nSize = 0;
if( pCur->eState!=CURSOR_VALID
- || pCur->ix==0
- || pCur->pPage->leaf==0
+ || pCur->ix==0
+ || pCur->pPage->leaf==0
){
- return btreePrevious(pCur);
+ return btreePrevious(pCur);
}
- pCur->ix--;
+ pCur->ix--;
return SQLITE_OK;
}
@@ -71708,7 +71708,7 @@ static int allocateBtreePage(
}
testcase( iTrunk==mxPage );
if( iTrunk>mxPage || nSearch++ > n ){
- rc = SQLITE_CORRUPT_PGNO(pPrevTrunk ? pPrevTrunk->pgno : 1);
+ rc = SQLITE_CORRUPT_PGNO(pPrevTrunk ? pPrevTrunk->pgno : 1);
}else{
rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0);
}
@@ -71737,7 +71737,7 @@ static int allocateBtreePage(
TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
}else if( k>(u32)(pBt->usableSize/4 - 2) ){
/* Value of k is out of range. Database corruption */
- rc = SQLITE_CORRUPT_PGNO(iTrunk);
+ rc = SQLITE_CORRUPT_PGNO(iTrunk);
goto end_allocate_page;
#ifndef SQLITE_OMIT_AUTOVACUUM
}else if( searchList
@@ -71771,7 +71771,7 @@ static int allocateBtreePage(
MemPage *pNewTrunk;
Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
if( iNewTrunk>mxPage ){
- rc = SQLITE_CORRUPT_PGNO(iTrunk);
+ rc = SQLITE_CORRUPT_PGNO(iTrunk);
goto end_allocate_page;
}
testcase( iNewTrunk==mxPage );
@@ -71836,7 +71836,7 @@ static int allocateBtreePage(
iPage = get4byte(&aData[8+closest*4]);
testcase( iPage==mxPage );
if( iPage>mxPage || iPage<2 ){
- rc = SQLITE_CORRUPT_PGNO(iTrunk);
+ rc = SQLITE_CORRUPT_PGNO(iTrunk);
goto end_allocate_page;
}
testcase( iPage==mxPage );
@@ -72096,9 +72096,9 @@ static void freePage(MemPage *pPage, int *pRC){
static SQLITE_NOINLINE int clearCellOverflow(
MemPage *pPage, /* The page that contains the Cell */
unsigned char *pCell, /* First byte of the Cell */
- CellInfo *pInfo /* Size information about the cell */
+ CellInfo *pInfo /* Size information about the cell */
){
- BtShared *pBt;
+ BtShared *pBt;
Pgno ovflPgno;
int rc;
int nOvfl;
@@ -72109,16 +72109,16 @@ static SQLITE_NOINLINE int clearCellOverflow(
testcase( pCell + pInfo->nSize == pPage->aDataEnd );
testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd );
if( pCell + pInfo->nSize > pPage->aDataEnd ){
- /* Cell extends past end of page */
- return SQLITE_CORRUPT_PAGE(pPage);
+ /* Cell extends past end of page */
+ return SQLITE_CORRUPT_PAGE(pPage);
}
- ovflPgno = get4byte(pCell + pInfo->nSize - 4);
- pBt = pPage->pBt;
+ ovflPgno = get4byte(pCell + pInfo->nSize - 4);
+ pBt = pPage->pBt;
assert( pBt->usableSize > 4 );
ovflPageSize = pBt->usableSize - 4;
- nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize;
+ nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize;
assert( nOvfl>0 ||
- (CORRUPT_DB && (pInfo->nPayload + ovflPageSize)<ovflPageSize)
+ (CORRUPT_DB && (pInfo->nPayload + ovflPageSize)<ovflPageSize)
);
while( nOvfl-- ){
Pgno iNext = 0;
@@ -72191,75 +72191,75 @@ static SQLITE_NOINLINE int clearCellOverflow(
static int fillInCell(
MemPage *pPage, /* The page that contains the cell */
unsigned char *pCell, /* Complete text of the cell */
- const BtreePayload *pX, /* Payload with which to construct the cell */
+ const BtreePayload *pX, /* Payload with which to construct the cell */
int *pnSize /* Write cell size here */
){
int nPayload;
const u8 *pSrc;
- int nSrc, n, rc, mn;
+ int nSrc, n, rc, mn;
int spaceLeft;
- MemPage *pToRelease;
+ MemPage *pToRelease;
unsigned char *pPrior;
unsigned char *pPayload;
- BtShared *pBt;
- Pgno pgnoOvfl;
+ BtShared *pBt;
+ Pgno pgnoOvfl;
int nHeader;
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
/* pPage is not necessarily writeable since pCell might be auxiliary
** buffer space that is separate from the pPage buffer area */
- assert( pCell<pPage->aData || pCell>=&pPage->aData[pPage->pBt->pageSize]
+ assert( pCell<pPage->aData || pCell>=&pPage->aData[pPage->pBt->pageSize]
|| sqlite3PagerIswriteable(pPage->pDbPage) );
/* Fill in the header. */
nHeader = pPage->childPtrSize;
- if( pPage->intKey ){
- nPayload = pX->nData + pX->nZero;
- pSrc = pX->pData;
- nSrc = pX->nData;
- assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */
+ if( pPage->intKey ){
+ nPayload = pX->nData + pX->nZero;
+ pSrc = pX->pData;
+ nSrc = pX->nData;
+ assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */
nHeader += putVarint32(&pCell[nHeader], nPayload);
- nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey);
+ nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey);
}else{
- assert( pX->nKey<=0x7fffffff && pX->pKey!=0 );
- nSrc = nPayload = (int)pX->nKey;
- pSrc = pX->pKey;
- nHeader += putVarint32(&pCell[nHeader], nPayload);
+ assert( pX->nKey<=0x7fffffff && pX->pKey!=0 );
+ nSrc = nPayload = (int)pX->nKey;
+ pSrc = pX->pKey;
+ nHeader += putVarint32(&pCell[nHeader], nPayload);
}
- /* Fill in the payload */
- pPayload = &pCell[nHeader];
+ /* Fill in the payload */
+ pPayload = &pCell[nHeader];
if( nPayload<=pPage->maxLocal ){
- /* This is the common case where everything fits on the btree page
- ** and no overflow pages are required. */
+ /* This is the common case where everything fits on the btree page
+ ** and no overflow pages are required. */
n = nHeader + nPayload;
testcase( n==3 );
testcase( n==4 );
if( n<4 ) n = 4;
*pnSize = n;
- assert( nSrc<=nPayload );
- testcase( nSrc<nPayload );
- memcpy(pPayload, pSrc, nSrc);
- memset(pPayload+nSrc, 0, nPayload-nSrc);
- return SQLITE_OK;
- }
-
- /* If we reach this point, it means that some of the content will need
- ** to spill onto overflow pages.
- */
- mn = pPage->minLocal;
- n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4);
- testcase( n==pPage->maxLocal );
- testcase( n==pPage->maxLocal+1 );
- if( n > pPage->maxLocal ) n = mn;
- spaceLeft = n;
- *pnSize = n + nHeader + 4;
- pPrior = &pCell[nHeader+n];
- pToRelease = 0;
- pgnoOvfl = 0;
- pBt = pPage->pBt;
-
+ assert( nSrc<=nPayload );
+ testcase( nSrc<nPayload );
+ memcpy(pPayload, pSrc, nSrc);
+ memset(pPayload+nSrc, 0, nPayload-nSrc);
+ return SQLITE_OK;
+ }
+
+ /* If we reach this point, it means that some of the content will need
+ ** to spill onto overflow pages.
+ */
+ mn = pPage->minLocal;
+ n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4);
+ testcase( n==pPage->maxLocal );
+ testcase( n==pPage->maxLocal+1 );
+ if( n > pPage->maxLocal ) n = mn;
+ spaceLeft = n;
+ *pnSize = n + nHeader + 4;
+ pPrior = &pCell[nHeader+n];
+ pToRelease = 0;
+ pgnoOvfl = 0;
+ pBt = pPage->pBt;
+
/* At this point variables should be set as follows:
**
** nPayload Total payload size in bytes
@@ -72272,47 +72272,47 @@ static int fillInCell(
** Use a call to btreeParseCellPtr() to verify that the values above
** were computed correctly.
*/
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
{
CellInfo info;
pPage->xParseCell(pPage, pCell, &info);
- assert( nHeader==(int)(info.pPayload - pCell) );
- assert( info.nKey==pX->nKey );
+ assert( nHeader==(int)(info.pPayload - pCell) );
+ assert( info.nKey==pX->nKey );
assert( *pnSize == info.nSize );
assert( spaceLeft == info.nLocal );
}
#endif
/* Write the payload into the local Cell and any extra into overflow pages */
- while( 1 ){
- n = nPayload;
- if( n>spaceLeft ) n = spaceLeft;
-
- /* If pToRelease is not zero than pPayload points into the data area
- ** of pToRelease. Make sure pToRelease is still writeable. */
- assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
-
- /* If pPayload is part of the data area of pPage, then make sure pPage
- ** is still writeable */
- assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize]
- || sqlite3PagerIswriteable(pPage->pDbPage) );
-
- if( nSrc>=n ){
- memcpy(pPayload, pSrc, n);
- }else if( nSrc>0 ){
- n = nSrc;
- memcpy(pPayload, pSrc, n);
- }else{
- memset(pPayload, 0, n);
- }
- nPayload -= n;
- if( nPayload<=0 ) break;
- pPayload += n;
- pSrc += n;
- nSrc -= n;
- spaceLeft -= n;
+ while( 1 ){
+ n = nPayload;
+ if( n>spaceLeft ) n = spaceLeft;
+
+ /* If pToRelease is not zero than pPayload points into the data area
+ ** of pToRelease. Make sure pToRelease is still writeable. */
+ assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
+
+ /* If pPayload is part of the data area of pPage, then make sure pPage
+ ** is still writeable */
+ assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize]
+ || sqlite3PagerIswriteable(pPage->pDbPage) );
+
+ if( nSrc>=n ){
+ memcpy(pPayload, pSrc, n);
+ }else if( nSrc>0 ){
+ n = nSrc;
+ memcpy(pPayload, pSrc, n);
+ }else{
+ memset(pPayload, 0, n);
+ }
+ nPayload -= n;
+ if( nPayload<=0 ) break;
+ pPayload += n;
+ pSrc += n;
+ nSrc -= n;
+ spaceLeft -= n;
if( spaceLeft==0 ){
- MemPage *pOvfl = 0;
+ MemPage *pOvfl = 0;
#ifndef SQLITE_OMIT_AUTOVACUUM
Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
if( pBt->autoVacuum ){
@@ -72399,7 +72399,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
hdr = pPage->hdrOffset;
testcase( pc==(u32)get2byte(&data[hdr+5]) );
testcase( pc+sz==pPage->pBt->usableSize );
- if( pc+sz > pPage->pBt->usableSize ){
+ if( pc+sz > pPage->pBt->usableSize ){
*pRC = SQLITE_CORRUPT_BKPT;
return;
}
@@ -72433,8 +72433,8 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
** in pTemp or the original pCell) and also record its index.
** Allocating a new entry in pPage->aCell[] implies that
** pPage->nOverflow is incremented.
-**
-** *pRC must be SQLITE_OK when this routine is called.
+**
+** *pRC must be SQLITE_OK when this routine is called.
*/
static void insertCell(
MemPage *pPage, /* Page into which we are copying */
@@ -72450,7 +72450,7 @@ static void insertCell(
u8 *data; /* The content of the whole page */
u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */
- assert( *pRC==SQLITE_OK );
+ assert( *pRC==SQLITE_OK );
assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
assert( MX_CELL(pPage->pBt)<=10921 );
assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB );
@@ -72468,10 +72468,10 @@ static void insertCell(
put4byte(pCell, iChild);
}
j = pPage->nOverflow++;
- /* Comparison against ArraySize-1 since we hold back one extra slot
- ** as a contingency. In other words, never need more than 3 overflow
- ** slots but 4 are allocated, just to be safe. */
- assert( j < ArraySize(pPage->apOvfl)-1 );
+ /* Comparison against ArraySize-1 since we hold back one extra slot
+ ** as a contingency. In other words, never need more than 3 overflow
+ ** slots but 4 are allocated, just to be safe. */
+ assert( j < ArraySize(pPage->apOvfl)-1 );
pPage->apOvfl[j] = pCell;
pPage->aiOvfl[j] = (u16)i;
@@ -72550,7 +72550,7 @@ static void insertCell(
/*
** A CellArray object contains a cache of pointers and sizes for a
-** consecutive sequence of cells that might be held on multiple pages.
+** consecutive sequence of cells that might be held on multiple pages.
**
** The cells in this array are the divider cell or cells from the pParent
** page plus up to three child pages. There are a total of nCell cells.
@@ -72783,16 +72783,16 @@ static int pageInsertArray(
assert( pCArray->szCell[i]!=0 );
sz = pCArray->szCell[i];
if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
- if( (pData - pBegin)<sz ) return 1;
+ if( (pData - pBegin)<sz ) return 1;
pData -= sz;
pSlot = pData;
}
- /* pSlot and pCArray->apCell[i] will never overlap on a well-formed
- ** database. But they might for a corrupt database. Hence use memmove()
- ** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */
- assert( (pSlot+sz)<=pCArray->apCell[i]
- || pSlot>=(pCArray->apCell[i]+sz)
- || CORRUPT_DB );
+ /* pSlot and pCArray->apCell[i] will never overlap on a well-formed
+ ** database. But they might for a corrupt database. Hence use memmove()
+ ** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */
+ assert( (pSlot+sz)<=pCArray->apCell[i]
+ || pSlot>=(pCArray->apCell[i]+sz)
+ || CORRUPT_DB );
if( (uptr)(pCArray->apCell[i]+sz)>(uptr)pEnd
&& (uptr)(pCArray->apCell[i])<(uptr)pEnd
){
@@ -72800,7 +72800,7 @@ static int pageInsertArray(
(void)SQLITE_CORRUPT_BKPT;
return 1;
}
- memmove(pSlot, pCArray->apCell[i], sz);
+ memmove(pSlot, pCArray->apCell[i], sz);
put2byte(pCellptr, (pSlot - aData));
pCellptr += 2;
i++;
@@ -72840,7 +72840,7 @@ static int pageFreeArray(
for(i=iFirst; i<iEnd; i++){
u8 *pCell = pCArray->apCell[i];
- if( SQLITE_WITHIN(pCell, pStart, pEnd) ){
+ if( SQLITE_WITHIN(pCell, pStart, pEnd) ){
int sz;
/* No need to use cachedCellSize() here. The sizes of all cells that
** are to be freed have already been computing while deciding which
@@ -72971,7 +72971,7 @@ static int editPage(
for(i=0; i<nNew && !CORRUPT_DB; i++){
u8 *pCell = pCArray->apCell[i+iNew];
int iOff = get2byteAligned(&pPg->aCellIdx[i*2]);
- if( SQLITE_WITHIN(pCell, aData, &aData[pPg->pBt->usableSize]) ){
+ if( SQLITE_WITHIN(pCell, aData, &aData[pPg->pBt->usableSize]) ){
pCell = &pTmp[pCell - aData];
}
assert( 0==memcmp(pCell, &aData[iOff],
@@ -73091,10 +73091,10 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
while( ((*(pOut++) = *(pCell++))&0x80) && pCell<pStop );
/* Insert the new divider cell into pParent. */
- if( rc==SQLITE_OK ){
- insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace),
- 0, pPage->pgno, &rc);
- }
+ if( rc==SQLITE_OK ){
+ insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace),
+ 0, pPage->pgno, &rc);
+ }
/* Set the right-child pointer of pParent to point to the new page. */
put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
@@ -73128,8 +73128,8 @@ static int ptrmapCheckPages(MemPage **apPage, int nPage){
z = findCell(pPage, j);
pPage->xParseCell(pPage, z, &info);
- if( info.nLocal<info.nPayload ){
- Pgno ovfl = get4byte(&z[info.nSize-4]);
+ if( info.nLocal<info.nPayload ){
+ Pgno ovfl = get4byte(&z[info.nSize-4]);
ptrmapGet(pBt, ovfl, &e, &n);
assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 );
}
@@ -73299,7 +73299,7 @@ static int balance_nonroot(
assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx );
if( !aOvflSpace ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
assert( pParent->nFree>=0 );
@@ -73353,7 +73353,7 @@ static int balance_nonroot(
nMaxCells += apOld[i]->nCell + ArraySize(pParent->apOvfl);
if( (i--)==0 ) break;
- if( pParent->nOverflow && i+nxDiv==pParent->aiOvfl[0] ){
+ if( pParent->nOverflow && i+nxDiv==pParent->aiOvfl[0] ){
apDiv[i] = pParent->apOvfl[0];
pgno = get4byte(apDiv[i]);
szNew[i] = pParent->xCellSize(pParent, apDiv[i]);
@@ -73375,7 +73375,7 @@ static int balance_nonroot(
** In this case, temporarily copy the cell into the aOvflSpace[]
** buffer. It will be copied out again as soon as the aSpace[] buffer
** is allocated. */
- if( pBt->btsFlags & BTS_FAST_SECURE ){
+ if( pBt->btsFlags & BTS_FAST_SECURE ){
int iOff;
/* If the following if() condition is not true, the db is corrupted.
@@ -73403,9 +73403,9 @@ static int balance_nonroot(
+ pBt->pageSize; /* aSpace1 */
assert( szScratch<=7*(int)pBt->pageSize );
- b.apCell = sqlite3StackAllocRaw(0, szScratch );
+ b.apCell = sqlite3StackAllocRaw(0, szScratch );
if( b.apCell==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto balance_cleanup;
}
b.szCell = (u16*)&b.apCell[nMaxCells];
@@ -73465,7 +73465,7 @@ static int balance_nonroot(
** long be able to find the cells if a pointer to each cell is not saved
** first.
*/
- memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
+ memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
if( pOld->nOverflow>0 ){
if( NEVER(limit<pOld->aiOvfl[0]) ){
rc = SQLITE_CORRUPT_BKPT;
@@ -73632,7 +73632,7 @@ static int balance_nonroot(
assert( r<nMaxCells );
(void)cachedCellSize(&b, r);
if( szRight!=0
- && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+(i==k-1?0:2)))){
+ && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+(i==k-1?0:2)))){
break;
}
szRight += b.szCell[d] + 2;
@@ -73865,9 +73865,9 @@ static int balance_nonroot(
** any cell). But it is important to pass the correct size to
** insertCell(), so reparse the cell now.
**
- ** This can only happen for b-trees used to evaluate "IN (SELECT ...)"
- ** and WITHOUT ROWID tables with exactly one column which is the
- ** primary key.
+ ** This can only happen for b-trees used to evaluate "IN (SELECT ...)"
+ ** and WITHOUT ROWID tables with exactly one column which is the
+ ** primary key.
*/
if( b.szCell[j]==4 ){
assert(leafCorrection==4);
@@ -73969,8 +73969,8 @@ static int balance_nonroot(
** by smaller than the child due to the database header, and so all the
** free space needs to be up front.
*/
- assert( nNew==1 || CORRUPT_DB );
- rc = defragmentPage(apNew[0], -1);
+ assert( nNew==1 || CORRUPT_DB );
+ rc = defragmentPage(apNew[0], -1);
testcase( rc!=SQLITE_OK );
assert( apNew[0]->nFree ==
(get2byteNotZero(&apNew[0]->aData[5]) - apNew[0]->cellOffset
@@ -74014,7 +74014,7 @@ static int balance_nonroot(
** Cleanup before returning.
*/
balance_cleanup:
- sqlite3StackFree(0, b.apCell);
+ sqlite3StackFree(0, b.apCell);
for(i=0; i<nOld; i++){
releasePage(apOld[i]);
}
@@ -74132,12 +74132,12 @@ static int balance(BtCursor *pCur){
u8 aBalanceQuickSpace[13];
u8 *pFree = 0;
- VVA_ONLY( int balance_quick_called = 0 );
- VVA_ONLY( int balance_deeper_called = 0 );
+ VVA_ONLY( int balance_quick_called = 0 );
+ VVA_ONLY( int balance_deeper_called = 0 );
do {
int iPage;
- MemPage *pPage = pCur->pPage;
+ MemPage *pPage = pCur->pPage;
if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break;
if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
@@ -74149,16 +74149,16 @@ static int balance(BtCursor *pCur){
** and copy the current contents of the root-page to it. The
** next iteration of the do-loop will balance the child page.
*/
- assert( balance_deeper_called==0 );
- VVA_ONLY( balance_deeper_called++ );
+ assert( balance_deeper_called==0 );
+ VVA_ONLY( balance_deeper_called++ );
rc = balance_deeper(pPage, &pCur->apPage[1]);
if( rc==SQLITE_OK ){
pCur->iPage = 1;
- pCur->ix = 0;
+ pCur->ix = 0;
pCur->aiIdx[0] = 0;
- pCur->apPage[0] = pPage;
- pCur->pPage = pCur->apPage[1];
- assert( pCur->pPage->nOverflow );
+ pCur->apPage[0] = pPage;
+ pCur->pPage = pCur->apPage[1];
+ assert( pCur->pPage->nOverflow );
}
}else{
break;
@@ -74193,7 +74193,7 @@ static int balance(BtCursor *pCur){
** of the aBalanceQuickSpace[] might sneak in.
*/
assert( balance_quick_called==0 );
- VVA_ONLY( balance_quick_called++ );
+ VVA_ONLY( balance_quick_called++ );
rc = balance_quick(pParent, pPage, aBalanceQuickSpace);
}else
#endif
@@ -74239,7 +74239,7 @@ static int balance(BtCursor *pCur){
releasePage(pPage);
pCur->iPage--;
assert( pCur->iPage>=0 );
- pCur->pPage = pCur->apPage[pCur->iPage];
+ pCur->pPage = pCur->apPage[pCur->iPage];
}
}while( rc==SQLITE_OK );
@@ -74345,39 +74345,39 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
/*
-** Insert a new record into the BTree. The content of the new record
-** is described by the pX object. The pCur cursor is used only to
-** define what table the record should be inserted into, and is left
-** pointing at a random location.
+** Insert a new record into the BTree. The content of the new record
+** is described by the pX object. The pCur cursor is used only to
+** define what table the record should be inserted into, and is left
+** pointing at a random location.
**
-** For a table btree (used for rowid tables), only the pX.nKey value of
-** the key is used. The pX.pKey value must be NULL. The pX.nKey is the
-** rowid or INTEGER PRIMARY KEY of the row. The pX.nData,pData,nZero fields
-** hold the content of the row.
+** For a table btree (used for rowid tables), only the pX.nKey value of
+** the key is used. The pX.pKey value must be NULL. The pX.nKey is the
+** rowid or INTEGER PRIMARY KEY of the row. The pX.nData,pData,nZero fields
+** hold the content of the row.
**
-** For an index btree (used for indexes and WITHOUT ROWID tables), the
+** For an index btree (used for indexes and WITHOUT ROWID tables), the
** key is an arbitrary byte sequence stored in pX.pKey,nKey. The
-** pX.pData,nData,nZero fields must be zero.
-**
+** pX.pData,nData,nZero fields must be zero.
+**
** If the seekResult parameter is non-zero, then a successful call to
-** MovetoUnpacked() to seek cursor pCur to (pKey,nKey) has already
-** been performed. In other words, if seekResult!=0 then the cursor
-** is currently pointing to a cell that will be adjacent to the cell
-** to be inserted. If seekResult<0 then pCur points to a cell that is
-** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell
-** that is larger than (pKey,nKey).
-**
-** If seekResult==0, that means pCur is pointing at some unknown location.
-** In that case, this routine must seek the cursor to the correct insertion
-** point for (pKey,nKey) before doing the insertion. For index btrees,
-** if pX->nMem is non-zero, then pX->aMem contains pointers to the unpacked
-** key values and pX->aMem can be used instead of pX->pKey to avoid having
-** to decode the key.
+** MovetoUnpacked() to seek cursor pCur to (pKey,nKey) has already
+** been performed. In other words, if seekResult!=0 then the cursor
+** is currently pointing to a cell that will be adjacent to the cell
+** to be inserted. If seekResult<0 then pCur points to a cell that is
+** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell
+** that is larger than (pKey,nKey).
+**
+** If seekResult==0, that means pCur is pointing at some unknown location.
+** In that case, this routine must seek the cursor to the correct insertion
+** point for (pKey,nKey) before doing the insertion. For index btrees,
+** if pX->nMem is non-zero, then pX->aMem contains pointers to the unpacked
+** key values and pX->aMem can be used instead of pX->pKey to avoid having
+** to decode the key.
*/
SQLITE_PRIVATE int sqlite3BtreeInsert(
BtCursor *pCur, /* Insert data into the table of this cursor */
- const BtreePayload *pX, /* Content of the row to be inserted */
- int flags, /* True if this is likely an append */
+ const BtreePayload *pX, /* Content of the row to be inserted */
+ int flags, /* True if this is likely an append */
int seekResult /* Result of prior MovetoUnpacked() call */
){
int rc;
@@ -74392,13 +74392,13 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags );
assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 );
-
+
if( pCur->eState==CURSOR_FAULT ){
assert( pCur->skipNext!=SQLITE_OK );
return pCur->skipNext;
}
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( (pCur->curFlags & BTCF_WriteFlag)!=0
&& pBt->inTransaction==TRANS_WRITE
&& (pBt->btsFlags & BTS_READ_ONLY)==0 );
@@ -74436,7 +74436,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
}
if( pCur->pKeyInfo==0 ){
- assert( pX->pKey==0 );
+ assert( pX->pKey==0 );
/* If this is an insert into a table b-tree, invalidate any incrblob
** cursors open on the row being replaced */
if( p->hasIncrblobCur ){
@@ -74453,12 +74453,12 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
assert( loc==0 );
}
#endif
-
+
/* On the other hand, BTREE_SAVEPOSITION==0 does not imply
** that the cursor is not pointing to a row to be overwritten.
** So do a complete check.
*/
- if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){
+ if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){
/* The cursor is pointing to the entry that is to be
** overwritten */
assert( pX->nData>=0 && pX->nZero>=0 );
@@ -74505,7 +74505,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
(flags & BTREE_APPEND)!=0, &loc);
}
if( rc ) return rc;
- }
+ }
/* If the cursor is currently pointing to an entry to be overwritten
** and the new content is the same as as the old, then use the
@@ -74526,7 +74526,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
|| (pCur->eState==CURSOR_INVALID && loc)
|| CORRUPT_DB );
- pPage = pCur->pPage;
+ pPage = pCur->pPage;
assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
assert( pPage->leaf || !pPage->intKey );
if( pPage->nFree<0 ){
@@ -74539,7 +74539,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
}
TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
- pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
+ pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
loc==0 ? "overwrite" : "new entry"));
assert( pPage->isInit );
newCell = pBt->pTmpSpace;
@@ -74562,9 +74562,9 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
if( rc ) goto end_insert;
assert( szNew==pPage->xCellSize(pPage, newCell) );
assert( szNew <= MX_CELL_SIZE(pBt) );
- idx = pCur->ix;
+ idx = pCur->ix;
if( loc==0 ){
- CellInfo info;
+ CellInfo info;
assert( idx>=0 );
if( idx>=pPage->nCell ){
return SQLITE_CORRUPT_BKPT;
@@ -74581,38 +74581,38 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
testcase( pCur->curFlags & BTCF_ValidOvfl );
invalidateOverflowCache(pCur);
if( info.nSize==szNew && info.nLocal==info.nPayload
- && (!ISAUTOVACUUM || szNew<pPage->minLocal)
- ){
- /* Overwrite the old cell with the new if they are the same size.
- ** We could also try to do this if the old cell is smaller, then add
- ** the leftover space to the free list. But experiments show that
- ** doing that is no faster then skipping this optimization and just
+ && (!ISAUTOVACUUM || szNew<pPage->minLocal)
+ ){
+ /* Overwrite the old cell with the new if they are the same size.
+ ** We could also try to do this if the old cell is smaller, then add
+ ** the leftover space to the free list. But experiments show that
+ ** doing that is no faster then skipping this optimization and just
** calling dropCell() and insertCell().
- **
- ** This optimization cannot be used on an autovacuum database if the
- ** new entry uses overflow pages, as the insertCell() call below is
- ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */
- assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */
+ **
+ ** This optimization cannot be used on an autovacuum database if the
+ ** new entry uses overflow pages, as the insertCell() call below is
+ ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */
+ assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */
if( oldCell < pPage->aData+pPage->hdrOffset+10 ){
return SQLITE_CORRUPT_BKPT;
}
if( oldCell+szNew > pPage->aDataEnd ){
return SQLITE_CORRUPT_BKPT;
}
- memcpy(oldCell, newCell, szNew);
- return SQLITE_OK;
- }
- dropCell(pPage, idx, info.nSize, &rc);
+ memcpy(oldCell, newCell, szNew);
+ return SQLITE_OK;
+ }
+ dropCell(pPage, idx, info.nSize, &rc);
if( rc ) goto end_insert;
}else if( loc<0 && pPage->nCell>0 ){
assert( pPage->leaf );
- idx = ++pCur->ix;
- pCur->curFlags &= ~BTCF_ValidNKey;
+ idx = ++pCur->ix;
+ pCur->curFlags &= ~BTCF_ValidNKey;
}else{
assert( pPage->leaf );
}
insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
- assert( pPage->nOverflow==0 || rc==SQLITE_OK );
+ assert( pPage->nOverflow==0 || rc==SQLITE_OK );
assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );
/* If no error has occurred and pPage has an overflow cell, call balance()
@@ -74636,8 +74636,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
** row without seeking the cursor. This can be a big performance boost.
*/
pCur->info.nSize = 0;
- if( pPage->nOverflow ){
- assert( rc==SQLITE_OK );
+ if( pPage->nOverflow ){
+ assert( rc==SQLITE_OK );
pCur->curFlags &= ~(BTCF_ValidNKey);
rc = balance(pCur);
@@ -74645,24 +74645,24 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
** fails. Internal data structure corruption will result otherwise.
** Also, set the cursor state to invalid. This stops saveCursorPosition()
** from trying to save the current position of the cursor. */
- pCur->pPage->nOverflow = 0;
+ pCur->pPage->nOverflow = 0;
pCur->eState = CURSOR_INVALID;
- if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){
- btreeReleaseAllCursorPages(pCur);
- if( pCur->pKeyInfo ){
- assert( pCur->pKey==0 );
- pCur->pKey = sqlite3Malloc( pX->nKey );
- if( pCur->pKey==0 ){
- rc = SQLITE_NOMEM;
- }else{
- memcpy(pCur->pKey, pX->pKey, pX->nKey);
- }
- }
- pCur->eState = CURSOR_REQUIRESEEK;
- pCur->nKey = pX->nKey;
- }
- }
- assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 );
+ if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){
+ btreeReleaseAllCursorPages(pCur);
+ if( pCur->pKeyInfo ){
+ assert( pCur->pKey==0 );
+ pCur->pKey = sqlite3Malloc( pX->nKey );
+ if( pCur->pKey==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memcpy(pCur->pKey, pX->pKey, pX->nKey);
+ }
+ }
+ pCur->eState = CURSOR_REQUIRESEEK;
+ pCur->nKey = pX->nKey;
+ }
+ }
+ assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 );
end_insert:
return rc;
@@ -74778,22 +74778,22 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64
/*
** Delete the entry that the cursor is pointing to.
-**
-** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then
-** the cursor is left pointing at an arbitrary location after the delete.
-** But if that bit is set, then the cursor is left in a state such that
-** the next call to BtreeNext() or BtreePrev() moves it to the same row
-** as it would have been on if the call to BtreeDelete() had been omitted.
-**
-** The BTREE_AUXDELETE bit of flags indicates that is one of several deletes
-** associated with a single table entry and its indexes. Only one of those
-** deletes is considered the "primary" delete. The primary delete occurs
-** on a cursor that is not a BTREE_FORDELETE cursor. All but one delete
-** operation on non-FORDELETE cursors is tagged with the AUXDELETE flag.
-** The BTREE_AUXDELETE bit is a hint that is not used by this implementation,
-** but which might be used by alternative storage engines.
-*/
-SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
+**
+** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then
+** the cursor is left pointing at an arbitrary location after the delete.
+** But if that bit is set, then the cursor is left in a state such that
+** the next call to BtreeNext() or BtreePrev() moves it to the same row
+** as it would have been on if the call to BtreeDelete() had been omitted.
+**
+** The BTREE_AUXDELETE bit of flags indicates that is one of several deletes
+** associated with a single table entry and its indexes. Only one of those
+** deletes is considered the "primary" delete. The primary delete occurs
+** on a cursor that is not a BTREE_FORDELETE cursor. All but one delete
+** operation on non-FORDELETE cursors is tagged with the AUXDELETE flag.
+** The BTREE_AUXDELETE bit is a hint that is not used by this implementation,
+** but which might be used by alternative storage engines.
+*/
+SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
Btree *p = pCur->pBtree;
BtShared *pBt = p->pBt;
int rc; /* Return code */
@@ -74801,11 +74801,11 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
unsigned char *pCell; /* Pointer to cell to delete */
int iCellIdx; /* Index of cell to delete */
int iCellDepth; /* Depth of node containing pCell */
- CellInfo info; /* Size of the cell being deleted */
- int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */
- u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */
+ CellInfo info; /* Size of the cell being deleted */
+ int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */
+ u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */
- assert( cursorOwnsBtShared(pCur) );
+ assert( cursorOwnsBtShared(pCur) );
assert( pBt->inTransaction==TRANS_WRITE );
assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
assert( pCur->curFlags & BTCF_WriteFlag );
@@ -74820,8 +74820,8 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
assert( CORRUPT_DB || pCur->eState==CURSOR_VALID );
iCellDepth = pCur->iPage;
- iCellIdx = pCur->ix;
- pPage = pCur->pPage;
+ iCellIdx = pCur->ix;
+ pPage = pCur->pPage;
pCell = findCell(pPage, iCellIdx);
if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){
return SQLITE_CORRUPT_BKPT;
@@ -74830,29 +74830,29 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
return SQLITE_CORRUPT_BKPT;
}
- /* If the bPreserve flag is set to true, then the cursor position must
- ** be preserved following this delete operation. If the current delete
- ** will cause a b-tree rebalance, then this is done by saving the cursor
+ /* If the bPreserve flag is set to true, then the cursor position must
+ ** be preserved following this delete operation. If the current delete
+ ** will cause a b-tree rebalance, then this is done by saving the cursor
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
** returning.
- **
- ** Or, if the current delete will not cause a rebalance, then the cursor
- ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
- ** before or after the deleted entry. In this case set bSkipnext to true. */
- if( bPreserve ){
+ **
+ ** Or, if the current delete will not cause a rebalance, then the cursor
+ ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
+ ** before or after the deleted entry. In this case set bSkipnext to true. */
+ if( bPreserve ){
if( !pPage->leaf
- || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
+ || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
|| pPage->nCell==1 /* See dbfuzz001.test for a test case */
- ){
- /* A b-tree rebalance will be required after deleting this entry.
- ** Save the cursor key. */
- rc = saveCursorKey(pCur);
- if( rc ) return rc;
- }else{
- bSkipnext = 1;
- }
- }
-
+ ){
+ /* A b-tree rebalance will be required after deleting this entry.
+ ** Save the cursor key. */
+ rc = saveCursorKey(pCur);
+ if( rc ) return rc;
+ }else{
+ bSkipnext = 1;
+ }
+ }
+
/* If the page containing the entry to delete is not a leaf page, move
** the cursor to the largest entry in the tree that is smaller than
** the entry being deleted. This cell will replace the cell being deleted
@@ -74861,13 +74861,13 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
** sub-tree headed by the child page of the cell being deleted. This makes
** balancing the tree following the delete operation easier. */
if( !pPage->leaf ){
- rc = sqlite3BtreePrevious(pCur, 0);
- assert( rc!=SQLITE_DONE );
+ rc = sqlite3BtreePrevious(pCur, 0);
+ assert( rc!=SQLITE_DONE );
if( rc ) return rc;
}
/* Save the positions of any other cursors open on this table before
- ** making any modifications. */
+ ** making any modifications. */
if( pCur->curFlags & BTCF_Multiple ){
rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
if( rc ) return rc;
@@ -74876,16 +74876,16 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
/* If this is a delete operation to remove a row from a table b-tree,
** invalidate any incrblob cursors open on the row being deleted. */
if( pCur->pKeyInfo==0 && p->hasIncrblobCur ){
- invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0);
+ invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0);
}
- /* Make the page containing the entry to be deleted writable. Then free any
- ** overflow pages associated with the entry and finally remove the cell
- ** itself from within the page. */
+ /* Make the page containing the entry to be deleted writable. Then free any
+ ** overflow pages associated with the entry and finally remove the cell
+ ** itself from within the page. */
rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc ) return rc;
BTREE_CLEAR_CELL(rc, pPage, pCell, info);
- dropCell(pPage, iCellIdx, info.nSize, &rc);
+ dropCell(pPage, iCellIdx, info.nSize, &rc);
if( rc ) return rc;
/* If the cell deleted was not located on a leaf page, then the cursor
@@ -74894,20 +74894,20 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
** node. The cell from the leaf node needs to be moved to the internal
** node to replace the deleted cell. */
if( !pPage->leaf ){
- MemPage *pLeaf = pCur->pPage;
+ MemPage *pLeaf = pCur->pPage;
int nCell;
- Pgno n;
+ Pgno n;
unsigned char *pTmp;
if( pLeaf->nFree<0 ){
rc = btreeComputeFreeSpace(pLeaf);
if( rc ) return rc;
}
- if( iCellDepth<pCur->iPage-1 ){
- n = pCur->apPage[iCellDepth+1]->pgno;
- }else{
- n = pCur->pPage->pgno;
- }
+ if( iCellDepth<pCur->iPage-1 ){
+ n = pCur->apPage[iCellDepth+1]->pgno;
+ }else{
+ n = pCur->pPage->pgno;
+ }
pCell = findCell(pLeaf, pLeaf->nCell-1);
if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT;
nCell = pLeaf->xCellSize(pLeaf, pCell);
@@ -74915,9 +74915,9 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
pTmp = pBt->pTmpSpace;
assert( pTmp!=0 );
rc = sqlite3PagerWrite(pLeaf->pDbPage);
- if( rc==SQLITE_OK ){
- insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
- }
+ if( rc==SQLITE_OK ){
+ insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
+ }
dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
if( rc ) return rc;
}
@@ -74939,35 +74939,35 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
** well. */
rc = balance(pCur);
if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
- releasePageNotNull(pCur->pPage);
- pCur->iPage--;
+ releasePageNotNull(pCur->pPage);
+ pCur->iPage--;
while( pCur->iPage>iCellDepth ){
releasePage(pCur->apPage[pCur->iPage--]);
}
- pCur->pPage = pCur->apPage[pCur->iPage];
+ pCur->pPage = pCur->apPage[pCur->iPage];
rc = balance(pCur);
}
if( rc==SQLITE_OK ){
- if( bSkipnext ){
- assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) );
- assert( pPage==pCur->pPage || CORRUPT_DB );
- assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
- pCur->eState = CURSOR_SKIPNEXT;
- if( iCellIdx>=pPage->nCell ){
- pCur->skipNext = -1;
- pCur->ix = pPage->nCell-1;
- }else{
- pCur->skipNext = 1;
- }
- }else{
- rc = moveToRoot(pCur);
- if( bPreserve ){
- btreeReleaseAllCursorPages(pCur);
- pCur->eState = CURSOR_REQUIRESEEK;
- }
- if( rc==SQLITE_EMPTY ) rc = SQLITE_OK;
- }
+ if( bSkipnext ){
+ assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) );
+ assert( pPage==pCur->pPage || CORRUPT_DB );
+ assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
+ pCur->eState = CURSOR_SKIPNEXT;
+ if( iCellIdx>=pPage->nCell ){
+ pCur->skipNext = -1;
+ pCur->ix = pPage->nCell-1;
+ }else{
+ pCur->skipNext = 1;
+ }
+ }else{
+ rc = moveToRoot(pCur);
+ if( bPreserve ){
+ btreeReleaseAllCursorPages(pCur);
+ pCur->eState = CURSOR_REQUIRESEEK;
+ }
+ if( rc==SQLITE_EMPTY ) rc = SQLITE_OK;
+ }
}
return rc;
}
@@ -75151,7 +75151,7 @@ static int clearDatabasePage(
unsigned char *pCell;
int i;
int hdr;
- CellInfo info;
+ CellInfo info;
assert( sqlite3_mutex_held(pBt->mutex) );
if( pgno>btreePagecount(pBt) ){
@@ -75264,7 +75264,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
assert( sqlite3BtreeHoldsMutex(p) );
assert( p->inTrans==TRANS_WRITE );
- assert( iTable>=2 );
+ assert( iTable>=2 );
if( iTable>btreePagecount(pBt) ){
return SQLITE_CORRUPT_BKPT;
}
@@ -75280,66 +75280,66 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
*piMoved = 0;
#ifdef SQLITE_OMIT_AUTOVACUUM
- freePage(pPage, &rc);
- releasePage(pPage);
+ freePage(pPage, &rc);
+ releasePage(pPage);
#else
- if( pBt->autoVacuum ){
- Pgno maxRootPgno;
- sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
+ if( pBt->autoVacuum ){
+ Pgno maxRootPgno;
+ sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
- if( iTable==maxRootPgno ){
- /* If the table being dropped is the table with the largest root-page
+ if( iTable==maxRootPgno ){
+ /* If the table being dropped is the table with the largest root-page
** number in the database, put the root page on the free list.
*/
- freePage(pPage, &rc);
- releasePage(pPage);
- if( rc!=SQLITE_OK ){
- return rc;
+ freePage(pPage, &rc);
+ releasePage(pPage);
+ if( rc!=SQLITE_OK ){
+ return rc;
}
}else{
- /* The table being dropped does not have the largest root-page
+ /* The table being dropped does not have the largest root-page
** number in the database. So move the page that does into the
- ** gap left by the deleted root-page.
- */
- MemPage *pMove;
+ ** gap left by the deleted root-page.
+ */
+ MemPage *pMove;
releasePage(pPage);
- rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
- releasePage(pMove);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- pMove = 0;
- rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
- freePage(pMove, &rc);
- releasePage(pMove);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- *piMoved = maxRootPgno;
- }
-
- /* Set the new 'max-root-page' value in the database header. This
- ** is the old value less one, less one more if that happens to
- ** be a root-page number, less one again if that is the
- ** PENDING_BYTE_PAGE.
- */
- maxRootPgno--;
- while( maxRootPgno==PENDING_BYTE_PAGE(pBt)
- || PTRMAP_ISPAGE(pBt, maxRootPgno) ){
- maxRootPgno--;
- }
- assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
-
- rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
- }else{
- freePage(pPage, &rc);
+ rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
+ releasePage(pMove);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ pMove = 0;
+ rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
+ freePage(pMove, &rc);
+ releasePage(pMove);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ *piMoved = maxRootPgno;
+ }
+
+ /* Set the new 'max-root-page' value in the database header. This
+ ** is the old value less one, less one more if that happens to
+ ** be a root-page number, less one again if that is the
+ ** PENDING_BYTE_PAGE.
+ */
+ maxRootPgno--;
+ while( maxRootPgno==PENDING_BYTE_PAGE(pBt)
+ || PTRMAP_ISPAGE(pBt, maxRootPgno) ){
+ maxRootPgno--;
+ }
+ assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
+
+ rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
+ }else{
+ freePage(pPage, &rc);
releasePage(pPage);
}
-#endif
+#endif
return rc;
}
SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
@@ -75437,8 +75437,8 @@ SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){
i64 nEntry = 0; /* Value to return in *pnEntry */
int rc; /* Return code */
- rc = moveToRoot(pCur);
- if( rc==SQLITE_EMPTY ){
+ rc = moveToRoot(pCur);
+ if( rc==SQLITE_EMPTY ){
*pnEntry = 0;
return SQLITE_OK;
}
@@ -75454,7 +75454,7 @@ SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){
** this page contains countable entries. Increment the entry counter
** accordingly.
*/
- pPage = pCur->pPage;
+ pPage = pCur->pPage;
if( pPage->leaf || !pPage->intKey ){
nEntry += pPage->nCell;
}
@@ -75477,16 +75477,16 @@ SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){
return moveToRoot(pCur);
}
moveToParent(pCur);
- }while ( pCur->ix>=pCur->pPage->nCell );
+ }while ( pCur->ix>=pCur->pPage->nCell );
- pCur->ix++;
- pPage = pCur->pPage;
+ pCur->ix++;
+ pPage = pCur->pPage;
}
/* Descend to the child node of the cell that the cursor currently
** points at. This is the right-child if (iIdx==pPage->nCell).
*/
- iIdx = pCur->ix;
+ iIdx = pCur->ix;
if( iIdx==pPage->nCell ){
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
}else{
@@ -75625,7 +75625,7 @@ static void checkList(
unsigned char *pOvflData;
if( checkRef(pCheck, iPage) ) break;
N--;
- if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){
+ if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){
checkAppendMsg(pCheck, "failed to get page %d", iPage);
break;
}
@@ -75872,16 +75872,16 @@ static int checkTreePage(
checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey);
}
maxKey = info.nKey;
- keyCanBeEqual = 0; /* Only the first key on the page may ==maxKey */
+ keyCanBeEqual = 0; /* Only the first key on the page may ==maxKey */
}
/* Check the content overflow list */
if( info.nPayload>info.nLocal ){
u32 nPage; /* Number of pages on the overflow chain */
Pgno pgnoOvfl; /* First page of the overflow chain */
- assert( pc + info.nSize - 4 <= usableSize );
+ assert( pc + info.nSize - 4 <= usableSize );
nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4);
- pgnoOvfl = get4byte(&pCell[info.nSize - 4]);
+ pgnoOvfl = get4byte(&pCell[info.nSize - 4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum ){
checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage);
@@ -76050,8 +76050,8 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
sqlite3BtreeEnter(p);
assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
- VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) );
- assert( nRef>=0 );
+ VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) );
+ assert( nRef>=0 );
sCheck.db = db;
sCheck.pBt = pBt;
sCheck.pPager = pBt->pPager;
@@ -76065,7 +76065,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
sCheck.aPgRef = 0;
sCheck.heap = 0;
sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
- sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL;
+ sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL;
if( sCheck.nPage==0 ){
goto integrity_ck_cleanup;
}
@@ -76222,7 +76222,7 @@ SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *
if( pBt->inTransaction!=TRANS_NONE ){
rc = SQLITE_LOCKED;
}else{
- rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt);
+ rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt);
}
sqlite3BtreeLeave(p);
}
@@ -76324,7 +76324,7 @@ SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
*/
SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
int rc;
- assert( cursorOwnsBtShared(pCsr) );
+ assert( cursorOwnsBtShared(pCsr) );
assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
assert( pCsr->curFlags & BTCF_Incrblob );
@@ -76362,7 +76362,7 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void
&& pCsr->pBt->inTransaction==TRANS_WRITE );
assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) );
assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) );
- assert( pCsr->pPage->intKey );
+ assert( pCsr->pPage->intKey );
return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1);
}
@@ -76432,25 +76432,25 @@ SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){
*/
SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
-#if !defined(SQLITE_OMIT_SHARED_CACHE)
-/*
-** Return true if the Btree passed as the only argument is sharable.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){
- return p->sharable;
-}
-
-/*
-** Return the number of connections to the BtShared object accessed by
+#if !defined(SQLITE_OMIT_SHARED_CACHE)
+/*
+** Return true if the Btree passed as the only argument is sharable.
+*/
+SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){
+ return p->sharable;
+}
+
+/*
+** Return the number of connections to the BtShared object accessed by
** the Btree handle passed as the only argument. For private caches
-** this is always 1. For shared caches it may be 1 or greater.
-*/
-SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){
- testcase( p->sharable );
- return p->pBt->nRef;
-}
-#endif
-
+** this is always 1. For shared caches it may be 1 or greater.
+*/
+SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){
+ testcase( p->sharable );
+ return p->pBt->nRef;
+}
+#endif
+
/************** End of btree.c ***********************************************/
/************** Begin file backup.c ******************************************/
/*
@@ -76538,16 +76538,16 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
int i = sqlite3FindDbName(pDb, zDb);
if( i==1 ){
- Parse sParse;
+ Parse sParse;
int rc = 0;
- memset(&sParse, 0, sizeof(sParse));
- sParse.db = pDb;
- if( sqlite3OpenTempDatabase(&sParse) ){
- sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
- rc = SQLITE_ERROR;
- }
- sqlite3DbFree(pErrorDb, sParse.zErrMsg);
- sqlite3ParserReset(&sParse);
+ memset(&sParse, 0, sizeof(sParse));
+ sParse.db = pDb;
+ if( sqlite3OpenTempDatabase(&sParse) ){
+ sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
+ rc = SQLITE_ERROR;
+ }
+ sqlite3DbFree(pErrorDb, sParse.zErrMsg);
+ sqlite3ParserReset(&sParse);
if( rc ){
return 0;
}
@@ -76593,7 +76593,7 @@ static int checkReadTransaction(sqlite3 *db, Btree *p){
** If an error occurs, NULL is returned and an error code and error message
** stored in database handle pDestDb.
*/
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
+SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3* pDestDb, /* Database to write to */
const char *zDestDb, /* Name of database within pDestDb */
sqlite3* pSrcDb, /* Database connection to read from */
@@ -76631,7 +76631,7 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
** sqlite3_backup_finish(). */
p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
if( !p ){
- sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT);
+ sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT);
}
}
@@ -76714,7 +76714,7 @@ static int backupOnePage(
DbPage *pDestPg = 0;
Pgno iDest = (Pgno)(iOff/nDestPgsz)+1;
if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue;
- if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0))
+ if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0))
&& SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg))
){
const u8 *zIn = &zSrcData[iOff%nSrcPgsz];
@@ -76773,7 +76773,7 @@ static void attachBackupObject(sqlite3_backup *p){
/*
** Copy nPage pages from the source b-tree to the destination.
*/
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
+SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
int rc;
int destMode; /* Destination journal mode */
int pgszSrc = 0; /* Source page size */
@@ -76814,24 +76814,24 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
bCloseTrans = 1;
}
- /* If the destination database has not yet been locked (i.e. if this
- ** is the first call to backup_step() for the current backup operation),
- ** try to set its page size to the same as the source database. This
- ** is especially important on ZipVFS systems, as in that case it is
- ** not possible to create a database file that uses one page size by
- ** writing to it with another. */
- if( p->bDestLocked==0 && rc==SQLITE_OK && setDestPgsz(p)==SQLITE_NOMEM ){
- rc = SQLITE_NOMEM;
- }
-
- /* Lock the destination database, if it is not locked already. */
- if( SQLITE_OK==rc && p->bDestLocked==0
+ /* If the destination database has not yet been locked (i.e. if this
+ ** is the first call to backup_step() for the current backup operation),
+ ** try to set its page size to the same as the source database. This
+ ** is especially important on ZipVFS systems, as in that case it is
+ ** not possible to create a database file that uses one page size by
+ ** writing to it with another. */
+ if( p->bDestLocked==0 && rc==SQLITE_OK && setDestPgsz(p)==SQLITE_NOMEM ){
+ rc = SQLITE_NOMEM;
+ }
+
+ /* Lock the destination database, if it is not locked already. */
+ if( SQLITE_OK==rc && p->bDestLocked==0
&& SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2,
(int*)&p->iDestSchema))
- ){
- p->bDestLocked = 1;
- }
-
+ ){
+ p->bDestLocked = 1;
+ }
+
/* Do not allow backup if the destination database is in WAL mode
** and the page sizes are different between source and destination */
pgszSrc = sqlite3BtreeGetPageSize(p->pSrc);
@@ -76850,7 +76850,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
const Pgno iSrcPg = p->iNext; /* Source page number */
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
DbPage *pSrcPg; /* Source page object */
- rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY);
+ rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY);
if( rc==SQLITE_OK ){
rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
sqlite3PagerUnref(pSrcPg);
@@ -76950,7 +76950,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){
if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){
DbPage *pPg;
- rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0);
+ rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0);
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite(pPg);
sqlite3PagerUnref(pPg);
@@ -76970,7 +76970,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
){
PgHdr *pSrcPg = 0;
const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
- rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg, 0);
+ rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg, 0);
if( rc==SQLITE_OK ){
u8 *zData = sqlite3PagerGetData(pSrcPg);
rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
@@ -77012,7 +77012,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
}
if( rc==SQLITE_IOERR_NOMEM ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
p->rc = rc;
}
@@ -77027,7 +77027,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
/*
** Release all resources associated with an sqlite3_backup* handle.
*/
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
+SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
sqlite3_backup **pp; /* Ptr to head of pagers backup list */
sqlite3 *pSrcDb; /* Source database connection */
int rc; /* Value to return */
@@ -77081,7 +77081,7 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
** Return the number of pages still to be backed up as of the most recent
** call to sqlite3_backup_step().
*/
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
+SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
@@ -77095,7 +77095,7 @@ SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
** Return the total number of pages in the source database as of the most
** recent call to sqlite3_backup_step().
*/
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
+SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
@@ -77206,10 +77206,10 @@ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
** sqlite3_backup_step(), we can guarantee that the copy finishes
** within a single call (unless an error occurs). The assert() statement
** checks this assumption - (p->rc) should be set to either SQLITE_DONE
- ** or an error code. */
+ ** or an error code. */
sqlite3_backup_step(&b, 0x7FFFFFFF);
assert( b.rc!=SQLITE_OK );
-
+
rc = sqlite3_backup_finish(&b);
if( rc==SQLITE_OK ){
pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
@@ -77261,7 +77261,7 @@ copy_finished:
*/
SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
/* If MEM_Dyn is set then Mem.xDel!=0.
- ** Mem.xDel might not be initialized if MEM_Dyn is clear.
+ ** Mem.xDel might not be initialized if MEM_Dyn is clear.
*/
assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
@@ -77274,34 +77274,34 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
/* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */
assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) );
- if( p->flags & MEM_Null ){
- /* Cannot be both MEM_Null and some other type */
+ if( p->flags & MEM_Null ){
+ /* Cannot be both MEM_Null and some other type */
assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 );
-
- /* If MEM_Null is set, then either the value is a pure NULL (the usual
- ** case) or it is a pointer set using sqlite3_bind_pointer() or
- ** sqlite3_result_pointer(). If a pointer, then MEM_Term must also be
- ** set.
- */
- if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){
- /* This is a pointer type. There may be a flag to indicate what to
- ** do with the pointer. */
- assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
- ((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
- ((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );
-
- /* No other bits set */
+
+ /* If MEM_Null is set, then either the value is a pure NULL (the usual
+ ** case) or it is a pointer set using sqlite3_bind_pointer() or
+ ** sqlite3_result_pointer(). If a pointer, then MEM_Term must also be
+ ** set.
+ */
+ if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){
+ /* This is a pointer type. There may be a flag to indicate what to
+ ** do with the pointer. */
+ assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
+ ((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
+ ((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );
+
+ /* No other bits set */
assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype|MEM_FromBind
- |MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
- }else{
- /* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,
- ** MEM_Ephem, MEM_Cleared, or MEM_Subtype */
- }
- }else{
- /* The MEM_Cleared bit is only allowed on NULLs */
- assert( (p->flags & MEM_Cleared)==0 );
- }
-
+ |MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
+ }else{
+ /* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,
+ ** MEM_Ephem, MEM_Cleared, or MEM_Subtype */
+ }
+ }else{
+ /* The MEM_Cleared bit is only allowed on NULLs */
+ assert( (p->flags & MEM_Cleared)==0 );
+ }
+
/* The szMalloc field holds the correct memory allocation size */
assert( p->szMalloc==0
|| (p->flags==MEM_Undefined
@@ -77463,7 +77463,7 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
assert( sqlite3VdbeCheckMemInvariants(pMem) );
assert( !sqlite3VdbeMemIsRowSet(pMem) );
- testcase( pMem->db==0 );
+ testcase( pMem->db==0 );
/* If the bPreserve flag is set to true, then the memory cell must already
** contain a valid string or blob value. */
@@ -77474,7 +77474,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
|| (pMem->flags==MEM_Undefined
&& pMem->szMalloc<=sqlite3DbMallocSize(pMem->db,pMem->zMalloc))
|| pMem->szMalloc==sqlite3DbMallocSize(pMem->db,pMem->zMalloc));
- if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
+ if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
if( pMem->db ){
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
}else{
@@ -77482,22 +77482,22 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
if( pMem->zMalloc==0 ) sqlite3_free(pMem->z);
pMem->z = pMem->zMalloc;
}
- bPreserve = 0;
- }else{
- if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
- pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
- }
- if( pMem->zMalloc==0 ){
- sqlite3VdbeMemSetNull(pMem);
- pMem->z = 0;
- pMem->szMalloc = 0;
- return SQLITE_NOMEM_BKPT;
- }else{
- pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
- }
-
- if( bPreserve && pMem->z ){
- assert( pMem->z!=pMem->zMalloc );
+ bPreserve = 0;
+ }else{
+ if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
+ pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
+ }
+ if( pMem->zMalloc==0 ){
+ sqlite3VdbeMemSetNull(pMem);
+ pMem->z = 0;
+ pMem->szMalloc = 0;
+ return SQLITE_NOMEM_BKPT;
+ }else{
+ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
+ }
+
+ if( bPreserve && pMem->z ){
+ assert( pMem->z!=pMem->zMalloc );
memcpy(pMem->zMalloc, pMem->z, pMem->n);
}
if( (pMem->flags&MEM_Dyn)!=0 ){
@@ -77536,26 +77536,26 @@ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
}
/*
-** It is already known that pMem contains an unterminated string.
-** Add the zero terminator.
+** It is already known that pMem contains an unterminated string.
+** Add the zero terminator.
**
** Three bytes of zero are added. In this way, there is guaranteed
** to be a double-zero byte at an even byte boundary in order to
** terminate a UTF16 string, even if the initial size of the buffer
** is an odd number of bytes.
-*/
-static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
+*/
+static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){
- return SQLITE_NOMEM_BKPT;
- }
- pMem->z[pMem->n] = 0;
- pMem->z[pMem->n+1] = 0;
+ return SQLITE_NOMEM_BKPT;
+ }
+ pMem->z[pMem->n] = 0;
+ pMem->z[pMem->n+1] = 0;
pMem->z[pMem->n+2] = 0;
- pMem->flags |= MEM_Term;
- return SQLITE_OK;
-}
-
-/*
+ pMem->flags |= MEM_Term;
+ return SQLITE_OK;
+}
+
+/*
** Change pMem so that its MEM_Str or MEM_Blob value is stored in
** MEM.zMalloc, where it can be safely written.
**
@@ -77565,11 +77565,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
assert( pMem!=0 );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( !sqlite3VdbeMemIsRowSet(pMem) );
- if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
- if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
- if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
- int rc = vdbeMemAddTerminator(pMem);
- if( rc ) return rc;
+ if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
+ if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
+ if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
+ int rc = vdbeMemAddTerminator(pMem);
+ if( rc ) return rc;
}
}
pMem->flags &= ~MEM_Ephem;
@@ -77586,29 +77586,29 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
*/
#ifndef SQLITE_OMIT_INCRBLOB
SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
- int nByte;
+ int nByte;
assert( pMem!=0 );
- assert( pMem->flags & MEM_Zero );
+ assert( pMem->flags & MEM_Zero );
assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) );
testcase( sqlite3_value_nochange(pMem) );
assert( !sqlite3VdbeMemIsRowSet(pMem) );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- /* Set nByte to the number of bytes required to store the expanded blob. */
- nByte = pMem->n + pMem->u.nZero;
- if( nByte<=0 ){
+ /* Set nByte to the number of bytes required to store the expanded blob. */
+ nByte = pMem->n + pMem->u.nZero;
+ if( nByte<=0 ){
if( (pMem->flags & MEM_Blob)==0 ) return SQLITE_OK;
- nByte = 1;
- }
- if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
- return SQLITE_NOMEM_BKPT;
- }
+ nByte = 1;
+ }
+ if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
+ return SQLITE_NOMEM_BKPT;
+ }
assert( pMem->z!=0 );
assert( sqlite3DbMallocSize(pMem->db,pMem->z) >= nByte );
- memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
- pMem->n += pMem->u.nZero;
- pMem->flags &= ~(MEM_Zero|MEM_Term);
+ memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
+ pMem->n += pMem->u.nZero;
+ pMem->flags &= ~(MEM_Zero|MEM_Term);
return SQLITE_OK;
}
#endif
@@ -77655,8 +77655,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
- pMem->enc = 0;
- return SQLITE_NOMEM_BKPT;
+ pMem->enc = 0;
+ return SQLITE_NOMEM_BKPT;
}
vdbeMemRenderNum(nByte, pMem->z, pMem);
@@ -77678,25 +77678,25 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
** otherwise.
*/
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
- sqlite3_context ctx;
- Mem t;
- assert( pFunc!=0 );
+ sqlite3_context ctx;
+ Mem t;
+ assert( pFunc!=0 );
assert( pMem!=0 );
- assert( pFunc->xFinalize!=0 );
- assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- memset(&ctx, 0, sizeof(ctx));
- memset(&t, 0, sizeof(t));
- t.flags = MEM_Null;
- t.db = pMem->db;
- ctx.pOut = &t;
- ctx.pMem = pMem;
- ctx.pFunc = pFunc;
- pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
- assert( (pMem->flags & MEM_Dyn)==0 );
- if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
- memcpy(pMem, &t, sizeof(t));
- return ctx.isError;
+ assert( pFunc->xFinalize!=0 );
+ assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
+ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+ memset(&ctx, 0, sizeof(ctx));
+ memset(&t, 0, sizeof(t));
+ t.flags = MEM_Null;
+ t.db = pMem->db;
+ ctx.pOut = &t;
+ ctx.pMem = pMem;
+ ctx.pFunc = pFunc;
+ pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
+ assert( (pMem->flags & MEM_Dyn)==0 );
+ if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
+ memcpy(pMem, &t, sizeof(t));
+ return ctx.isError;
}
/*
@@ -77761,7 +77761,7 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
vdbeMemClearExternAndSetNull(p);
}
if( p->szMalloc ){
- sqlite3DbFreeNN(p->db, p->zMalloc);
+ sqlite3DbFreeNN(p->db, p->zMalloc);
p->szMalloc = 0;
}
p->z = 0;
@@ -77789,7 +77789,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
** If the double is out of range of a 64-bit signed integer then
** return the closest available 64-bit signed integer.
*/
-static SQLITE_NOINLINE i64 doubleToInt64(double r){
+static SQLITE_NOINLINE i64 doubleToInt64(double r){
#ifdef SQLITE_OMIT_FLOATING_POINT
/* When floating-point is omitted, double and int64 are the same thing */
return r;
@@ -77825,11 +77825,11 @@ static SQLITE_NOINLINE i64 doubleToInt64(double r){
**
** If pMem represents a string value, its encoding might be changed.
*/
-static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){
- i64 value = 0;
- sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
- return value;
-}
+static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){
+ i64 value = 0;
+ sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
+ return value;
+}
SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
int flags;
assert( pMem!=0 );
@@ -77842,7 +77842,7 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
}else if( flags & MEM_Real ){
return doubleToInt64(pMem->u.r);
}else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){
- return memIntValue(pMem);
+ return memIntValue(pMem);
}else{
return 0;
}
@@ -77854,12 +77854,12 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
** value. If it is a string or blob, try to convert it to a double.
** If it is a NULL, return 0.0.
*/
-static SQLITE_NOINLINE double memRealValue(Mem *pMem){
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- double val = (double)0;
- sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
- return val;
-}
+static SQLITE_NOINLINE double memRealValue(Mem *pMem){
+ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
+ double val = (double)0;
+ sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
+ return val;
+}
SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
assert( pMem!=0 );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -77870,7 +77870,7 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
testcase( pMem->flags & MEM_IntReal );
return (double)pMem->u.i;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
- return memRealValue(pMem);
+ return memRealValue(pMem);
}else{
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
return (double)0;
@@ -77977,7 +77977,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
testcase( pMem->flags & MEM_IntReal );
testcase( pMem->flags & MEM_Null );
if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
- int rc;
+ int rc;
sqlite3_int64 ix;
assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -77992,7 +77992,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
}
}
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 );
- pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
+ pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
return SQLITE_OK;
}
@@ -78010,7 +78010,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
if( (pMem->flags & MEM_Blob)==0 ){
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
- if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob);
+ if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob);
}else{
pMem->flags &= ~(MEM_TypeMask&~MEM_Blob);
}
@@ -78131,27 +78131,27 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
}
}
-/* A no-op destructor */
+/* A no-op destructor */
SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
-
-/*
-** Set the value stored in *pMem should already be a NULL.
-** Also store a pointer to go with it.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(
- Mem *pMem,
- void *pPtr,
- const char *zPType,
- void (*xDestructor)(void*)
-){
- assert( pMem->flags==MEM_Null );
- pMem->u.zPType = zPType ? zPType : "";
- pMem->z = pPtr;
- pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
- pMem->eSubtype = 'p';
- pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
-}
-
+
+/*
+** Set the value stored in *pMem should already be a NULL.
+** Also store a pointer to go with it.
+*/
+SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(
+ Mem *pMem,
+ void *pPtr,
+ const char *zPType,
+ void (*xDestructor)(void*)
+){
+ assert( pMem->flags==MEM_Null );
+ pMem->u.zPType = zPType ? zPType : "";
+ pMem->z = pPtr;
+ pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
+ pMem->eSubtype = 'p';
+ pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
+}
+
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Delete any previous value and set the value stored in *pMem to val,
@@ -78381,7 +78381,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
testcase( nAlloc==31 );
testcase( nAlloc==32 );
if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(pMem->z, z, nAlloc);
}else{
@@ -78411,7 +78411,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
#ifndef SQLITE_OMIT_UTF16
if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
#endif
@@ -78424,9 +78424,9 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
/*
** Move data out of a btree key or data field and into a Mem structure.
-** The data is payload from the entry that pCur is currently pointing
+** The data is payload from the entry that pCur is currently pointing
** to. offset and amt determine what portion of the data or key to retrieve.
-** The result is written into the pMem element.
+** The result is written into the pMem element.
**
** The pMem object must have been initialized. This routine will use
** pMem->zMalloc to hold the content from the btree, if possible. New
@@ -78448,11 +78448,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
if( sqlite3BtreeMaxRecordSize(pCur)<offset+amt ){
return SQLITE_CORRUPT_BKPT;
}
- if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){
- rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z);
+ if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){
+ rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z);
if( rc==SQLITE_OK ){
- pMem->z[amt] = 0; /* Overrun area used when reading malformed records */
- pMem->flags = MEM_Blob;
+ pMem->z[amt] = 0; /* Overrun area used when reading malformed records */
+ pMem->flags = MEM_Blob;
pMem->n = (int)amt;
}else{
sqlite3VdbeMemRelease(pMem);
@@ -78499,7 +78499,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
assert( !sqlite3VdbeMemIsRowSet(pVal) );
assert( (pVal->flags & (MEM_Null))==0 );
if( pVal->flags & (MEM_Blob|MEM_Str) ){
- if( ExpandBlob(pVal) ) return 0;
+ if( ExpandBlob(pVal) ) return 0;
pVal->flags |= MEM_Str;
if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){
sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
@@ -78600,7 +78600,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
if( pRec ){
pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx);
if( pRec->pKeyInfo ){
- assert( pRec->pKeyInfo->nAllField==nCol );
+ assert( pRec->pKeyInfo->nAllField==nCol );
assert( pRec->pKeyInfo->enc==ENC(db) );
pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord)));
for(i=0; i<nCol; i++){
@@ -78608,7 +78608,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
pRec->aMem[i].db = db;
}
}else{
- sqlite3DbFreeNN(db, pRec);
+ sqlite3DbFreeNN(db, pRec);
pRec = 0;
}
}
@@ -78630,7 +78630,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
** to be a scalar SQL function. If
**
** * all function arguments are SQL literals,
-** * one of the SQLITE_FUNC_CONSTANT or _SLOCHNG function flags is set, and
+** * one of the SQLITE_FUNC_CONSTANT or _SLOCHNG function flags is set, and
** * the SQLITE_FUNC_NEEDCOLL function flag is not set,
**
** then this routine attempts to invoke the SQL function. Assuming no
@@ -78669,7 +78669,7 @@ static int valueFromFunction(
pList = p->x.pList;
if( pList ) nVal = pList->nExpr;
assert( !ExprHasProperty(p, EP_IntValue) );
- pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
+ pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
assert( pFunc );
if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
|| (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
@@ -78680,7 +78680,7 @@ static int valueFromFunction(
if( pList ){
apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
if( apVal==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto value_from_function_out;
}
for(i=0; i<nVal; i++){
@@ -78691,7 +78691,7 @@ static int valueFromFunction(
pVal = valueNew(db, pCtx);
if( pVal==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto value_from_function_out;
}
@@ -78699,7 +78699,7 @@ static int valueFromFunction(
memset(&ctx, 0, sizeof(ctx));
ctx.pOut = pVal;
ctx.pFunc = pFunc;
- pFunc->xSFunc(&ctx, nVal, apVal);
+ pFunc->xSFunc(&ctx, nVal, apVal);
if( ctx.isError ){
rc = ctx.isError;
sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
@@ -78722,7 +78722,7 @@ static int valueFromFunction(
for(i=0; i<nVal; i++){
sqlite3ValueFree(apVal[i]);
}
- sqlite3DbFreeNN(db, apVal);
+ sqlite3DbFreeNN(db, apVal);
}
*ppVal = pVal;
@@ -78757,13 +78757,13 @@ static int valueFromExpr(
const char *zNeg = "";
int rc = SQLITE_OK;
- assert( pExpr!=0 );
- while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
+ assert( pExpr!=0 );
+ while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
#if defined(SQLITE_ENABLE_STAT4)
- if( op==TK_REGISTER ) op = pExpr->op2;
-#else
+ if( op==TK_REGISTER ) op = pExpr->op2;
+#else
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
-#endif
+#endif
/* Compressed expressions only appear when parsing the DEFAULT clause
** on a table column definition, and hence only when pCtx==0. This
@@ -78878,9 +78878,9 @@ static int valueFromExpr(
no_mem:
#ifdef SQLITE_ENABLE_STAT4
- if( pCtx==0 || pCtx->pParse->nErr==0 )
-#endif
- sqlite3OomFault(db);
+ if( pCtx==0 || pCtx->pParse->nErr==0 )
+#endif
+ sqlite3OomFault(db);
sqlite3DbFree(db, zVal);
assert( *ppVal==0 );
#ifdef SQLITE_ENABLE_STAT4
@@ -78888,7 +78888,7 @@ no_mem:
#else
assert( pCtx==0 ); sqlite3ValueFree(pVal);
#endif
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
/*
@@ -78908,7 +78908,7 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
u8 affinity, /* Affinity to use */
sqlite3_value **ppVal /* Write the new value here */
){
- return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
+ return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
}
#ifdef SQLITE_ENABLE_STAT4
@@ -78944,13 +78944,13 @@ static int stat4ValueFromExpr(
/* Skip over any TK_COLLATE nodes */
pExpr = sqlite3ExprSkipCollate(pExpr);
- assert( pExpr==0 || pExpr->op!=TK_REGISTER || pExpr->op2!=TK_VARIABLE );
+ assert( pExpr==0 || pExpr->op!=TK_REGISTER || pExpr->op2!=TK_VARIABLE );
if( !pExpr ){
pVal = valueNew(db, pAlloc);
if( pVal ){
sqlite3VdbeMemSetNull((Mem*)pVal);
}
- }else if( pExpr->op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
+ }else if( pExpr->op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
Vdbe *v;
int iBindVar = pExpr->iColumn;
sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
@@ -78958,7 +78958,7 @@ static int stat4ValueFromExpr(
pVal = valueNew(db, pAlloc);
if( pVal ){
rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
- sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
+ sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
pVal->db = pParse->db;
}
}
@@ -78976,9 +78976,9 @@ static int stat4ValueFromExpr(
** structures intended to be compared against sample index keys stored
** in the sqlite_stat4 table.
**
-** A single call to this function populates zero or more fields of the
-** record starting with field iVal (fields are numbered from left to
-** right starting with 0). A single field is populated if:
+** A single call to this function populates zero or more fields of the
+** record starting with field iVal (fields are numbered from left to
+** right starting with 0). A single field is populated if:
**
** * (pExpr==0). In this case the value is assumed to be an SQL NULL,
**
@@ -78987,15 +78987,15 @@ static int stat4ValueFromExpr(
** * The sqlite3ValueFromExpr() function is able to extract a value
** from the expression (i.e. the expression is a literal value).
**
-** Or, if pExpr is a TK_VECTOR, one field is populated for each of the
-** vector components that match either of the two latter criteria listed
-** above.
+** Or, if pExpr is a TK_VECTOR, one field is populated for each of the
+** vector components that match either of the two latter criteria listed
+** above.
**
** Before any value is appended to the record, the affinity of the
-** corresponding column within index pIdx is applied to it. Before
-** this function returns, output parameter *pnExtract is set to the
-** number of values appended to the record.
-**
+** corresponding column within index pIdx is applied to it. Before
+** this function returns, output parameter *pnExtract is set to the
+** number of values appended to the record.
+**
** When this function is called, *ppRec must either point to an object
** allocated by an earlier call to this function, or must be NULL. If it
** is NULL and a value can be successfully extracted, a new UnpackedRecord
@@ -79010,33 +79010,33 @@ SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(
Index *pIdx, /* Index being probed */
UnpackedRecord **ppRec, /* IN/OUT: Probe record */
Expr *pExpr, /* The expression to extract a value from */
- int nElem, /* Maximum number of values to append */
+ int nElem, /* Maximum number of values to append */
int iVal, /* Array element to populate */
- int *pnExtract /* OUT: Values appended to the record */
+ int *pnExtract /* OUT: Values appended to the record */
){
- int rc = SQLITE_OK;
- int nExtract = 0;
+ int rc = SQLITE_OK;
+ int nExtract = 0;
- if( pExpr==0 || pExpr->op!=TK_SELECT ){
- int i;
- struct ValueNewStat4Ctx alloc;
+ if( pExpr==0 || pExpr->op!=TK_SELECT ){
+ int i;
+ struct ValueNewStat4Ctx alloc;
+
+ alloc.pParse = pParse;
+ alloc.pIdx = pIdx;
+ alloc.ppRec = ppRec;
+
+ for(i=0; i<nElem; i++){
+ sqlite3_value *pVal = 0;
+ Expr *pElem = (pExpr ? sqlite3VectorFieldSubexpr(pExpr, i) : 0);
+ u8 aff = sqlite3IndexColumnAffinity(pParse->db, pIdx, iVal+i);
+ alloc.iVal = iVal+i;
+ rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal);
+ if( !pVal ) break;
+ nExtract++;
+ }
+ }
- alloc.pParse = pParse;
- alloc.pIdx = pIdx;
- alloc.ppRec = ppRec;
-
- for(i=0; i<nElem; i++){
- sqlite3_value *pVal = 0;
- Expr *pElem = (pExpr ? sqlite3VectorFieldSubexpr(pExpr, i) : 0);
- u8 aff = sqlite3IndexColumnAffinity(pParse->db, pIdx, iVal+i);
- alloc.iVal = iVal+i;
- rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal);
- if( !pVal ) break;
- nExtract++;
- }
- }
-
- *pnExtract = nExtract;
+ *pnExtract = nExtract;
return rc;
}
@@ -79100,7 +79100,7 @@ SQLITE_PRIVATE int sqlite3Stat4Column(
if( iField>nRec ) return SQLITE_CORRUPT_BKPT;
if( pMem==0 ){
pMem = *ppVal = sqlite3ValueNew(db);
- if( pMem==0 ) return SQLITE_NOMEM_BKPT;
+ if( pMem==0 ) return SQLITE_NOMEM_BKPT;
}
sqlite3VdbeSerialGet(&a[iField-szField], t, pMem);
pMem->enc = ENC(db);
@@ -79115,14 +79115,14 @@ SQLITE_PRIVATE int sqlite3Stat4Column(
SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
if( pRec ){
int i;
- int nCol = pRec->pKeyInfo->nAllField;
+ int nCol = pRec->pKeyInfo->nAllField;
Mem *aMem = pRec->aMem;
sqlite3 *db = aMem[0].db;
for(i=0; i<nCol; i++){
sqlite3VdbeMemRelease(&aMem[i]);
}
sqlite3KeyInfoUnref(pRec->pKeyInfo);
- sqlite3DbFreeNN(db, pRec);
+ sqlite3DbFreeNN(db, pRec);
}
}
#endif /* ifdef SQLITE_ENABLE_STAT4 */
@@ -79146,7 +79146,7 @@ SQLITE_PRIVATE void sqlite3ValueSetStr(
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){
if( !v ) return;
sqlite3VdbeMemRelease((Mem *)v);
- sqlite3DbFreeNN(((Mem*)v)->db, v);
+ sqlite3DbFreeNN(((Mem*)v)->db, v);
}
/*
@@ -79203,9 +79203,9 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int);
SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
sqlite3 *db = pParse->db;
Vdbe *p;
- p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) );
+ p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) );
if( p==0 ) return 0;
- memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp));
+ memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp));
p->db = db;
if( db->pVdbe ){
db->pVdbe->pPrev = p;
@@ -79215,12 +79215,12 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
db->pVdbe = p;
p->iVdbeMagic = VDBE_MAGIC_INIT;
p->pParse = pParse;
- pParse->pVdbe = p;
+ pParse->pVdbe = p;
assert( pParse->aLabel==0 );
assert( pParse->nLabel==0 );
assert( p->nOpAlloc==0 );
- assert( pParse->szOpAlloc==0 );
- sqlite3VdbeAddOp2(p, OP_Init, 0, 1);
+ assert( pParse->szOpAlloc==0 );
+ sqlite3VdbeAddOp2(p, OP_Init, 0, 1);
return p;
}
@@ -79245,12 +79245,12 @@ SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
/*
** Remember the SQL string for a prepared statement.
*/
-SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){
+SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){
if( p==0 ) return;
- p->prepFlags = prepFlags;
- if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){
- p->expmask = 0;
- }
+ p->prepFlags = prepFlags;
+ if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){
+ p->expmask = 0;
+ }
assert( p->zSql==0 );
p->zSql = sqlite3DbStrNDup(p->db, z, n);
}
@@ -79298,7 +79298,7 @@ SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(
SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
Vdbe tmp, *pTmp;
char *zTmp;
- assert( pA->db==pB->db );
+ assert( pA->db==pB->db );
tmp = *pA;
*pA = *pB;
*pB = tmp;
@@ -79316,10 +79316,10 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
pA->zNormSql = pB->zNormSql;
pB->zNormSql = zTmp;
#endif
- pB->expmask = pA->expmask;
- pB->prepFlags = pA->prepFlags;
- memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
- pB->aCounter[SQLITE_STMTSTATUS_REPREPARE]++;
+ pB->expmask = pA->expmask;
+ pB->prepFlags = pA->prepFlags;
+ memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
+ pB->aCounter[SQLITE_STMTSTATUS_REPREPARE]++;
}
/*
@@ -79352,21 +79352,21 @@ static int growOpArray(Vdbe *v, int nOp){
UNUSED_PARAMETER(nOp);
#endif
- /* Ensure that the size of a VDBE does not grow too large */
- if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
- sqlite3OomFault(p->db);
- return SQLITE_NOMEM;
- }
-
+ /* Ensure that the size of a VDBE does not grow too large */
+ if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
+ sqlite3OomFault(p->db);
+ return SQLITE_NOMEM;
+ }
+
assert( nOp<=(1024/sizeof(Op)) );
assert( nNew>=(v->nOpAlloc+nOp) );
pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
if( pNew ){
- p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
+ p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
v->nOpAlloc = p->szOpAlloc/sizeof(Op);
v->aOp = pNew;
}
- return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
+ return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
}
#ifdef SQLITE_DEBUG
@@ -79403,21 +79403,21 @@ static void test_addop_breakpoint(int pc, Op *pOp){
** the sqlite3VdbeChangeP4() function to change the value of the P4
** operand.
*/
-static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){
+static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){
assert( p->nOpAlloc<=p->nOp );
- if( growOpArray(p, 1) ) return 1;
+ if( growOpArray(p, 1) ) return 1;
assert( p->nOpAlloc>p->nOp );
- return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
-}
+ return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
+}
SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
int i;
VdbeOp *pOp;
i = p->nOp;
assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
- assert( op>=0 && op<0xff );
+ assert( op>=0 && op<0xff );
if( p->nOpAlloc<=i ){
- return growOp3(p, op, p1, p2, p3);
+ return growOp3(p, op, p1, p2, p3);
}
assert( p->aOp!=0 );
p->nOp++;
@@ -79458,51 +79458,51 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){
return sqlite3VdbeAddOp3(p, op, p1, p2, 0);
}
-/* Generate code for an unconditional jump to instruction iDest
-*/
-SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe *p, int iDest){
- return sqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0);
-}
-
-/* Generate code to cause the string zStr to be loaded into
-** register iDest
-*/
-SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){
- return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0);
-}
-
-/*
-** Generate code that initializes multiple registers to string or integer
-** constants. The registers begin with iDest and increase consecutively.
-** One register is initialized for each characgter in zTypes[]. For each
-** "s" character in zTypes[], the register is a string if the argument is
-** not NULL, or OP_Null if the value is a null pointer. For each "i" character
-** in zTypes[], the register is initialized to an integer.
-**
-** If the input string does not end with "X" then an OP_ResultRow instruction
-** is generated for the values inserted.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){
- va_list ap;
- int i;
- char c;
- va_start(ap, zTypes);
- for(i=0; (c = zTypes[i])!=0; i++){
- if( c=='s' ){
- const char *z = va_arg(ap, const char*);
- sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest+i, 0, z, 0);
- }else if( c=='i' ){
- sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest+i);
- }else{
- goto skip_op_resultrow;
- }
- }
- sqlite3VdbeAddOp2(p, OP_ResultRow, iDest, i);
-skip_op_resultrow:
- va_end(ap);
-}
-
-/*
+/* Generate code for an unconditional jump to instruction iDest
+*/
+SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe *p, int iDest){
+ return sqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0);
+}
+
+/* Generate code to cause the string zStr to be loaded into
+** register iDest
+*/
+SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){
+ return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0);
+}
+
+/*
+** Generate code that initializes multiple registers to string or integer
+** constants. The registers begin with iDest and increase consecutively.
+** One register is initialized for each characgter in zTypes[]. For each
+** "s" character in zTypes[], the register is a string if the argument is
+** not NULL, or OP_Null if the value is a null pointer. For each "i" character
+** in zTypes[], the register is initialized to an integer.
+**
+** If the input string does not end with "X" then an OP_ResultRow instruction
+** is generated for the values inserted.
+*/
+SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){
+ va_list ap;
+ int i;
+ char c;
+ va_start(ap, zTypes);
+ for(i=0; (c = zTypes[i])!=0; i++){
+ if( c=='s' ){
+ const char *z = va_arg(ap, const char*);
+ sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest+i, 0, z, 0);
+ }else if( c=='i' ){
+ sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest+i);
+ }else{
+ goto skip_op_resultrow;
+ }
+ }
+ sqlite3VdbeAddOp2(p, OP_ResultRow, iDest, i);
+skip_op_resultrow:
+ va_end(ap);
+}
+
+/*
** Add an opcode that includes the p4 value as a pointer.
*/
SQLITE_PRIVATE int sqlite3VdbeAddOp4(
@@ -79563,8 +79563,8 @@ SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall(
}
/*
-** Add an opcode that includes the p4 value with a P4_INT64 or
-** P4_REAL type.
+** Add an opcode that includes the p4 value with a P4_INT64 or
+** P4_REAL type.
*/
SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(
Vdbe *p, /* Add the opcode to this VM */
@@ -79575,7 +79575,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(
const u8 *zP4, /* The P4 operand */
int p4type /* P4 operand type */
){
- char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8);
+ char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8);
if( p4copy ) memcpy(p4copy, zP4, 8);
return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type);
}
@@ -79653,7 +79653,7 @@ SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){
*/
SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, u16 p5){
int j;
- sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
+ sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
sqlite3VdbeChangeP5(p, p5);
for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j);
sqlite3MayAbort(p->pParse);
@@ -79671,29 +79671,29 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(
int p4 /* The P4 operand as an integer */
){
int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3);
- if( p->db->mallocFailed==0 ){
- VdbeOp *pOp = &p->aOp[addr];
- pOp->p4type = P4_INT32;
- pOp->p4.i = p4;
- }
+ if( p->db->mallocFailed==0 ){
+ VdbeOp *pOp = &p->aOp[addr];
+ pOp->p4type = P4_INT32;
+ pOp->p4.i = p4;
+ }
return addr;
}
-/* Insert the end of a co-routine
-*/
-SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){
- sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
-
- /* Clear the temporary register cache, thereby ensuring that each
- ** co-routine has its own independent set of registers, because co-routines
- ** might expect their registers to be preserved across an OP_Yield, and
- ** that could cause problems if two or more co-routines are using the same
- ** temporary register.
- */
- v->pParse->nTempReg = 0;
- v->pParse->nRangeReg = 0;
-}
-
+/* Insert the end of a co-routine
+*/
+SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){
+ sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
+
+ /* Clear the temporary register cache, thereby ensuring that each
+ ** co-routine has its own independent set of registers, because co-routines
+ ** might expect their registers to be preserved across an OP_Yield, and
+ ** that could cause problems if two or more co-routines are using the same
+ ** temporary register.
+ */
+ v->pParse->nTempReg = 0;
+ v->pParse->nRangeReg = 0;
+}
+
/*
** Create a new symbolic label for an instruction that has yet to be
** coded. The symbolic label is really just a negative number. The
@@ -79745,10 +79745,10 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){
}
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
Parse *p = v->pParse;
- int j = ADDR(x);
+ int j = ADDR(x);
assert( v->iVdbeMagic==VDBE_MAGIC_INIT );
assert( j<-p->nLabel );
- assert( j>=0 );
+ assert( j>=0 );
#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
@@ -79769,13 +79769,13 @@ SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){
p->runOnlyOnce = 1;
}
-/*
-** Mark the VDBE as one that can only be run multiple times.
-*/
-SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){
- p->runOnlyOnce = 0;
-}
-
+/*
+** Mark the VDBE as one that can only be run multiple times.
+*/
+SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){
+ p->runOnlyOnce = 0;
+}
+
#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */
/*
@@ -79860,7 +79860,7 @@ static Op *opIterNext(VdbeOpIter *p){
** * OP_VRename
** * OP_FkCounter with P2==0 (immediate foreign key constraint)
** * OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine
-** (for CREATE TABLE AS SELECT ...)
+** (for CREATE TABLE AS SELECT ...)
**
** Then check that the value of Parse.mayAbort is true if an
** ABORT may be thrown, or false otherwise. Return true if it does
@@ -79892,7 +79892,7 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
hasAbort = 1;
break;
}
- if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
+ if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
if( mayAbort ){
/* hasCreateIndex may also be set for some DELETE statements that use
** OP_Clear. So this routine may end up returning true in the case
@@ -79948,25 +79948,25 @@ SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){
#endif
/*
-** This routine is called after all opcodes have been inserted. It loops
-** through all the opcodes and fixes up some details.
+** This routine is called after all opcodes have been inserted. It loops
+** through all the opcodes and fixes up some details.
+**
+** (1) For each jump instruction with a negative P2 value (a label)
+** resolve the P2 value to an actual address.
+**
+** (2) Compute the maximum number of arguments used by any SQL function
+** and store that value in *pMaxFuncArgs.
**
-** (1) For each jump instruction with a negative P2 value (a label)
-** resolve the P2 value to an actual address.
+** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
+** indicate what the prepared statement actually does.
**
-** (2) Compute the maximum number of arguments used by any SQL function
-** and store that value in *pMaxFuncArgs.
+** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
**
-** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
-** indicate what the prepared statement actually does.
-**
-** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
-**
-** (5) Reclaim the memory allocated for storing labels.
-**
-** This routine will only function correctly if the mkopcodeh.tcl generator
-** script numbers the opcodes correctly. Changes to this routine must be
-** coordinated with changes to mkopcodeh.tcl.
+** (5) Reclaim the memory allocated for storing labels.
+**
+** This routine will only function correctly if the mkopcodeh.tcl generator
+** script numbers the opcodes correctly. Changes to this routine must be
+** coordinated with changes to mkopcodeh.tcl.
*/
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
int nMaxArgs = *pMaxFuncArgs;
@@ -79975,90 +79975,90 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
int *aLabel = pParse->aLabel;
p->readOnly = 1;
p->bIsReader = 0;
- pOp = &p->aOp[p->nOp-1];
- while(1){
-
- /* Only JUMP opcodes and the short list of special opcodes in the switch
- ** below need to be considered. The mkopcodeh.tcl generator script groups
- ** all these opcodes together near the front of the opcode list. Skip
- ** any opcode that does not need processing by virtual of the fact that
- ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization.
- */
- if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){
- /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
- ** cases from this switch! */
- switch( pOp->opcode ){
- case OP_Transaction: {
- if( pOp->p2!=0 ) p->readOnly = 0;
+ pOp = &p->aOp[p->nOp-1];
+ while(1){
+
+ /* Only JUMP opcodes and the short list of special opcodes in the switch
+ ** below need to be considered. The mkopcodeh.tcl generator script groups
+ ** all these opcodes together near the front of the opcode list. Skip
+ ** any opcode that does not need processing by virtual of the fact that
+ ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization.
+ */
+ if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){
+ /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
+ ** cases from this switch! */
+ switch( pOp->opcode ){
+ case OP_Transaction: {
+ if( pOp->p2!=0 ) p->readOnly = 0;
/* no break */ deliberate_fall_through
- }
- case OP_AutoCommit:
- case OP_Savepoint: {
- p->bIsReader = 1;
- break;
- }
+ }
+ case OP_AutoCommit:
+ case OP_Savepoint: {
+ p->bIsReader = 1;
+ break;
+ }
#ifndef SQLITE_OMIT_WAL
- case OP_Checkpoint:
-#endif
- case OP_Vacuum:
- case OP_JournalMode: {
- p->readOnly = 0;
- p->bIsReader = 1;
- break;
- }
- case OP_Next:
- case OP_SorterNext: {
- pOp->p4.xAdvance = sqlite3BtreeNext;
- pOp->p4type = P4_ADVANCE;
- /* The code generator never codes any of these opcodes as a jump
+ case OP_Checkpoint:
+#endif
+ case OP_Vacuum:
+ case OP_JournalMode: {
+ p->readOnly = 0;
+ p->bIsReader = 1;
+ break;
+ }
+ case OP_Next:
+ case OP_SorterNext: {
+ pOp->p4.xAdvance = sqlite3BtreeNext;
+ pOp->p4type = P4_ADVANCE;
+ /* The code generator never codes any of these opcodes as a jump
** to a label. They are always coded as a jump backwards to a
- ** known address */
- assert( pOp->p2>=0 );
- break;
- }
+ ** known address */
+ assert( pOp->p2>=0 );
+ break;
+ }
case OP_Prev: {
- pOp->p4.xAdvance = sqlite3BtreePrevious;
- pOp->p4type = P4_ADVANCE;
- /* The code generator never codes any of these opcodes as a jump
+ pOp->p4.xAdvance = sqlite3BtreePrevious;
+ pOp->p4type = P4_ADVANCE;
+ /* The code generator never codes any of these opcodes as a jump
** to a label. They are always coded as a jump backwards to a
- ** known address */
- assert( pOp->p2>=0 );
- break;
- }
+ ** known address */
+ assert( pOp->p2>=0 );
+ break;
+ }
#ifndef SQLITE_OMIT_VIRTUALTABLE
- case OP_VUpdate: {
- if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
- break;
- }
- case OP_VFilter: {
- int n;
- assert( (pOp - p->aOp) >= 3 );
- assert( pOp[-1].opcode==OP_Integer );
- n = pOp[-1].p1;
- if( n>nMaxArgs ) nMaxArgs = n;
- /* Fall through into the default case */
+ case OP_VUpdate: {
+ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
+ break;
+ }
+ case OP_VFilter: {
+ int n;
+ assert( (pOp - p->aOp) >= 3 );
+ assert( pOp[-1].opcode==OP_Integer );
+ n = pOp[-1].p1;
+ if( n>nMaxArgs ) nMaxArgs = n;
+ /* Fall through into the default case */
/* no break */ deliberate_fall_through
- }
-#endif
- default: {
- if( pOp->p2<0 ){
- /* The mkopcodeh.tcl script has so arranged things that the only
- ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
- ** have non-negative values for P2. */
- assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 );
+ }
+#endif
+ default: {
+ if( pOp->p2<0 ){
+ /* The mkopcodeh.tcl script has so arranged things that the only
+ ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
+ ** have non-negative values for P2. */
+ assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 );
assert( ADDR(pOp->p2)<-pParse->nLabel );
- pOp->p2 = aLabel[ADDR(pOp->p2)];
- }
- break;
- }
+ pOp->p2 = aLabel[ADDR(pOp->p2)];
+ }
+ break;
+ }
}
- /* The mkopcodeh.tcl script has so arranged things that the only
- ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
- ** have non-negative values for P2. */
- assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0);
+ /* The mkopcodeh.tcl script has so arranged things that the only
+ ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
+ ** have non-negative values for P2. */
+ assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0);
}
- if( pOp==p->aOp ) break;
- pOp--;
+ if( pOp==p->aOp ) break;
+ pOp--;
}
sqlite3DbFree(p->db, pParse->aLabel);
pParse->aLabel = 0;
@@ -80076,36 +80076,36 @@ SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){
}
/*
-** Verify that at least N opcode slots are available in p without
-** having to malloc for more space (except when compiled using
-** SQLITE_TEST_REALLOC_STRESS). This interface is used during testing
-** to verify that certain calls to sqlite3VdbeAddOpList() can never
-** fail due to a OOM fault and hence that the return value from
-** sqlite3VdbeAddOpList() will always be non-NULL.
-*/
-#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
-SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){
+** Verify that at least N opcode slots are available in p without
+** having to malloc for more space (except when compiled using
+** SQLITE_TEST_REALLOC_STRESS). This interface is used during testing
+** to verify that certain calls to sqlite3VdbeAddOpList() can never
+** fail due to a OOM fault and hence that the return value from
+** sqlite3VdbeAddOpList() will always be non-NULL.
+*/
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
+SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){
assert( p->nOp + N <= p->nOpAlloc );
-}
-#endif
-
-/*
-** Verify that the VM passed as the only argument does not contain
-** an OP_ResultRow opcode. Fail an assert() if it does. This is used
-** by code in pragma.c to ensure that the implementation of certain
-** pragmas comports with the flags specified in the mkpragmatab.tcl
-** script.
-*/
-#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
-SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p){
- int i;
- for(i=0; i<p->nOp; i++){
- assert( p->aOp[i].opcode!=OP_ResultRow );
- }
-}
-#endif
-
-/*
+}
+#endif
+
+/*
+** Verify that the VM passed as the only argument does not contain
+** an OP_ResultRow opcode. Fail an assert() if it does. This is used
+** by code in pragma.c to ensure that the implementation of certain
+** pragmas comports with the flags specified in the mkpragmatab.tcl
+** script.
+*/
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
+SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p){
+ int i;
+ for(i=0; i<p->nOp; i++){
+ assert( p->aOp[i].opcode!=OP_ResultRow );
+ }
+}
+#endif
+
+/*
** Generate code (a single OP_Abortable opcode) that will
** verify that the VDBE program can safely call Abort in the current
** context.
@@ -80141,54 +80141,54 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg)
}
/*
-** Add a whole list of operations to the operation stack. Return a
-** pointer to the first operation inserted.
-**
-** Non-zero P2 arguments to jump instructions are automatically adjusted
-** so that the jump target is relative to the first operation inserted.
+** Add a whole list of operations to the operation stack. Return a
+** pointer to the first operation inserted.
+**
+** Non-zero P2 arguments to jump instructions are automatically adjusted
+** so that the jump target is relative to the first operation inserted.
*/
-SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(
- Vdbe *p, /* Add opcodes to the prepared statement */
- int nOp, /* Number of opcodes to add */
- VdbeOpList const *aOp, /* The opcodes to be added */
- int iLineno /* Source-file line number of first opcode */
-){
- int i;
- VdbeOp *pOut, *pFirst;
- assert( nOp>0 );
+SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(
+ Vdbe *p, /* Add opcodes to the prepared statement */
+ int nOp, /* Number of opcodes to add */
+ VdbeOpList const *aOp, /* The opcodes to be added */
+ int iLineno /* Source-file line number of first opcode */
+){
+ int i;
+ VdbeOp *pOut, *pFirst;
+ assert( nOp>0 );
assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
return 0;
}
- pFirst = pOut = &p->aOp[p->nOp];
- for(i=0; i<nOp; i++, aOp++, pOut++){
- pOut->opcode = aOp->opcode;
- pOut->p1 = aOp->p1;
- pOut->p2 = aOp->p2;
- assert( aOp->p2>=0 );
- if( (sqlite3OpcodeProperty[aOp->opcode] & OPFLG_JUMP)!=0 && aOp->p2>0 ){
- pOut->p2 += p->nOp;
- }
- pOut->p3 = aOp->p3;
- pOut->p4type = P4_NOTUSED;
- pOut->p4.p = 0;
- pOut->p5 = 0;
+ pFirst = pOut = &p->aOp[p->nOp];
+ for(i=0; i<nOp; i++, aOp++, pOut++){
+ pOut->opcode = aOp->opcode;
+ pOut->p1 = aOp->p1;
+ pOut->p2 = aOp->p2;
+ assert( aOp->p2>=0 );
+ if( (sqlite3OpcodeProperty[aOp->opcode] & OPFLG_JUMP)!=0 && aOp->p2>0 ){
+ pOut->p2 += p->nOp;
+ }
+ pOut->p3 = aOp->p3;
+ pOut->p4type = P4_NOTUSED;
+ pOut->p4.p = 0;
+ pOut->p5 = 0;
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
- pOut->zComment = 0;
+ pOut->zComment = 0;
#endif
#ifdef SQLITE_VDBE_COVERAGE
- pOut->iSrcLine = iLineno+i;
+ pOut->iSrcLine = iLineno+i;
#else
- (void)iLineno;
+ (void)iLineno;
#endif
#ifdef SQLITE_DEBUG
- if( p->db->flags & SQLITE_VdbeAddopTrace ){
- sqlite3VdbePrintOp(0, i+p->nOp, &p->aOp[i+p->nOp]);
- }
+ if( p->db->flags & SQLITE_VdbeAddopTrace ){
+ sqlite3VdbePrintOp(0, i+p->nOp, &p->aOp[i+p->nOp]);
+ }
#endif
}
- p->nOp += nOp;
- return pFirst;
+ p->nOp += nOp;
+ return pFirst;
}
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS)
@@ -80220,24 +80220,24 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus(
/*
-** Change the value of the opcode, or P1, P2, P3, or P5 operands
-** for a specific instruction.
+** Change the value of the opcode, or P1, P2, P3, or P5 operands
+** for a specific instruction.
*/
SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){
- sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode;
-}
+ sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode;
+}
SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
- sqlite3VdbeGetOp(p,addr)->p1 = val;
+ sqlite3VdbeGetOp(p,addr)->p1 = val;
}
SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
- sqlite3VdbeGetOp(p,addr)->p2 = val;
+ sqlite3VdbeGetOp(p,addr)->p2 = val;
}
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
- sqlite3VdbeGetOp(p,addr)->p3 = val;
+ sqlite3VdbeGetOp(p,addr)->p3 = val;
}
-SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){
- assert( p->nOp>0 || p->db->mallocFailed );
- if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5;
+SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){
+ assert( p->nOp>0 || p->db->mallocFailed );
+ if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5;
}
/*
@@ -80282,63 +80282,63 @@ SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){
** the FuncDef is not ephermal, then do nothing.
*/
static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
- if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
- sqlite3DbFreeNN(db, pDef);
+ if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
+ sqlite3DbFreeNN(db, pDef);
}
}
/*
** Delete a P4 value if necessary.
*/
-static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){
- if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
- sqlite3DbFreeNN(db, p);
-}
-static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){
- freeEphemeralFunction(db, p->pFunc);
+static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){
+ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
sqlite3DbFreeNN(db, p);
-}
+}
+static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){
+ freeEphemeralFunction(db, p->pFunc);
+ sqlite3DbFreeNN(db, p);
+}
static void freeP4(sqlite3 *db, int p4type, void *p4){
- assert( db );
- switch( p4type ){
- case P4_FUNCCTX: {
- freeP4FuncCtx(db, (sqlite3_context*)p4);
- break;
- }
- case P4_REAL:
- case P4_INT64:
- case P4_DYNAMIC:
- case P4_DYNBLOB:
- case P4_INTARRAY: {
- sqlite3DbFree(db, p4);
- break;
- }
- case P4_KEYINFO: {
- if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
- break;
- }
-#ifdef SQLITE_ENABLE_CURSOR_HINTS
- case P4_EXPR: {
- sqlite3ExprDelete(db, (Expr*)p4);
- break;
- }
-#endif
- case P4_FUNCDEF: {
- freeEphemeralFunction(db, (FuncDef*)p4);
- break;
- }
- case P4_MEM: {
- if( db->pnBytesFreed==0 ){
- sqlite3ValueFree((sqlite3_value*)p4);
- }else{
- freeP4Mem(db, (Mem*)p4);
- }
- break;
- }
- case P4_VTAB : {
- if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
- break;
- }
+ assert( db );
+ switch( p4type ){
+ case P4_FUNCCTX: {
+ freeP4FuncCtx(db, (sqlite3_context*)p4);
+ break;
+ }
+ case P4_REAL:
+ case P4_INT64:
+ case P4_DYNAMIC:
+ case P4_DYNBLOB:
+ case P4_INTARRAY: {
+ sqlite3DbFree(db, p4);
+ break;
+ }
+ case P4_KEYINFO: {
+ if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
+ break;
+ }
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+ case P4_EXPR: {
+ sqlite3ExprDelete(db, (Expr*)p4);
+ break;
+ }
+#endif
+ case P4_FUNCDEF: {
+ freeEphemeralFunction(db, (FuncDef*)p4);
+ break;
+ }
+ case P4_MEM: {
+ if( db->pnBytesFreed==0 ){
+ sqlite3ValueFree((sqlite3_value*)p4);
+ }else{
+ freeP4Mem(db, (Mem*)p4);
+ }
+ break;
+ }
+ case P4_VTAB : {
+ if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
+ break;
+ }
}
}
@@ -80350,13 +80350,13 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
if( aOp ){
Op *pOp;
- for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){
- if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p);
+ for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){
+ if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
sqlite3DbFree(db, pOp->zComment);
#endif
}
- sqlite3DbFreeNN(db, aOp);
+ sqlite3DbFreeNN(db, aOp);
}
}
@@ -80380,16 +80380,16 @@ SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe *pVdbe){
/*
** Change the opcode at addr into OP_Noop
*/
-SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
- VdbeOp *pOp;
- if( p->db->mallocFailed ) return 0;
- assert( addr>=0 && addr<p->nOp );
- pOp = &p->aOp[addr];
- freeP4(p->db, pOp->p4type, pOp->p4.p);
- pOp->p4type = P4_NOTUSED;
- pOp->p4.z = 0;
- pOp->opcode = OP_Noop;
- return 1;
+SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
+ VdbeOp *pOp;
+ if( p->db->mallocFailed ) return 0;
+ assert( addr>=0 && addr<p->nOp );
+ pOp = &p->aOp[addr];
+ freeP4(p->db, pOp->p4type, pOp->p4.p);
+ pOp->p4type = P4_NOTUSED;
+ pOp->p4.z = 0;
+ pOp->opcode = OP_Noop;
+ return 1;
}
/*
@@ -80397,8 +80397,8 @@ SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
** then remove it. Return true if and only if an opcode was removed.
*/
SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
- if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){
- return sqlite3VdbeChangeToNoop(p, p->nOp-1);
+ if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){
+ return sqlite3VdbeChangeToNoop(p, p->nOp-1);
}else{
return 0;
}
@@ -80456,34 +80456,34 @@ SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters(
**
** If addr<0 then change P4 on the most recently inserted instruction.
*/
-static void SQLITE_NOINLINE vdbeChangeP4Full(
- Vdbe *p,
- Op *pOp,
- const char *zP4,
- int n
-){
- if( pOp->p4type ){
- freeP4(p->db, pOp->p4type, pOp->p4.p);
- pOp->p4type = 0;
- pOp->p4.p = 0;
- }
- if( n<0 ){
- sqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n);
- }else{
- if( n==0 ) n = sqlite3Strlen30(zP4);
- pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
- pOp->p4type = P4_DYNAMIC;
- }
-}
+static void SQLITE_NOINLINE vdbeChangeP4Full(
+ Vdbe *p,
+ Op *pOp,
+ const char *zP4,
+ int n
+){
+ if( pOp->p4type ){
+ freeP4(p->db, pOp->p4type, pOp->p4.p);
+ pOp->p4type = 0;
+ pOp->p4.p = 0;
+ }
+ if( n<0 ){
+ sqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n);
+ }else{
+ if( n==0 ) n = sqlite3Strlen30(zP4);
+ pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
+ pOp->p4type = P4_DYNAMIC;
+ }
+}
SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
Op *pOp;
sqlite3 *db;
assert( p!=0 );
db = p->db;
assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
- assert( p->aOp!=0 || db->mallocFailed );
- if( db->mallocFailed ){
- if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4);
+ assert( p->aOp!=0 || db->mallocFailed );
+ if( db->mallocFailed ){
+ if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4);
return;
}
assert( p->nOp>0 );
@@ -80492,45 +80492,45 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
addr = p->nOp - 1;
}
pOp = &p->aOp[addr];
- if( n>=0 || pOp->p4type ){
- vdbeChangeP4Full(p, pOp, zP4, n);
- return;
- }
+ if( n>=0 || pOp->p4type ){
+ vdbeChangeP4Full(p, pOp, zP4, n);
+ return;
+ }
if( n==P4_INT32 ){
/* Note: this cast is safe, because the origin data point was an int
** that was cast to a (const char *). */
pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
pOp->p4type = P4_INT32;
- }else if( zP4!=0 ){
- assert( n<0 );
+ }else if( zP4!=0 ){
+ assert( n<0 );
pOp->p4.p = (void*)zP4;
pOp->p4type = (signed char)n;
- if( n==P4_VTAB ) sqlite3VtabLock((VTable*)zP4);
- }
-}
-
-/*
+ if( n==P4_VTAB ) sqlite3VtabLock((VTable*)zP4);
+ }
+}
+
+/*
** Change the P4 operand of the most recently coded instruction
-** to the value defined by the arguments. This is a high-speed
-** version of sqlite3VdbeChangeP4().
-**
-** The P4 operand must not have been previously defined. And the new
-** P4 must not be P4_INT32. Use sqlite3VdbeChangeP4() in either of
-** those cases.
-*/
-SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){
- VdbeOp *pOp;
- assert( n!=P4_INT32 && n!=P4_VTAB );
- assert( n<=0 );
- if( p->db->mallocFailed ){
- freeP4(p->db, n, pP4);
- }else{
- assert( pP4!=0 );
- assert( p->nOp>0 );
- pOp = &p->aOp[p->nOp-1];
- assert( pOp->p4type==P4_NOTUSED );
- pOp->p4type = n;
- pOp->p4.p = pP4;
+** to the value defined by the arguments. This is a high-speed
+** version of sqlite3VdbeChangeP4().
+**
+** The P4 operand must not have been previously defined. And the new
+** P4 must not be P4_INT32. Use sqlite3VdbeChangeP4() in either of
+** those cases.
+*/
+SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){
+ VdbeOp *pOp;
+ assert( n!=P4_INT32 && n!=P4_VTAB );
+ assert( n<=0 );
+ if( p->db->mallocFailed ){
+ freeP4(p->db, n, pP4);
+ }else{
+ assert( pP4!=0 );
+ assert( p->nOp>0 );
+ pOp = &p->aOp[p->nOp-1];
+ assert( pOp->p4type==P4_NOTUSED );
+ pOp->p4type = n;
+ pOp->p4.p = pP4;
}
}
@@ -80540,11 +80540,11 @@ SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){
*/
SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
Vdbe *v = pParse->pVdbe;
- KeyInfo *pKeyInfo;
+ KeyInfo *pKeyInfo;
assert( v!=0 );
assert( pIdx!=0 );
- pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pIdx);
- if( pKeyInfo ) sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
+ pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pIdx);
+ if( pKeyInfo ) sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
}
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
@@ -80656,7 +80656,7 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(
const char *zSynopsis;
int nOpName;
int ii;
- char zAlt[50];
+ char zAlt[50];
StrAccum x;
sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
@@ -80666,10 +80666,10 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(
int seenCom = 0;
char c;
zSynopsis = zOpName + nOpName + 1;
- if( strncmp(zSynopsis,"IF ",3)==0 ){
+ if( strncmp(zSynopsis,"IF ",3)==0 ){
sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3);
- zSynopsis = zAlt;
- }
+ zSynopsis = zAlt;
+ }
for(ii=0; (c = zSynopsis[ii])!=0; ii++){
if( c=='P' ){
c = zSynopsis[++ii];
@@ -80729,101 +80729,101 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(
}
#endif /* SQLITE_ENABLE_EXPLAIN_COMMENTS */
-#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
-/*
-** Translate the P4.pExpr value for an OP_CursorHint opcode into text
-** that can be displayed in the P4 column of EXPLAIN output.
-*/
-static void displayP4Expr(StrAccum *p, Expr *pExpr){
- const char *zOp = 0;
- switch( pExpr->op ){
- case TK_STRING:
+#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
+/*
+** Translate the P4.pExpr value for an OP_CursorHint opcode into text
+** that can be displayed in the P4 column of EXPLAIN output.
+*/
+static void displayP4Expr(StrAccum *p, Expr *pExpr){
+ const char *zOp = 0;
+ switch( pExpr->op ){
+ case TK_STRING:
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3_str_appendf(p, "%Q", pExpr->u.zToken);
- break;
- case TK_INTEGER:
+ break;
+ case TK_INTEGER:
sqlite3_str_appendf(p, "%d", pExpr->u.iValue);
- break;
- case TK_NULL:
+ break;
+ case TK_NULL:
sqlite3_str_appendf(p, "NULL");
- break;
- case TK_REGISTER: {
+ break;
+ case TK_REGISTER: {
sqlite3_str_appendf(p, "r[%d]", pExpr->iTable);
- break;
- }
- case TK_COLUMN: {
- if( pExpr->iColumn<0 ){
+ break;
+ }
+ case TK_COLUMN: {
+ if( pExpr->iColumn<0 ){
sqlite3_str_appendf(p, "rowid");
- }else{
+ }else{
sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn);
- }
- break;
- }
- case TK_LT: zOp = "LT"; break;
- case TK_LE: zOp = "LE"; break;
- case TK_GT: zOp = "GT"; break;
- case TK_GE: zOp = "GE"; break;
- case TK_NE: zOp = "NE"; break;
- case TK_EQ: zOp = "EQ"; break;
- case TK_IS: zOp = "IS"; break;
- case TK_ISNOT: zOp = "ISNOT"; break;
- case TK_AND: zOp = "AND"; break;
- case TK_OR: zOp = "OR"; break;
- case TK_PLUS: zOp = "ADD"; break;
- case TK_STAR: zOp = "MUL"; break;
- case TK_MINUS: zOp = "SUB"; break;
- case TK_REM: zOp = "REM"; break;
- case TK_BITAND: zOp = "BITAND"; break;
- case TK_BITOR: zOp = "BITOR"; break;
- case TK_SLASH: zOp = "DIV"; break;
- case TK_LSHIFT: zOp = "LSHIFT"; break;
- case TK_RSHIFT: zOp = "RSHIFT"; break;
- case TK_CONCAT: zOp = "CONCAT"; break;
- case TK_UMINUS: zOp = "MINUS"; break;
- case TK_UPLUS: zOp = "PLUS"; break;
- case TK_BITNOT: zOp = "BITNOT"; break;
- case TK_NOT: zOp = "NOT"; break;
- case TK_ISNULL: zOp = "ISNULL"; break;
- case TK_NOTNULL: zOp = "NOTNULL"; break;
-
- default:
+ }
+ break;
+ }
+ case TK_LT: zOp = "LT"; break;
+ case TK_LE: zOp = "LE"; break;
+ case TK_GT: zOp = "GT"; break;
+ case TK_GE: zOp = "GE"; break;
+ case TK_NE: zOp = "NE"; break;
+ case TK_EQ: zOp = "EQ"; break;
+ case TK_IS: zOp = "IS"; break;
+ case TK_ISNOT: zOp = "ISNOT"; break;
+ case TK_AND: zOp = "AND"; break;
+ case TK_OR: zOp = "OR"; break;
+ case TK_PLUS: zOp = "ADD"; break;
+ case TK_STAR: zOp = "MUL"; break;
+ case TK_MINUS: zOp = "SUB"; break;
+ case TK_REM: zOp = "REM"; break;
+ case TK_BITAND: zOp = "BITAND"; break;
+ case TK_BITOR: zOp = "BITOR"; break;
+ case TK_SLASH: zOp = "DIV"; break;
+ case TK_LSHIFT: zOp = "LSHIFT"; break;
+ case TK_RSHIFT: zOp = "RSHIFT"; break;
+ case TK_CONCAT: zOp = "CONCAT"; break;
+ case TK_UMINUS: zOp = "MINUS"; break;
+ case TK_UPLUS: zOp = "PLUS"; break;
+ case TK_BITNOT: zOp = "BITNOT"; break;
+ case TK_NOT: zOp = "NOT"; break;
+ case TK_ISNULL: zOp = "ISNULL"; break;
+ case TK_NOTNULL: zOp = "NOTNULL"; break;
+
+ default:
sqlite3_str_appendf(p, "%s", "expr");
- break;
- }
-
- if( zOp ){
+ break;
+ }
+
+ if( zOp ){
sqlite3_str_appendf(p, "%s(", zOp);
- displayP4Expr(p, pExpr->pLeft);
- if( pExpr->pRight ){
+ displayP4Expr(p, pExpr->pLeft);
+ if( pExpr->pRight ){
sqlite3_str_append(p, ",", 1);
- displayP4Expr(p, pExpr->pRight);
- }
+ displayP4Expr(p, pExpr->pRight);
+ }
sqlite3_str_append(p, ")", 1);
- }
-}
-#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
-
-
-#if VDBE_DISPLAY_P4
+ }
+}
+#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
+
+
+#if VDBE_DISPLAY_P4
/*
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
char *zP4 = 0;
- StrAccum x;
+ StrAccum x;
sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
switch( pOp->p4type ){
case P4_KEYINFO: {
- int j;
+ int j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->aSortFlags!=0 );
sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField);
- for(j=0; j<pKeyInfo->nKeyField; j++){
+ for(j=0; j<pKeyInfo->nKeyField; j++){
CollSeq *pColl = pKeyInfo->aColl[j];
- const char *zColl = pColl ? pColl->zName : "";
- if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
+ const char *zColl = pColl ? pColl->zName : "";
+ if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
sqlite3_str_appendf(&x, ",%s%s%s",
(pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_DESC) ? "-" : "",
(pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_BIGNULL)? "N." : "",
@@ -80832,12 +80832,12 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
sqlite3_str_append(&x, ")", 1);
break;
}
-#ifdef SQLITE_ENABLE_CURSOR_HINTS
- case P4_EXPR: {
- displayP4Expr(&x, pOp->p4.pExpr);
- break;
- }
-#endif
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+ case P4_EXPR: {
+ displayP4Expr(&x, pOp->p4.pExpr);
+ break;
+ }
+#endif
case P4_COLLSEQ: {
static const char *const encnames[] = {"?", "8", "16LE", "16BE"};
CollSeq *pColl = pOp->p4.pColl;
@@ -80877,7 +80877,7 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
}else if( pMem->flags & MEM_Real ){
sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
}else if( pMem->flags & MEM_Null ){
- zP4 = "NULL";
+ zP4 = "NULL";
}else{
assert( pMem->flags & MEM_Blob );
zP4 = "(blob)";
@@ -80895,10 +80895,10 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
u32 i;
u32 *ai = pOp->p4.ai;
u32 n = ai[0]; /* The first element of an INTARRAY is always the
- ** count of the number of elements to follow */
- for(i=1; i<=n; i++){
+ ** count of the number of elements to follow */
+ for(i=1; i<=n; i++){
sqlite3_str_appendf(&x, "%c%u", (i==1 ? '[' : ','), ai[i]);
- }
+ }
sqlite3_str_append(&x, "]", 1);
break;
}
@@ -80906,14 +80906,14 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
zP4 = "program";
break;
}
- case P4_DYNBLOB:
+ case P4_DYNBLOB:
case P4_ADVANCE: {
break;
}
- case P4_TABLE: {
+ case P4_TABLE: {
zP4 = pOp->p4.pTab->zName;
- break;
- }
+ break;
+ }
default: {
zP4 = pOp->p4.z;
}
@@ -80924,7 +80924,7 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
}
return sqlite3StrAccumFinish(&x);
}
-#endif /* VDBE_DISPLAY_P4 */
+#endif /* VDBE_DISPLAY_P4 */
/*
** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
@@ -80943,7 +80943,7 @@ SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){
}
}
-#if !defined(SQLITE_OMIT_SHARED_CACHE)
+#if !defined(SQLITE_OMIT_SHARED_CACHE)
/*
** If SQLite is compiled to support shared-cache mode and to be threadsafe,
** this routine obtains the mutex associated with each BtShared structure
@@ -81040,21 +81040,21 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
#endif
/*
-** Initialize an array of N Mem element.
-*/
-static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
- while( (N--)>0 ){
- p->db = db;
- p->flags = flags;
- p->szMalloc = 0;
-#ifdef SQLITE_DEBUG
- p->pScopyFrom = 0;
-#endif
- p++;
- }
-}
-
-/*
+** Initialize an array of N Mem element.
+*/
+static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
+ while( (N--)>0 ){
+ p->db = db;
+ p->flags = flags;
+ p->szMalloc = 0;
+#ifdef SQLITE_DEBUG
+ p->pScopyFrom = 0;
+#endif
+ p++;
+ }
+}
+
+/*
** Release an array of N Mem elements
*/
static void releaseMemArray(Mem *p, int N){
@@ -81089,7 +81089,7 @@ static void releaseMemArray(Mem *p, int N){
testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel );
sqlite3VdbeMemRelease(p);
}else if( p->szMalloc ){
- sqlite3DbFreeNN(db, p->zMalloc);
+ sqlite3DbFreeNN(db, p->zMalloc);
p->szMalloc = 0;
}
@@ -81255,7 +81255,7 @@ SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
sqlite3VdbeFreeCursor(p->v, apCsr[i]);
}
releaseMemArray(aMem, p->nChildMem);
- sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
+ sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
sqlite3DbFree(p->v->db, p);
}
@@ -81286,7 +81286,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
int i; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
Mem *pMem = &p->aMem[1]; /* First Mem of result set */
- int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
+ int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
Op *aOp; /* Array of opcodes */
Op *pOp; /* Current opcode */
@@ -81304,11 +81304,11 @@ SQLITE_PRIVATE int sqlite3VdbeList(
if( p->rc==SQLITE_NOMEM ){
/* This happens if a malloc() inside a call to sqlite3_column_text() or
** sqlite3_column_text16() failed. */
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
return SQLITE_ERROR;
}
- if( bListSubprogs ){
+ if( bListSubprogs ){
/* The first 8 memory cells are used for the result set. So we will
** commandeer the 9th cell to use as storage for an array of pointers
** to trigger subprograms. The VDBE is guaranteed to have at least 9
@@ -81322,13 +81322,13 @@ SQLITE_PRIVATE int sqlite3VdbeList(
/* Figure out which opcode is next to display */
rc = sqlite3VdbeNextOpcode(p, pSub, p->explain==2, &p->pc, &i, &aOp);
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
pOp = aOp + i;
if( AtomicLoad(&db->u1.isInterrupted) ){
- p->rc = SQLITE_INTERRUPT;
- rc = SQLITE_ERROR;
- sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
- }else{
+ p->rc = SQLITE_INTERRUPT;
+ rc = SQLITE_ERROR;
+ sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
+ }else{
char *zP4 = sqlite3VdbeDisplayP4(db, pOp);
if( p->explain==2 ){
sqlite3VdbeMemSetInt64(pMem, pOp->p1);
@@ -81336,7 +81336,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);
p->nResColumn = 4;
- }else{
+ }else{
sqlite3VdbeMemSetInt64(pMem+0, i);
sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
-1, SQLITE_UTF8, SQLITE_STATIC);
@@ -81349,13 +81349,13 @@ SQLITE_PRIVATE int sqlite3VdbeList(
{
char *zCom = sqlite3VdbeDisplayComment(db, pOp, zP4);
sqlite3VdbeMemSetStr(pMem+7, zCom, -1, SQLITE_UTF8, sqlite3_free);
- }
+ }
#else
sqlite3VdbeMemSetNull(pMem+7);
#endif
sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
p->nResColumn = 8;
- }
+ }
p->pResultSet = pMem;
if( db->mallocFailed ){
p->rc = SQLITE_NOMEM;
@@ -81419,46 +81419,46 @@ SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){
}
#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
-/* An instance of this object describes bulk memory available for use
-** by subcomponents of a prepared statement. Space is allocated out
-** of a ReusableSpace object by the allocSpace() routine below.
-*/
-struct ReusableSpace {
+/* An instance of this object describes bulk memory available for use
+** by subcomponents of a prepared statement. Space is allocated out
+** of a ReusableSpace object by the allocSpace() routine below.
+*/
+struct ReusableSpace {
u8 *pSpace; /* Available memory */
sqlite3_int64 nFree; /* Bytes of available memory */
sqlite3_int64 nNeeded; /* Total bytes that could not be allocated */
-};
-
-/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
-** from the ReusableSpace object. Return a pointer to the allocated
-** memory on success. If insufficient memory is available in the
-** ReusableSpace object, increase the ReusableSpace.nNeeded
-** value by the amount needed and return NULL.
-**
-** If pBuf is not initially NULL, that means that the memory has already
-** been allocated by a prior call to this routine, so just return a copy
-** of pBuf and leave ReusableSpace unchanged.
-**
-** This allocator is employed to repurpose unused slots at the end of the
-** opcode array of prepared state for other memory needs of the prepared
-** statement.
+};
+
+/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
+** from the ReusableSpace object. Return a pointer to the allocated
+** memory on success. If insufficient memory is available in the
+** ReusableSpace object, increase the ReusableSpace.nNeeded
+** value by the amount needed and return NULL.
+**
+** If pBuf is not initially NULL, that means that the memory has already
+** been allocated by a prior call to this routine, so just return a copy
+** of pBuf and leave ReusableSpace unchanged.
+**
+** This allocator is employed to repurpose unused slots at the end of the
+** opcode array of prepared state for other memory needs of the prepared
+** statement.
*/
static void *allocSpace(
- struct ReusableSpace *p, /* Bulk memory available for allocation */
- void *pBuf, /* Pointer to a prior allocation */
+ struct ReusableSpace *p, /* Bulk memory available for allocation */
+ void *pBuf, /* Pointer to a prior allocation */
sqlite3_int64 nByte /* Bytes of memory needed */
){
- assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
- if( pBuf==0 ){
- nByte = ROUND8(nByte);
- if( nByte <= p->nFree ){
- p->nFree -= nByte;
- pBuf = &p->pSpace[p->nFree];
- }else{
- p->nNeeded += nByte;
- }
- }
- assert( EIGHT_BYTE_ALIGNMENT(pBuf) );
+ assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
+ if( pBuf==0 ){
+ nByte = ROUND8(nByte);
+ if( nByte <= p->nFree ){
+ p->nFree -= nByte;
+ pBuf = &p->pSpace[p->nFree];
+ }else{
+ p->nNeeded += nByte;
+ }
+ }
+ assert( EIGHT_BYTE_ALIGNMENT(pBuf) );
return pBuf;
}
@@ -81481,7 +81481,7 @@ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
p->iVdbeMagic = VDBE_MAGIC_RUN;
#ifdef SQLITE_DEBUG
- for(i=0; i<p->nMem; i++){
+ for(i=0; i<p->nMem; i++){
assert( p->aMem[i].db==p->db );
}
#endif
@@ -81529,7 +81529,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
int nCursor; /* Number of cursors required */
int nArg; /* Number of arguments in subprograms */
int n; /* Loop counter */
- struct ReusableSpace x; /* Reusable bulk memory */
+ struct ReusableSpace x; /* Reusable bulk memory */
assert( p!=0 );
assert( p->nOp>0 );
@@ -81545,24 +81545,24 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
nCursor = pParse->nTab;
nArg = pParse->nMaxArg;
- /* Each cursor uses a memory cell. The first cursor (cursor 0) can
- ** use aMem[0] which is not otherwise used by the VDBE program. Allocate
- ** space at the end of aMem[] for cursors 1 and greater.
+ /* Each cursor uses a memory cell. The first cursor (cursor 0) can
+ ** use aMem[0] which is not otherwise used by the VDBE program. Allocate
+ ** space at the end of aMem[] for cursors 1 and greater.
** See also: allocateCursor().
*/
nMem += nCursor;
- if( nCursor==0 && nMem>0 ) nMem++; /* Space for aMem[0] even if not used */
+ if( nCursor==0 && nMem>0 ) nMem++; /* Space for aMem[0] even if not used */
- /* Figure out how much reusable memory is available at the end of the
- ** opcode array. This extra memory will be reallocated for other elements
- ** of the prepared statement.
+ /* Figure out how much reusable memory is available at the end of the
+ ** opcode array. This extra memory will be reallocated for other elements
+ ** of the prepared statement.
*/
- n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
- x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */
- assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
- x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
- assert( x.nFree>=0 );
- assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
+ n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
+ x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */
+ assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
+ x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
+ assert( x.nFree>=0 );
+ assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
resolveP2Values(p, &nArg);
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
@@ -81590,14 +81590,14 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
}
p->expired = 0;
- /* Memory for registers, parameters, cursor, etc, is allocated in one or two
+ /* Memory for registers, parameters, cursor, etc, is allocated in one or two
** passes. On the first pass, we try to reuse unused memory at the
** end of the opcode array. If we are unable to satisfy all memory
** requirements by reusing the opcode array tail, then the second
** pass will fill in the remainder using a fresh memory allocation.
**
** This two-pass approach that reuses as much memory as possible from
- ** the leftover memory at the end of the opcode array. This can significantly
+ ** the leftover memory at the end of the opcode array. This can significantly
** reduce the amount of memory held by a prepared statement.
*/
x.nNeeded = 0;
@@ -81609,8 +81609,8 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64));
#endif
if( x.nNeeded ){
- x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
- x.nFree = x.nNeeded;
+ x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
+ x.nFree = x.nNeeded;
if( !db->mallocFailed ){
p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
@@ -81622,20 +81622,20 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
}
}
- if( db->mallocFailed ){
- p->nVar = 0;
- p->nCursor = 0;
- p->nMem = 0;
- }else{
- p->nCursor = nCursor;
+ if( db->mallocFailed ){
+ p->nVar = 0;
+ p->nCursor = 0;
+ p->nMem = 0;
+ }else{
+ p->nCursor = nCursor;
p->nVar = (ynVar)nVar;
- initMemArray(p->aVar, nVar, db, MEM_Null);
- p->nMem = nMem;
- initMemArray(p->aMem, nMem, db, MEM_Undefined);
- memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*));
-#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
- memset(p->anExec, 0, p->nOp*sizeof(i64));
-#endif
+ initMemArray(p->aVar, nVar, db, MEM_Null);
+ p->nMem = nMem;
+ initMemArray(p->aMem, nMem, db, MEM_Undefined);
+ memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*));
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ memset(p->anExec, 0, p->nOp*sizeof(i64));
+#endif
}
sqlite3VdbeRewind(p);
}
@@ -81648,28 +81648,28 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
if( pCx==0 ){
return;
}
- assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE );
+ assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE );
assert( pCx->pBtx==0 || pCx->isEphemeral );
- switch( pCx->eCurType ){
- case CURTYPE_SORTER: {
- sqlite3VdbeSorterClose(p->db, pCx);
- break;
- }
- case CURTYPE_BTREE: {
+ switch( pCx->eCurType ){
+ case CURTYPE_SORTER: {
+ sqlite3VdbeSorterClose(p->db, pCx);
+ break;
+ }
+ case CURTYPE_BTREE: {
assert( pCx->uc.pCursor!=0 );
sqlite3BtreeCloseCursor(pCx->uc.pCursor);
- break;
- }
+ break;
+ }
#ifndef SQLITE_OMIT_VIRTUALTABLE
- case CURTYPE_VTAB: {
- sqlite3_vtab_cursor *pVCur = pCx->uc.pVCur;
- const sqlite3_module *pModule = pVCur->pVtab->pModule;
- assert( pVCur->pVtab->nRef>0 );
- pVCur->pVtab->nRef--;
- pModule->xClose(pVCur);
- break;
- }
-#endif
+ case CURTYPE_VTAB: {
+ sqlite3_vtab_cursor *pVCur = pCx->uc.pVCur;
+ const sqlite3_module *pModule = pVCur->pVtab->pModule;
+ assert( pVCur->pVtab->nRef>0 );
+ pVCur->pVtab->nRef--;
+ pModule->xClose(pVCur);
+ break;
+ }
+#endif
}
}
@@ -81709,9 +81709,9 @@ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
v->db->lastRowid = pFrame->lastRowid;
v->nChange = pFrame->nChange;
v->db->nChange = pFrame->nDbChange;
- sqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0);
- v->pAuxData = pFrame->pAuxData;
- pFrame->pAuxData = 0;
+ sqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0);
+ v->pAuxData = pFrame->pAuxData;
+ pFrame->pAuxData = 0;
return pFrame->pc;
}
@@ -81734,7 +81734,7 @@ static void closeAllCursors(Vdbe *p){
assert( p->nFrame==0 );
closeCursorsInFrame(p);
if( p->aMem ){
- releaseMemArray(p->aMem, p->nMem);
+ releaseMemArray(p->aMem, p->nMem);
}
while( p->pDelFrame ){
VdbeFrame *pDel = p->pDelFrame;
@@ -81743,7 +81743,7 @@ static void closeAllCursors(Vdbe *p){
}
/* Delete any auxdata allocations made by the VM */
- if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0);
+ if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0);
assert( p->pAuxData==0 );
}
@@ -81757,15 +81757,15 @@ SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
int n;
sqlite3 *db = p->db;
- if( p->nResColumn ){
- releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
- sqlite3DbFree(db, p->aColName);
- }
+ if( p->nResColumn ){
+ releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
+ sqlite3DbFree(db, p->aColName);
+ }
n = nResColumn*COLNAME_N;
p->nResColumn = (u16)nResColumn;
- p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
+ p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
if( p->aColName==0 ) return;
- initMemArray(p->aColName, n, db, MEM_Null);
+ initMemArray(p->aColName, n, db, MEM_Null);
}
/*
@@ -81791,7 +81791,7 @@ SQLITE_PRIVATE int sqlite3VdbeSetColName(
assert( var<COLNAME_N );
if( p->db->mallocFailed ){
assert( !zName || xDel!=SQLITE_DYNAMIC );
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
assert( p->aColName!=0 );
pColName = &(p->aColName[idx+var*p->nResColumn]);
@@ -81808,8 +81808,8 @@ SQLITE_PRIVATE int sqlite3VdbeSetColName(
*/
static int vdbeCommit(sqlite3 *db, Vdbe *p){
int i;
- int nTrans = 0; /* Number of databases with an active write-transaction
- ** that are candidates for a two-phase commit using a
+ int nTrans = 0; /* Number of databases with an active write-transaction
+ ** that are candidates for a two-phase commit using a
** super-journal */
int rc = SQLITE_OK;
int needXcommit = 0;
@@ -81839,28 +81839,28 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
Btree *pBt = db->aDb[i].pBt;
if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){
/* Whether or not a database might need a super-journal depends upon
- ** its journal mode (among other things). This matrix determines which
+ ** its journal mode (among other things). This matrix determines which
** journal modes use a super-journal and which do not */
- static const u8 aMJNeeded[] = {
- /* DELETE */ 1,
- /* PERSIST */ 1,
- /* OFF */ 0,
- /* TRUNCATE */ 1,
- /* MEMORY */ 0,
- /* WAL */ 0
- };
- Pager *pPager; /* Pager associated with pBt */
+ static const u8 aMJNeeded[] = {
+ /* DELETE */ 1,
+ /* PERSIST */ 1,
+ /* OFF */ 0,
+ /* TRUNCATE */ 1,
+ /* MEMORY */ 0,
+ /* WAL */ 0
+ };
+ Pager *pPager; /* Pager associated with pBt */
needXcommit = 1;
sqlite3BtreeEnter(pBt);
- pPager = sqlite3BtreePager(pBt);
- if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
- && aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
- && sqlite3PagerIsMemdb(pPager)==0
+ pPager = sqlite3BtreePager(pBt);
+ if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
+ && aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
+ && sqlite3PagerIsMemdb(pPager)==0
){
- assert( i!=1 );
- nTrans++;
- }
- rc = sqlite3PagerExclusiveLock(pPager);
+ assert( i!=1 );
+ nTrans++;
+ }
+ rc = sqlite3PagerExclusiveLock(pPager);
sqlite3BtreeLeave(pBt);
}
}
@@ -82102,60 +82102,60 @@ static void checkActiveVdbeCnt(sqlite3 *db){
** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned.
** Otherwise SQLITE_OK.
*/
-static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){
+static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){
sqlite3 *const db = p->db;
int rc = SQLITE_OK;
- int i;
- const int iSavepoint = p->iStatement-1;
+ int i;
+ const int iSavepoint = p->iStatement-1;
- assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
- assert( db->nStatement>0 );
- assert( p->iStatement==(db->nStatement+db->nSavepoint) );
+ assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
+ assert( db->nStatement>0 );
+ assert( p->iStatement==(db->nStatement+db->nSavepoint) );
for(i=0; i<db->nDb; i++){
- int rc2 = SQLITE_OK;
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
+ int rc2 = SQLITE_OK;
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ){
if( eOp==SAVEPOINT_ROLLBACK ){
- rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint);
+ rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint);
+ }
+ if( rc2==SQLITE_OK ){
+ rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint);
}
- if( rc2==SQLITE_OK ){
- rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint);
- }
if( rc==SQLITE_OK ){
- rc = rc2;
+ rc = rc2;
}
}
- }
- db->nStatement--;
- p->iStatement = 0;
+ }
+ db->nStatement--;
+ p->iStatement = 0;
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
if( eOp==SAVEPOINT_ROLLBACK ){
- rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint);
+ rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint);
}
- if( rc==SQLITE_OK ){
- rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint);
- }
}
-
+
/* If the statement transaction is being rolled back, also restore the
** database handles deferred constraint counter to the value it had when
- ** the statement transaction was opened. */
- if( eOp==SAVEPOINT_ROLLBACK ){
- db->nDeferredCons = p->nStmtDefCons;
- db->nDeferredImmCons = p->nStmtDefImmCons;
- }
+ ** the statement transaction was opened. */
+ if( eOp==SAVEPOINT_ROLLBACK ){
+ db->nDeferredCons = p->nStmtDefCons;
+ db->nDeferredImmCons = p->nStmtDefImmCons;
+ }
return rc;
}
-SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
- if( p->db->nStatement && p->iStatement ){
- return vdbeCloseStatement(p, eOp);
- }
- return SQLITE_OK;
-}
+SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
+ if( p->db->nStatement && p->iStatement ){
+ return vdbeCloseStatement(p, eOp);
+ }
+ return SQLITE_OK;
+}
+
-
/*
** This function is called when a transaction opened by the database
** handle associated with the VM passed as an argument is about to be
@@ -82217,10 +82217,10 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
return SQLITE_OK;
}
- if( db->mallocFailed ){
- p->rc = SQLITE_NOMEM_BKPT;
- }
- closeAllCursors(p);
+ if( db->mallocFailed ){
+ p->rc = SQLITE_NOMEM_BKPT;
+ }
+ closeAllCursors(p);
checkActiveVdbeCnt(db);
/* No commit or rollback needed if the program never started or if the
@@ -82383,8 +82383,8 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
}
p->iVdbeMagic = VDBE_MAGIC_HALT;
checkActiveVdbeCnt(db);
- if( db->mallocFailed ){
- p->rc = SQLITE_NOMEM_BKPT;
+ if( db->mallocFailed ){
+ p->rc = SQLITE_NOMEM_BKPT;
}
/* If the auto-commit flag is set to true, then any locks that were held
@@ -82420,16 +82420,16 @@ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){
sqlite3 *db = p->db;
int rc = p->rc;
if( p->zErrMsg ){
- db->bBenignMalloc++;
+ db->bBenignMalloc++;
sqlite3BeginBenignMalloc();
if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db);
sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
sqlite3EndBenignMalloc();
- db->bBenignMalloc--;
- }else if( db->pErr ){
- sqlite3ValueSetNull(db->pErr);
+ db->bBenignMalloc--;
+ }else if( db->pErr ){
+ sqlite3ValueSetNull(db->pErr);
}
- db->errCode = rc;
+ db->errCode = rc;
return rc;
}
@@ -82466,10 +82466,10 @@ static void vdbeInvokeSqllog(Vdbe *v){
** VDBE_MAGIC_INIT.
*/
SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
-#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
- int i;
-#endif
-
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+ int i;
+#endif
+
sqlite3 *db;
db = p->db;
@@ -82500,21 +82500,21 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
}
- /* Reset register contents and reclaim error message memory.
+ /* Reset register contents and reclaim error message memory.
*/
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/* Execute assert() statements to ensure that the Vdbe.apCsr[] and
- ** Vdbe.aMem[] arrays have already been cleaned up. */
- if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
- if( p->aMem ){
- for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
- }
-#endif
+ ** Vdbe.aMem[] arrays have already been cleaned up. */
+ if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
+ if( p->aMem ){
+ for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
+ }
+#endif
if( p->zErrMsg ){
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
}
- p->pResultSet = 0;
+ p->pResultSet = 0;
#ifdef SQLITE_DEBUG
p->nWrite = 0;
#endif
@@ -82588,22 +82588,22 @@ SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
** * the corresponding bit in argument mask is clear (where the first
** function parameter corresponds to bit 0 etc.).
*/
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
while( *pp ){
AuxData *pAux = *pp;
if( (iOp<0)
- || (pAux->iAuxOp==iOp
- && pAux->iAuxArg>=0
- && (pAux->iAuxArg>31 || !(mask & MASKBIT32(pAux->iAuxArg))))
+ || (pAux->iAuxOp==iOp
+ && pAux->iAuxArg>=0
+ && (pAux->iAuxArg>31 || !(mask & MASKBIT32(pAux->iAuxArg))))
){
- testcase( pAux->iAuxArg==31 );
- if( pAux->xDeleteAux ){
- pAux->xDeleteAux(pAux->pAux);
+ testcase( pAux->iAuxArg==31 );
+ if( pAux->xDeleteAux ){
+ pAux->xDeleteAux(pAux->pAux);
}
- *pp = pAux->pNextAux;
- sqlite3DbFree(db, pAux);
+ *pp = pAux->pNextAux;
+ sqlite3DbFree(db, pAux);
}else{
- pp= &pAux->pNextAux;
+ pp= &pAux->pNextAux;
}
}
}
@@ -82626,10 +82626,10 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
sqlite3DbFree(db, pSub);
}
if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){
- releaseMemArray(p->aVar, p->nVar);
- sqlite3DbFree(db, p->pVList);
- sqlite3DbFree(db, p->pFree);
- }
+ releaseMemArray(p->aVar, p->nVar);
+ sqlite3DbFree(db, p->pVList);
+ sqlite3DbFree(db, p->pFree);
+ }
vdbeFreeOpArray(db, p->aOp, p->nOp);
sqlite3DbFree(db, p->aColName);
sqlite3DbFree(db, p->zSql);
@@ -82644,12 +82644,12 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
}
#endif
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
- {
- int i;
- for(i=0; i<p->nScan; i++){
- sqlite3DbFree(db, p->aScan[i].zName);
- }
- sqlite3DbFree(db, p->aScan);
+ {
+ int i;
+ for(i=0; i<p->nScan; i++){
+ sqlite3DbFree(db, p->aScan[i].zName);
+ }
+ sqlite3DbFree(db, p->aScan);
}
#endif
}
@@ -82660,7 +82660,7 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
sqlite3 *db;
- assert( p!=0 );
+ assert( p!=0 );
db = p->db;
assert( sqlite3_mutex_held(db->mutex) );
sqlite3VdbeClearObject(db, p);
@@ -82675,7 +82675,7 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
}
p->iVdbeMagic = VDBE_MAGIC_DEAD;
p->db = 0;
- sqlite3DbFreeNN(db, p);
+ sqlite3DbFreeNN(db, p);
}
/*
@@ -82690,7 +82690,7 @@ SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor *p){
#endif
assert( p->deferredMoveto );
assert( p->isTable );
- assert( p->eCurType==CURTYPE_BTREE );
+ assert( p->eCurType==CURTYPE_BTREE );
rc = sqlite3BtreeTableMoveto(p->uc.pCursor, p->movetoTarget, 0, &res);
if( rc ) return rc;
if( res!=0 ) return SQLITE_CORRUPT_BKPT;
@@ -82711,10 +82711,10 @@ SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor *p){
*/
static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
int isDifferentRow, rc;
- assert( p->eCurType==CURTYPE_BTREE );
- assert( p->uc.pCursor!=0 );
- assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) );
- rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow);
+ assert( p->eCurType==CURTYPE_BTREE );
+ assert( p->uc.pCursor!=0 );
+ assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) );
+ rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow);
p->cacheStatus = CACHE_STALE;
if( isDifferentRow ) p->nullRow = 1;
return rc;
@@ -82725,8 +82725,8 @@ static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
** if need be. Return any I/O error from the restore operation.
*/
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
- assert( p->eCurType==CURTYPE_BTREE );
- if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
+ assert( p->eCurType==CURTYPE_BTREE );
+ if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
return handleMovedCursor(p);
}
return SQLITE_OK;
@@ -82746,19 +82746,19 @@ SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
** not been deleted out from under the cursor, then this routine is a no-op.
*/
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){
- VdbeCursor *p = *pp;
- assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
+ VdbeCursor *p = *pp;
+ assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
if( p->deferredMoveto ){
u32 iMap;
assert( !p->isEphemeral );
if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){
- *pp = p->pAltCursor;
- *piCol = iMap - 1;
- return SQLITE_OK;
- }
+ *pp = p->pAltCursor;
+ *piCol = iMap - 1;
+ return SQLITE_OK;
+ }
return sqlite3VdbeFinishMoveto(p);
}
- if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
+ if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
return handleMovedCursor(p);
}
return SQLITE_OK;
@@ -82818,13 +82818,13 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){
** this routine is now only used by the STAT3 logic and STAT3 support has
** ended. The code is kept here for historical reference only.
*/
-SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
+SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
int flags = pMem->flags;
u32 n;
- assert( pLen!=0 );
+ assert( pLen!=0 );
if( flags&MEM_Null ){
- *pLen = 0;
+ *pLen = 0;
return 0;
}
if( flags&(MEM_Int|MEM_IntReal) ){
@@ -82840,19 +82840,19 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
u = i;
}
if( u<=127 ){
- if( (i&1)==i && file_format>=4 ){
- *pLen = 0;
- return 8+(u32)u;
- }else{
- *pLen = 1;
- return 1;
- }
- }
- if( u<=32767 ){ *pLen = 2; return 2; }
- if( u<=8388607 ){ *pLen = 3; return 3; }
- if( u<=2147483647 ){ *pLen = 4; return 4; }
- if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
- *pLen = 8;
+ if( (i&1)==i && file_format>=4 ){
+ *pLen = 0;
+ return 8+(u32)u;
+ }else{
+ *pLen = 1;
+ return 1;
+ }
+ }
+ if( u<=32767 ){ *pLen = 2; return 2; }
+ if( u<=8388607 ){ *pLen = 3; return 3; }
+ if( u<=2147483647 ){ *pLen = 4; return 4; }
+ if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
+ *pLen = 8;
if( flags&MEM_IntReal ){
/* If the value is IntReal and is going to take up 8 bytes to store
** as an integer, then we might as well make it an 8-byte floating
@@ -82865,7 +82865,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
return 6;
}
if( flags&MEM_Real ){
- *pLen = 8;
+ *pLen = 8;
return 7;
}
assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
@@ -82874,47 +82874,47 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
if( flags & MEM_Zero ){
n += pMem->u.nZero;
}
- *pLen = n;
+ *pLen = n;
return ((n*2) + 12 + ((flags&MEM_Str)!=0));
}
#endif /* inlined into OP_MakeRecord */
/*
-** The sizes for serial types less than 128
+** The sizes for serial types less than 128
*/
static const u8 sqlite3SmallTypeSizes[] = {
/* 0 1 2 3 4 5 6 7 8 9 */
-/* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0,
-/* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
-/* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
-/* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
-/* 40 */ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18,
-/* 50 */ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
-/* 60 */ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28,
-/* 70 */ 29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
-/* 80 */ 34, 34, 35, 35, 36, 36, 37, 37, 38, 38,
-/* 90 */ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
-/* 100 */ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
-/* 110 */ 49, 49, 50, 50, 51, 51, 52, 52, 53, 53,
-/* 120 */ 54, 54, 55, 55, 56, 56, 57, 57
+/* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0,
+/* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
+/* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
+/* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
+/* 40 */ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18,
+/* 50 */ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
+/* 60 */ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28,
+/* 70 */ 29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
+/* 80 */ 34, 34, 35, 35, 36, 36, 37, 37, 38, 38,
+/* 90 */ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
+/* 100 */ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
+/* 110 */ 49, 49, 50, 50, 51, 51, 52, 52, 53, 53,
+/* 120 */ 54, 54, 55, 55, 56, 56, 57, 57
};
/*
** Return the length of the data corresponding to the supplied serial-type.
*/
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){
- if( serial_type>=128 ){
+ if( serial_type>=128 ){
return (serial_type-12)/2;
}else{
assert( serial_type<12
- || sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 );
+ || sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 );
return sqlite3SmallTypeSizes[serial_type];
}
}
-SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){
- assert( serial_type<128 );
+SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){
+ assert( serial_type<128 );
return sqlite3SmallTypeSizes[serial_type];
-}
+}
/*
** If we are on an architecture with mixed-endian floating
@@ -83010,7 +83010,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
== (int)sqlite3VdbeSerialTypeLen(serial_type) );
len = pMem->n;
- if( len>0 ) memcpy(buf, pMem->z, len);
+ if( len>0 ) memcpy(buf, pMem->z, len);
return len;
}
@@ -83078,13 +83078,13 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
Mem *pMem /* Memory cell to write value into */
){
switch( serial_type ){
- case 10: { /* Internal use only: NULL with virtual table
- ** UPDATE no-change flag set */
- pMem->flags = MEM_Null|MEM_Zero;
- pMem->n = 0;
- pMem->u.nZero = 0;
- break;
- }
+ case 10: { /* Internal use only: NULL with virtual table
+ ** UPDATE no-change flag set */
+ pMem->flags = MEM_Null|MEM_Zero;
+ pMem->n = 0;
+ pMem->u.nZero = 0;
+ break;
+ }
case 11: /* Reserved for future use */
case 0: { /* Null */
/* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
@@ -83120,9 +83120,9 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
** twos-complement integer. */
pMem->u.i = FOUR_BYTE_INT(buf);
#ifdef __HP_cc
- /* Work around a sign-extension bug in the HP compiler for HP/UX */
- if( buf[0]&0x80 ) pMem->u.i |= 0xffffffff80000000LL;
-#endif
+ /* Work around a sign-extension bug in the HP compiler for HP/UX */
+ if( buf[0]&0x80 ) pMem->u.i |= 0xffffffff80000000LL;
+#endif
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 4;
@@ -83178,17 +83178,17 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
** If an OOM error occurs, NULL is returned.
*/
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
- KeyInfo *pKeyInfo /* Description of the record */
+ KeyInfo *pKeyInfo /* Description of the record */
){
UnpackedRecord *p; /* Unpacked record to return */
int nByte; /* Number of bytes required for *p */
- nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
- p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
- if( !p ) return 0;
+ nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
+ p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
+ if( !p ) return 0;
p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
assert( pKeyInfo->aSortFlags!=0 );
p->pKeyInfo = pKeyInfo;
- p->nField = pKeyInfo->nKeyField + 1;
+ p->nField = pKeyInfo->nKeyField + 1;
return p;
}
@@ -83223,7 +83223,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
pMem->db = pKeyInfo->db;
/* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */
pMem->szMalloc = 0;
- pMem->z = 0;
+ pMem->z = 0;
d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
pMem++;
if( (++u)>=p->nField ) break;
@@ -83235,11 +83235,11 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
** warnings from MSAN. */
sqlite3VdbeMemSetNull(pMem-1);
}
- assert( u<=pKeyInfo->nKeyField + 1 );
+ assert( u<=pKeyInfo->nKeyField + 1 );
p->nField = u;
}
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/*
** This function compares two index or table record keys in the same way
** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
@@ -83284,9 +83284,9 @@ static int vdbeRecordCompareDebug(
idx1 = getVarint32(aKey1, szHdr1);
if( szHdr1>98307 ) return SQLITE_CORRUPT;
d1 = szHdr1;
- assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB );
+ assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB );
assert( pKeyInfo->aSortFlags!=0 );
- assert( pKeyInfo->nKeyField>0 );
+ assert( pKeyInfo->nKeyField>0 );
assert( idx1<=szHdr1 || CORRUPT_DB );
do{
u32 serial_type1;
@@ -83350,16 +83350,16 @@ debugCompareEnd:
}
#endif
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/*
** Count the number of fields (a.k.a. columns) in the record given by
** pKey,nKey. The verify that this count is less than or equal to the
-** limit given by pKeyInfo->nAllField.
+** limit given by pKeyInfo->nAllField.
**
** If this constraint is not satisfied, it means that the high-speed
** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will
** not work correctly. If this assert() ever fires, it probably means
-** that the KeyInfo.nKeyField or KeyInfo.nAllField values were computed
+** that the KeyInfo.nKeyField or KeyInfo.nAllField values were computed
** incorrectly.
*/
static void vdbeAssertFieldCountWithinLimits(
@@ -83380,7 +83380,7 @@ static void vdbeAssertFieldCountWithinLimits(
idx += getVarint32(aKey+idx, notUsed);
nField++;
}
- assert( nField <= pKeyInfo->nAllField );
+ assert( nField <= pKeyInfo->nAllField );
}
#else
# define vdbeAssertFieldCountWithinLimits(A,B,C)
@@ -83413,12 +83413,12 @@ static int vdbeCompareMemString(
sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
- if( (v1==0 || v2==0) ){
- if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
- rc = 0;
- }else{
- rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2);
- }
+ if( (v1==0 || v2==0) ){
+ if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
+ rc = 0;
+ }else{
+ rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2);
+ }
sqlite3VdbeMemRelease(&c1);
sqlite3VdbeMemRelease(&c2);
return rc;
@@ -83426,78 +83426,78 @@ static int vdbeCompareMemString(
}
/*
-** The input pBlob is guaranteed to be a Blob that is not marked
-** with MEM_Zero. Return true if it could be a zero-blob.
-*/
-static int isAllZero(const char *z, int n){
- int i;
- for(i=0; i<n; i++){
- if( z[i] ) return 0;
- }
- return 1;
-}
-
-/*
+** The input pBlob is guaranteed to be a Blob that is not marked
+** with MEM_Zero. Return true if it could be a zero-blob.
+*/
+static int isAllZero(const char *z, int n){
+ int i;
+ for(i=0; i<n; i++){
+ if( z[i] ) return 0;
+ }
+ return 1;
+}
+
+/*
** Compare two blobs. Return negative, zero, or positive if the first
** is less than, equal to, or greater than the second, respectively.
** If one blob is a prefix of the other, then the shorter is the lessor.
*/
SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
- int c;
- int n1 = pB1->n;
- int n2 = pB2->n;
-
- /* It is possible to have a Blob value that has some non-zero content
- ** followed by zero content. But that only comes up for Blobs formed
- ** by the OP_MakeRecord opcode, and such Blobs never get passed into
- ** sqlite3MemCompare(). */
- assert( (pB1->flags & MEM_Zero)==0 || n1==0 );
- assert( (pB2->flags & MEM_Zero)==0 || n2==0 );
-
- if( (pB1->flags|pB2->flags) & MEM_Zero ){
- if( pB1->flags & pB2->flags & MEM_Zero ){
- return pB1->u.nZero - pB2->u.nZero;
- }else if( pB1->flags & MEM_Zero ){
- if( !isAllZero(pB2->z, pB2->n) ) return -1;
- return pB1->u.nZero - n2;
- }else{
- if( !isAllZero(pB1->z, pB1->n) ) return +1;
- return n1 - pB2->u.nZero;
- }
- }
- c = memcmp(pB1->z, pB2->z, n1>n2 ? n2 : n1);
+ int c;
+ int n1 = pB1->n;
+ int n2 = pB2->n;
+
+ /* It is possible to have a Blob value that has some non-zero content
+ ** followed by zero content. But that only comes up for Blobs formed
+ ** by the OP_MakeRecord opcode, and such Blobs never get passed into
+ ** sqlite3MemCompare(). */
+ assert( (pB1->flags & MEM_Zero)==0 || n1==0 );
+ assert( (pB2->flags & MEM_Zero)==0 || n2==0 );
+
+ if( (pB1->flags|pB2->flags) & MEM_Zero ){
+ if( pB1->flags & pB2->flags & MEM_Zero ){
+ return pB1->u.nZero - pB2->u.nZero;
+ }else if( pB1->flags & MEM_Zero ){
+ if( !isAllZero(pB2->z, pB2->n) ) return -1;
+ return pB1->u.nZero - n2;
+ }else{
+ if( !isAllZero(pB1->z, pB1->n) ) return +1;
+ return n1 - pB2->u.nZero;
+ }
+ }
+ c = memcmp(pB1->z, pB2->z, n1>n2 ? n2 : n1);
if( c ) return c;
- return n1 - n2;
+ return n1 - n2;
}
-/*
-** Do a comparison between a 64-bit signed integer and a 64-bit floating-point
-** number. Return negative, zero, or positive if the first (i64) is less than,
-** equal to, or greater than the second (double).
-*/
+/*
+** Do a comparison between a 64-bit signed integer and a 64-bit floating-point
+** number. Return negative, zero, or positive if the first (i64) is less than,
+** equal to, or greater than the second (double).
+*/
SQLITE_PRIVATE int sqlite3IntFloatCompare(i64 i, double r){
- if( sizeof(LONGDOUBLE_TYPE)>8 ){
- LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i;
+ if( sizeof(LONGDOUBLE_TYPE)>8 ){
+ LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i;
testcase( x<r );
testcase( x>r );
testcase( x==r );
- if( x<r ) return -1;
+ if( x<r ) return -1;
if( x>r ) return +1; /*NO_TEST*/ /* work around bugs in gcov */
return 0; /*NO_TEST*/ /* work around bugs in gcov */
- }else{
- i64 y;
- double s;
- if( r<-9223372036854775808.0 ) return +1;
+ }else{
+ i64 y;
+ double s;
+ if( r<-9223372036854775808.0 ) return +1;
if( r>=9223372036854775808.0 ) return -1;
- y = (i64)r;
- if( i<y ) return -1;
+ y = (i64)r;
+ if( i<y ) return -1;
if( i>y ) return +1;
- s = (double)i;
- if( s<r ) return -1;
- if( s>r ) return +1;
- return 0;
- }
-}
+ s = (double)i;
+ if( s<r ) return -1;
+ if( s>r ) return +1;
+ return 0;
+ }
+}
/*
** Compare the values contained by the two memory cells, returning
@@ -83524,7 +83524,7 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
return (f2&MEM_Null) - (f1&MEM_Null);
}
- /* At least one of the two values is a number
+ /* At least one of the two values is a number
*/
if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){
testcase( combined_flags & MEM_Int );
@@ -83534,37 +83534,37 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
testcase( f1 & f2 & MEM_Int );
testcase( f1 & f2 & MEM_IntReal );
if( pMem1->u.i < pMem2->u.i ) return -1;
- if( pMem1->u.i > pMem2->u.i ) return +1;
+ if( pMem1->u.i > pMem2->u.i ) return +1;
+ return 0;
+ }
+ if( (f1 & f2 & MEM_Real)!=0 ){
+ if( pMem1->u.r < pMem2->u.r ) return -1;
+ if( pMem1->u.r > pMem2->u.r ) return +1;
return 0;
}
- if( (f1 & f2 & MEM_Real)!=0 ){
- if( pMem1->u.r < pMem2->u.r ) return -1;
- if( pMem1->u.r > pMem2->u.r ) return +1;
- return 0;
- }
if( (f1&(MEM_Int|MEM_IntReal))!=0 ){
testcase( f1 & MEM_Int );
testcase( f1 & MEM_IntReal );
- if( (f2&MEM_Real)!=0 ){
- return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
+ if( (f2&MEM_Real)!=0 ){
+ return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
}else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return +1;
return 0;
- }else{
- return -1;
- }
- }
+ }else{
+ return -1;
+ }
+ }
if( (f1&MEM_Real)!=0 ){
if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
testcase( f2 & MEM_Int );
testcase( f2 & MEM_IntReal );
- return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
- }else{
- return -1;
- }
+ return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
+ }else{
+ return -1;
+ }
}
- return +1;
+ return +1;
}
/* If one value is a string and the other is a blob, the string is less.
@@ -83578,7 +83578,7 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
return -1;
}
- assert( pMem1->enc==pMem2->enc || pMem1->db->mallocFailed );
+ assert( pMem1->enc==pMem2->enc || pMem1->db->mallocFailed );
assert( pMem1->enc==SQLITE_UTF8 ||
pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
@@ -83701,7 +83701,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField
|| CORRUPT_DB );
assert( pPKey2->pKeyInfo->aSortFlags!=0 );
- assert( pPKey2->pKeyInfo->nKeyField>0 );
+ assert( pPKey2->pKeyInfo->nKeyField>0 );
assert( idx1<=szHdr1 || CORRUPT_DB );
do{
u32 serial_type;
@@ -83718,7 +83718,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
rc = -1;
}else if( serial_type==7 ){
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
- rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r);
+ rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r);
}else{
i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]);
i64 rhs = pRhs->u.i;
@@ -83744,13 +83744,13 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
}else{
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
if( serial_type==7 ){
- if( mem1.u.r<pRhs->u.r ){
- rc = -1;
- }else if( mem1.u.r>pRhs->u.r ){
- rc = +1;
- }
+ if( mem1.u.r<pRhs->u.r ){
+ rc = -1;
+ }else if( mem1.u.r>pRhs->u.r ){
+ rc = +1;
+ }
}else{
- rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r);
+ rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r);
}
}
}
@@ -83790,7 +83790,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
/* RHS is a blob */
else if( pRhs->flags & MEM_Blob ){
- assert( (pRhs->flags & MEM_Zero)==0 || pRhs->n==0 );
+ assert( (pRhs->flags & MEM_Zero)==0 || pRhs->n==0 );
getVarint32NR(&aKey1[idx1], serial_type);
testcase( serial_type==12 );
if( serial_type<12 || (serial_type & 0x01) ){
@@ -83802,12 +83802,12 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
if( (d1+nStr) > (unsigned)nKey1 ){
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
- }else if( pRhs->flags & MEM_Zero ){
- if( !isAllZero((const char*)&aKey1[d1],nStr) ){
- rc = 1;
- }else{
- rc = nStr - pRhs->u.nZero;
- }
+ }else if( pRhs->flags & MEM_Zero ){
+ if( !isAllZero((const char*)&aKey1[d1],nStr) ){
+ rc = 1;
+ }else{
+ rc = nStr - pRhs->u.nZero;
+ }
}else{
int nCmp = MIN(nStr, pRhs->n);
rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
@@ -83856,7 +83856,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
|| vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc)
|| pPKey2->pKeyInfo->db->mallocFailed
);
- pPKey2->eqSeen = 1;
+ pPKey2->eqSeen = 1;
return pPKey2->default_rc;
}
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
@@ -83885,7 +83885,7 @@ static int vdbeRecordCompareInt(
int res;
u32 y;
u64 x;
- i64 v;
+ i64 v;
i64 lhs;
vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
@@ -83944,7 +83944,7 @@ static int vdbeRecordCompareInt(
return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
}
- v = pPKey2->aMem[0].u.i;
+ v = pPKey2->aMem[0].u.i;
if( v>lhs ){
res = pPKey2->r1;
}else if( v<lhs ){
@@ -83957,7 +83957,7 @@ static int vdbeRecordCompareInt(
/* The first fields of the two keys are equal and there are no trailing
** fields. Return pPKey2->default_rc in this case. */
res = pPKey2->default_rc;
- pPKey2->eqSeen = 1;
+ pPKey2->eqSeen = 1;
}
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) );
@@ -83978,7 +83978,7 @@ static int vdbeRecordCompareString(
int serial_type;
int res;
- assert( pPKey2->aMem[0].flags & MEM_Str );
+ assert( pPKey2->aMem[0].flags & MEM_Str );
vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
serial_type = (u8)(aKey1[1]);
if( serial_type >= 0x80 ){
@@ -84012,7 +84012,7 @@ static int vdbeRecordCompareString(
res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
}else{
res = pPKey2->default_rc;
- pPKey2->eqSeen = 1;
+ pPKey2->eqSeen = 1;
}
}else if( res>0 ){
res = pPKey2->r2;
@@ -84048,7 +84048,7 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
** The easiest way to enforce this limit is to consider only records with
** 13 fields or less. If the first field is an integer, the maximum legal
** header size is (12*5 + 1 + 1) bytes. */
- if( p->pKeyInfo->nAllField<=13 ){
+ if( p->pKeyInfo->nAllField<=13 ){
int flags = p->aMem[0].flags;
if( p->pKeyInfo->aSortFlags[0] ){
if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){
@@ -84099,7 +84099,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
** this code can safely assume that nCellKey is 32-bits
*/
assert( sqlite3BtreeCursorIsValid(pCur) );
- nCellKey = sqlite3BtreePayloadSize(pCur);
+ nCellKey = sqlite3BtreePayloadSize(pCur);
assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
/* Read in the complete content of the index entry */
@@ -84172,13 +84172,13 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
){
i64 nCellKey = 0;
int rc;
- BtCursor *pCur;
+ BtCursor *pCur;
Mem m;
- assert( pC->eCurType==CURTYPE_BTREE );
- pCur = pC->uc.pCursor;
+ assert( pC->eCurType==CURTYPE_BTREE );
+ pCur = pC->uc.pCursor;
assert( sqlite3BtreeCursorIsValid(pCur) );
- nCellKey = sqlite3BtreePayloadSize(pCur);
+ nCellKey = sqlite3BtreePayloadSize(pCur);
/* nCellKey will always be between 0 and 0xffffffff because of the way
** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
if( nCellKey<=0 || nCellKey>0x7fffffff ){
@@ -84246,13 +84246,13 @@ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){
}
/*
-** Return the SQLITE_PREPARE flags for a Vdbe.
-*/
-SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe *v){
- return v->prepFlags;
-}
-
-/*
+** Return the SQLITE_PREPARE flags for a Vdbe.
+*/
+SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe *v){
+ return v->prepFlags;
+}
+
+/*
** Return a pointer to an sqlite3_value structure containing the value bound
** parameter iVar of VM v. Except, if the value is an SQL NULL, return
** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
@@ -84264,7 +84264,7 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff
assert( iVar>0 );
if( v ){
Mem *pMem = &v->aVar[iVar-1];
- assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
+ assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
if( 0==(pMem->flags & MEM_Null) ){
sqlite3_value *pRet = sqlite3ValueNew(v->db);
if( pRet ){
@@ -84284,28 +84284,28 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff
*/
SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
assert( iVar>0 );
- assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
- if( iVar>=32 ){
- v->expmask |= 0x80000000;
+ assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
+ if( iVar>=32 ){
+ v->expmask |= 0x80000000;
}else{
v->expmask |= ((u32)1 << (iVar-1));
}
}
-/*
-** Cause a function to throw an error if it was call from OP_PureFunc
-** rather than OP_Function.
-**
-** OP_PureFunc means that the function must be deterministic, and should
-** throw an error if it is given inputs that would make it non-deterministic.
-** This routine is invoked by date/time functions that use non-deterministic
-** features such as 'now'.
-*/
-SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context *pCtx){
+/*
+** Cause a function to throw an error if it was call from OP_PureFunc
+** rather than OP_Function.
+**
+** OP_PureFunc means that the function must be deterministic, and should
+** throw an error if it is given inputs that would make it non-deterministic.
+** This routine is invoked by date/time functions that use non-deterministic
+** features such as 'now'.
+*/
+SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context *pCtx){
const VdbeOp *pOp;
#ifdef SQLITE_ENABLE_STAT4
- if( pCtx->pVdbe==0 ) return 1;
-#endif
+ if( pCtx->pVdbe==0 ) return 1;
+#endif
pOp = pCtx->pVdbe->aOp + pCtx->iOp;
if( pOp->opcode==OP_PureFunc ){
const char *zContext;
@@ -84321,11 +84321,11 @@ SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context *pCtx){
pCtx->pFunc->zName, zContext);
sqlite3_result_error(pCtx, zMsg, -1);
sqlite3_free(zMsg);
- return 0;
- }
- return 1;
-}
-
+ return 0;
+ }
+ return 1;
+}
+
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
@@ -84333,109 +84333,109 @@ SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context *pCtx){
** in memory obtained from sqlite3DbMalloc).
*/
SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){
- if( pVtab->zErrMsg ){
- sqlite3 *db = p->db;
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
- sqlite3_free(pVtab->zErrMsg);
- pVtab->zErrMsg = 0;
- }
+ if( pVtab->zErrMsg ){
+ sqlite3 *db = p->db;
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
+ sqlite3_free(pVtab->zErrMsg);
+ pVtab->zErrMsg = 0;
+ }
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
-
-/*
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+
+/*
** If the second argument is not NULL, release any allocations associated
-** with the memory cells in the p->aMem[] array. Also free the UnpackedRecord
-** structure itself, using sqlite3DbFree().
-**
-** This function is used to free UnpackedRecord structures allocated by
-** the vdbeUnpackRecord() function found in vdbeapi.c.
-*/
-static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
- if( p ){
- int i;
- for(i=0; i<nField; i++){
- Mem *pMem = &p->aMem[i];
- if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
- }
- sqlite3DbFreeNN(db, p);
- }
-}
-#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
-
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
-/*
-** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call,
-** then cursor passed as the second argument should point to the row about
-** to be update or deleted. If the application calls sqlite3_preupdate_old(),
-** the required value will be read from the row the cursor points to.
-*/
-SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
- Vdbe *v, /* Vdbe pre-update hook is invoked by */
- VdbeCursor *pCsr, /* Cursor to grab old.* values from */
- int op, /* SQLITE_INSERT, UPDATE or DELETE */
- const char *zDb, /* Database name */
- Table *pTab, /* Modified table */
- i64 iKey1, /* Initial key value */
+** with the memory cells in the p->aMem[] array. Also free the UnpackedRecord
+** structure itself, using sqlite3DbFree().
+**
+** This function is used to free UnpackedRecord structures allocated by
+** the vdbeUnpackRecord() function found in vdbeapi.c.
+*/
+static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
+ if( p ){
+ int i;
+ for(i=0; i<nField; i++){
+ Mem *pMem = &p->aMem[i];
+ if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
+ }
+ sqlite3DbFreeNN(db, p);
+ }
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call,
+** then cursor passed as the second argument should point to the row about
+** to be update or deleted. If the application calls sqlite3_preupdate_old(),
+** the required value will be read from the row the cursor points to.
+*/
+SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
+ Vdbe *v, /* Vdbe pre-update hook is invoked by */
+ VdbeCursor *pCsr, /* Cursor to grab old.* values from */
+ int op, /* SQLITE_INSERT, UPDATE or DELETE */
+ const char *zDb, /* Database name */
+ Table *pTab, /* Modified table */
+ i64 iKey1, /* Initial key value */
int iReg, /* Register for new.* record */
int iBlobWrite
-){
- sqlite3 *db = v->db;
- i64 iKey2;
- PreUpdate preupdate;
- const char *zTbl = pTab->zName;
- static const u8 fakeSortOrder = 0;
-
- assert( db->pPreUpdate==0 );
- memset(&preupdate, 0, sizeof(PreUpdate));
- if( HasRowid(pTab)==0 ){
- iKey1 = iKey2 = 0;
- preupdate.pPk = sqlite3PrimaryKeyIndex(pTab);
- }else{
- if( op==SQLITE_UPDATE ){
- iKey2 = v->aMem[iReg].u.i;
- }else{
- iKey2 = iKey1;
- }
- }
-
+){
+ sqlite3 *db = v->db;
+ i64 iKey2;
+ PreUpdate preupdate;
+ const char *zTbl = pTab->zName;
+ static const u8 fakeSortOrder = 0;
+
+ assert( db->pPreUpdate==0 );
+ memset(&preupdate, 0, sizeof(PreUpdate));
+ if( HasRowid(pTab)==0 ){
+ iKey1 = iKey2 = 0;
+ preupdate.pPk = sqlite3PrimaryKeyIndex(pTab);
+ }else{
+ if( op==SQLITE_UPDATE ){
+ iKey2 = v->aMem[iReg].u.i;
+ }else{
+ iKey2 = iKey1;
+ }
+ }
+
assert( pCsr!=0 );
assert( pCsr->eCurType==CURTYPE_BTREE );
assert( pCsr->nField==pTab->nCol
- || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
- );
-
- preupdate.v = v;
- preupdate.pCsr = pCsr;
- preupdate.op = op;
- preupdate.iNewReg = iReg;
- preupdate.keyinfo.db = db;
- preupdate.keyinfo.enc = ENC(db);
- preupdate.keyinfo.nKeyField = pTab->nCol;
+ || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
+ );
+
+ preupdate.v = v;
+ preupdate.pCsr = pCsr;
+ preupdate.op = op;
+ preupdate.iNewReg = iReg;
+ preupdate.keyinfo.db = db;
+ preupdate.keyinfo.enc = ENC(db);
+ preupdate.keyinfo.nKeyField = pTab->nCol;
preupdate.keyinfo.aSortFlags = (u8*)&fakeSortOrder;
- preupdate.iKey1 = iKey1;
- preupdate.iKey2 = iKey2;
- preupdate.pTab = pTab;
+ preupdate.iKey1 = iKey1;
+ preupdate.iKey2 = iKey2;
+ preupdate.pTab = pTab;
preupdate.iBlobWrite = iBlobWrite;
-
- db->pPreUpdate = &preupdate;
- db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
- db->pPreUpdate = 0;
- sqlite3DbFree(db, preupdate.aRecord);
- vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked);
- vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked);
- if( preupdate.aNew ){
- int i;
- for(i=0; i<pCsr->nField; i++){
- sqlite3VdbeMemRelease(&preupdate.aNew[i]);
- }
- sqlite3DbFreeNN(db, preupdate.aNew);
- }
-}
-#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
-
+
+ db->pPreUpdate = &preupdate;
+ db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
+ db->pPreUpdate = 0;
+ sqlite3DbFree(db, preupdate.aRecord);
+ vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked);
+ vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked);
+ if( preupdate.aNew ){
+ int i;
+ for(i=0; i<pCsr->nField; i++){
+ sqlite3VdbeMemRelease(&preupdate.aNew[i]);
+ }
+ sqlite3DbFreeNN(db, preupdate.aNew);
+ }
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
/************** End of vdbeaux.c *********************************************/
/************** Begin file vdbeapi.c *****************************************/
/*
@@ -84465,7 +84465,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
** collating sequences are registered or if an authorizer function is
** added or changed.
*/
-SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p==0 || p->expired;
}
@@ -84500,21 +84500,21 @@ static int vdbeSafetyNotNull(Vdbe *p){
*/
static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
sqlite3_int64 iNow;
- sqlite3_int64 iElapse;
+ sqlite3_int64 iElapse;
assert( p->startTime>0 );
assert( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 );
assert( db->init.busy==0 );
assert( p->zSql!=0 );
sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
- iElapse = (iNow - p->startTime)*1000000;
+ iElapse = (iNow - p->startTime)*1000000;
#ifndef SQLITE_OMIT_DEPRECATED
- if( db->xProfile ){
- db->xProfile(db->pProfileArg, p->zSql, iElapse);
- }
+ if( db->xProfile ){
+ db->xProfile(db->pProfileArg, p->zSql, iElapse);
+ }
#endif
- if( db->mTrace & SQLITE_TRACE_PROFILE ){
+ if( db->mTrace & SQLITE_TRACE_PROFILE ){
db->trace.xV2(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse);
- }
+ }
p->startTime = 0;
}
/*
@@ -84536,7 +84536,7 @@ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
/* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
@@ -84563,7 +84563,7 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
rc = SQLITE_OK;
@@ -84584,7 +84584,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){
/*
** Set all the parameters in the compiled SQL statement to NULL.
*/
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
int i;
int rc = SQLITE_OK;
Vdbe *p = (Vdbe*)pStmt;
@@ -84596,8 +84596,8 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
sqlite3VdbeMemRelease(&p->aVar[i]);
p->aVar[i].flags = MEM_Null;
}
- assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 );
- if( p->expmask ){
+ assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 );
+ if( p->expmask ){
p->expired = 1;
}
sqlite3_mutex_leave(mutex);
@@ -84609,10 +84609,10 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
** The following routines extract information from a Mem or sqlite3_value
** structure.
*/
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
+SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
- if( ExpandBlob(p)!=SQLITE_OK ){
+ if( ExpandBlob(p)!=SQLITE_OK ){
assert( p->flags==MEM_Null && p->z==0 );
return 0;
}
@@ -84622,49 +84622,49 @@ SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
return sqlite3_value_text(pVal);
}
}
-SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){
return sqlite3ValueBytes(pVal, SQLITE_UTF8);
}
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){
return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
}
-SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){
+SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){
return sqlite3VdbeRealValue((Mem*)pVal);
}
-SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){
return (int)sqlite3VdbeIntValue((Mem*)pVal);
}
-SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
+SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
return sqlite3VdbeIntValue((Mem*)pVal);
}
-SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value *pVal){
- Mem *pMem = (Mem*)pVal;
- return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0);
-}
-SQLITE_API void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){
- Mem *p = (Mem*)pVal;
- if( (p->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) ==
- (MEM_Null|MEM_Term|MEM_Subtype)
- && zPType!=0
- && p->eSubtype=='p'
- && strcmp(p->u.zPType, zPType)==0
- ){
- return (void*)p->z;
- }else{
- return 0;
- }
-}
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
+SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value *pVal){
+ Mem *pMem = (Mem*)pVal;
+ return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0);
+}
+SQLITE_API void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){
+ Mem *p = (Mem*)pVal;
+ if( (p->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) ==
+ (MEM_Null|MEM_Term|MEM_Subtype)
+ && zPType!=0
+ && p->eSubtype=='p'
+ && strcmp(p->u.zPType, zPType)==0
+ ){
+ return (void*)p->z;
+ }else{
+ return 0;
+ }
+}
+SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){
+SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
}
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){
+SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16BE);
}
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
+SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16LE);
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -84672,7 +84672,7 @@ SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
** point number string BLOB NULL
*/
-SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
+SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
static const u8 aType[] = {
SQLITE_BLOB, /* 0x00 (not possible) */
SQLITE_NULL, /* 0x01 NULL */
@@ -84757,11 +84757,11 @@ SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
return aType[pVal->flags&MEM_AffMask];
}
-/* Return true if a parameter to xUpdate represents an unchanged column */
-SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){
- return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
-}
-
+/* Return true if a parameter to xUpdate represents an unchanged column */
+SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){
+ return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
+}
+
/* Return true if a parameter value originated from an sqlite3_bind() */
SQLITE_API int sqlite3_value_frombind(sqlite3_value *pVal){
return (pVal->flags&MEM_FromBind)!=0;
@@ -84769,7 +84769,7 @@ SQLITE_API int sqlite3_value_frombind(sqlite3_value *pVal){
/* Make a copy of an sqlite3_value object
*/
-SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
+SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
sqlite3_value *pNew;
if( pOrig==0 ) return 0;
pNew = sqlite3_malloc( sizeof(*pNew) );
@@ -84792,7 +84792,7 @@ SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
/* Destroy an sqlite3_value object previously obtained from
** sqlite3_value_dup().
*/
-SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){
+SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){
sqlite3ValueFree(pOld);
}
@@ -84843,7 +84843,7 @@ static int invokeValueDestructor(
sqlite3_result_error_toobig(pCtx);
return SQLITE_TOOBIG;
}
-SQLITE_API void sqlite3_result_blob(
+SQLITE_API void sqlite3_result_blob(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -84853,7 +84853,7 @@ SQLITE_API void sqlite3_result_blob(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, 0, xDel);
}
-SQLITE_API void sqlite3_result_blob64(
+SQLITE_API void sqlite3_result_blob64(
sqlite3_context *pCtx,
const void *z,
sqlite3_uint64 n,
@@ -84867,53 +84867,53 @@ SQLITE_API void sqlite3_result_blob64(
setResultStrOrError(pCtx, z, (int)n, 0, xDel);
}
}
-SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
+SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
}
-SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
+SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
+SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
-SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
+SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal);
}
-SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
+SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
}
-SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){
+SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
}
-SQLITE_API void sqlite3_result_pointer(
- sqlite3_context *pCtx,
- void *pPtr,
- const char *zPType,
- void (*xDestructor)(void*)
-){
- Mem *pOut = pCtx->pOut;
- assert( sqlite3_mutex_held(pOut->db->mutex) );
- sqlite3VdbeMemRelease(pOut);
- pOut->flags = MEM_Null;
- sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor);
-}
-SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
- Mem *pOut = pCtx->pOut;
- assert( sqlite3_mutex_held(pOut->db->mutex) );
- pOut->eSubtype = eSubtype & 0xff;
- pOut->flags |= MEM_Subtype;
-}
-SQLITE_API void sqlite3_result_text(
+SQLITE_API void sqlite3_result_pointer(
+ sqlite3_context *pCtx,
+ void *pPtr,
+ const char *zPType,
+ void (*xDestructor)(void*)
+){
+ Mem *pOut = pCtx->pOut;
+ assert( sqlite3_mutex_held(pOut->db->mutex) );
+ sqlite3VdbeMemRelease(pOut);
+ pOut->flags = MEM_Null;
+ sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor);
+}
+SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
+ Mem *pOut = pCtx->pOut;
+ assert( sqlite3_mutex_held(pOut->db->mutex) );
+ pOut->eSubtype = eSubtype & 0xff;
+ pOut->flags |= MEM_Subtype;
+}
+SQLITE_API void sqlite3_result_text(
sqlite3_context *pCtx,
const char *z,
int n,
@@ -84922,7 +84922,7 @@ SQLITE_API void sqlite3_result_text(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
}
-SQLITE_API void sqlite3_result_text64(
+SQLITE_API void sqlite3_result_text64(
sqlite3_context *pCtx,
const char *z,
sqlite3_uint64 n,
@@ -84939,7 +84939,7 @@ SQLITE_API void sqlite3_result_text64(
}
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API void sqlite3_result_text16(
+SQLITE_API void sqlite3_result_text16(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -84948,7 +84948,7 @@ SQLITE_API void sqlite3_result_text16(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
}
-SQLITE_API void sqlite3_result_text16be(
+SQLITE_API void sqlite3_result_text16be(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -84957,7 +84957,7 @@ SQLITE_API void sqlite3_result_text16be(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
}
-SQLITE_API void sqlite3_result_text16le(
+SQLITE_API void sqlite3_result_text16le(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -84967,15 +84967,15 @@ SQLITE_API void sqlite3_result_text16le(
setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
}
#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
+SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemCopy(pCtx->pOut, pValue);
}
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
+SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
}
-SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
+SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
Mem *pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pOut->db->mutex) );
if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
@@ -84988,7 +84988,7 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
return sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
#endif
}
-SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
+SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
pCtx->isError = errCode ? errCode : -1;
#ifdef SQLITE_DEBUG
if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
@@ -85000,7 +85000,7 @@ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
}
/* Force an SQLITE_TOOBIG error. */
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
+SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1,
@@ -85008,11 +85008,11 @@ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
}
/* An SQLITE_NOMEM error. */
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
+SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
- pCtx->isError = SQLITE_NOMEM_BKPT;
- sqlite3OomFault(pCtx->pOut->db);
+ pCtx->isError = SQLITE_NOMEM_BKPT;
+ sqlite3OomFault(pCtx->pOut->db);
}
#ifndef SQLITE_UNTESTABLE
@@ -85045,8 +85045,8 @@ static int doWalCallbacks(sqlite3 *db){
sqlite3BtreeEnter(pBt);
nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
sqlite3BtreeLeave(pBt);
- if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){
- rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
+ if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){
+ rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
}
}
}
@@ -85101,7 +85101,7 @@ static int sqlite3Step(Vdbe *p){
db = p->db;
if( db->mallocFailed ){
p->rc = SQLITE_NOMEM;
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
if( p->pc<0 && p->expired ){
@@ -85131,7 +85131,7 @@ static int sqlite3Step(Vdbe *p){
#ifndef SQLITE_OMIT_TRACE
if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
- && !db->init.busy && p->zSql ){
+ && !db->init.busy && p->zSql ){
sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
}else{
assert( p->startTime==0 );
@@ -85180,7 +85180,7 @@ static int sqlite3Step(Vdbe *p){
db->errCode = rc;
if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){
- p->rc = SQLITE_NOMEM_BKPT;
+ p->rc = SQLITE_NOMEM_BKPT;
if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ) rc = p->rc;
}
end_of_step:
@@ -85188,7 +85188,7 @@ end_of_step:
** statements prepared using the legacy sqlite3_prepare() interface */
assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0
|| rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR
- || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE
+ || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE
);
return (rc&db->errMask);
}
@@ -85198,7 +85198,7 @@ end_of_step:
** sqlite3Step() to do most of the work. If a schema error occurs,
** call sqlite3Reprepare() and try again.
*/
-SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
int rc = SQLITE_OK; /* Result from sqlite3Step() */
Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */
int cnt = 0; /* Counter to prevent infinite loop of reprepares */
@@ -85213,27 +85213,27 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
&& cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
int savedPc = v->pc;
- rc = sqlite3Reprepare(v);
- if( rc!=SQLITE_OK ){
+ rc = sqlite3Reprepare(v);
+ if( rc!=SQLITE_OK ){
/* This case occurs after failing to recompile an sql statement.
** The error message from the SQL compiler has already been loaded
** into the database handle. This block copies the error message
- ** from the database handle into the statement and sets the statement
+ ** from the database handle into the statement and sets the statement
** program counter to 0 to ensure that when the statement is
- ** finalized or reset the parser error message is available via
- ** sqlite3_errmsg() and sqlite3_errcode().
- */
+ ** finalized or reset the parser error message is available via
+ ** sqlite3_errmsg() and sqlite3_errcode().
+ */
const char *zErr = (const char *)sqlite3_value_text(db->pErr);
- sqlite3DbFree(db, v->zErrMsg);
- if( !db->mallocFailed ){
- v->zErrMsg = sqlite3DbStrDup(db, zErr);
- v->rc = rc = sqlite3ApiExit(db, rc);
- } else {
- v->zErrMsg = 0;
- v->rc = rc = SQLITE_NOMEM_BKPT;
- }
- break;
- }
+ sqlite3DbFree(db, v->zErrMsg);
+ if( !db->mallocFailed ){
+ v->zErrMsg = sqlite3DbStrDup(db, zErr);
+ v->rc = rc = sqlite3ApiExit(db, rc);
+ } else {
+ v->zErrMsg = 0;
+ v->rc = rc = SQLITE_NOMEM_BKPT;
+ }
+ break;
+ }
sqlite3_reset(pStmt);
if( savedPc>=0 ) v->doingRerun = 1;
assert( v->expired==0 );
@@ -85247,7 +85247,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.
*/
-SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
+SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
assert( p && p->pFunc );
return p->pFunc->pUserData;
}
@@ -85262,31 +85262,31 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
** sqlite3_create_function16() routines that originally registered the
** application defined function.
*/
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
- assert( p && p->pOut );
+SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
+ assert( p && p->pOut );
return p->pOut->db;
}
/*
-** If this routine is invoked from within an xColumn method of a virtual
-** table, then it returns true if and only if the the call is during an
-** UPDATE operation and the value of the column will not be modified
-** by the UPDATE.
-**
-** If this routine is called from any context other than within the
-** xColumn method of a virtual table, then the return value is meaningless
-** and arbitrary.
-**
-** Virtual table implements might use this routine to optimize their
-** performance by substituting a NULL result, or some other light-weight
-** value, as a signal to the xUpdate routine that the column is unchanged.
-*/
-SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
- assert( p );
- return sqlite3_value_nochange(p->pOut);
-}
-
-/*
+** If this routine is invoked from within an xColumn method of a virtual
+** table, then it returns true if and only if the the call is during an
+** UPDATE operation and the value of the column will not be modified
+** by the UPDATE.
+**
+** If this routine is called from any context other than within the
+** xColumn method of a virtual table, then the return value is meaningless
+** and arbitrary.
+**
+** Virtual table implements might use this routine to optimize their
+** performance by substituting a NULL result, or some other light-weight
+** value, as a signal to the xUpdate routine that the column is unchanged.
+*/
+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
+ assert( p );
+ return sqlite3_value_nochange(p->pOut);
+}
+
+/*
** Return the current time for a statement. If the current time
** is requested more than once within the same run of a single prepared
** statement, the exact same time is returned for each invocation regardless
@@ -85335,8 +85335,8 @@ static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){
** context is allocated on the first call. Subsequent calls return the
** same context that was returned on prior calls.
*/
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
- assert( p && p->pFunc && p->pFunc->xFinalize );
+SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
+ assert( p && p->pFunc && p->pFunc->xFinalize );
assert( sqlite3_mutex_held(p->pOut->db->mutex) );
testcase( nByte<0 );
if( (p->pMem->flags & MEM_Agg)==0 ){
@@ -85349,14 +85349,14 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
/*
** Return the auxiliary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
-**
-** The left-most argument is 0.
-**
-** Undocumented behavior: If iArg is negative then access a cache of
-** auxiliary data pointers that is available to all functions within a
-** single prepared statement. The iArg values must match.
-*/
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
+**
+** The left-most argument is 0.
+**
+** Undocumented behavior: If iArg is negative then access a cache of
+** auxiliary data pointers that is available to all functions within a
+** single prepared statement. The iArg values must match.
+*/
+SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
AuxData *pAuxData;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
@@ -85365,26 +85365,26 @@ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
#else
assert( pCtx->pVdbe!=0 );
#endif
- for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
- if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
- return pAuxData->pAux;
- }
+ for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
+ if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
+ return pAuxData->pAux;
+ }
}
- return 0;
+ return 0;
}
/*
** Set the auxiliary data pointer and delete function, for the iArg'th
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.
-**
-** The left-most argument is 0.
-**
-** Undocumented behavior: If iArg is negative then make the data available
-** to all functions within the current prepared statement using iArg as an
-** access code.
-*/
-SQLITE_API void sqlite3_set_auxdata(
+**
+** The left-most argument is 0.
+**
+** Undocumented behavior: If iArg is negative then make the data available
+** to all functions within the current prepared statement using iArg as an
+** access code.
+*/
+SQLITE_API void sqlite3_set_auxdata(
sqlite3_context *pCtx,
int iArg,
void *pAux,
@@ -85400,25 +85400,25 @@ SQLITE_API void sqlite3_set_auxdata(
assert( pVdbe!=0 );
#endif
- for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
- if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
- break;
- }
+ for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
+ if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
+ break;
+ }
}
if( pAuxData==0 ){
pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
if( !pAuxData ) goto failed;
- pAuxData->iAuxOp = pCtx->iOp;
- pAuxData->iAuxArg = iArg;
- pAuxData->pNextAux = pVdbe->pAuxData;
+ pAuxData->iAuxOp = pCtx->iOp;
+ pAuxData->iAuxArg = iArg;
+ pAuxData->pNextAux = pVdbe->pAuxData;
pVdbe->pAuxData = pAuxData;
if( pCtx->isError==0 ) pCtx->isError = -1;
- }else if( pAuxData->xDeleteAux ){
- pAuxData->xDeleteAux(pAuxData->pAux);
+ }else if( pAuxData->xDeleteAux ){
+ pAuxData->xDeleteAux(pAuxData->pAux);
}
pAuxData->pAux = pAux;
- pAuxData->xDeleteAux = xDelete;
+ pAuxData->xDeleteAux = xDelete;
return;
failed:
@@ -85437,8 +85437,8 @@ failed:
** implementations should keep their own counts within their aggregate
** context.
*/
-SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
- assert( p && p->pMem && p->pFunc && p->pFunc->xFinalize );
+SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
+ assert( p && p->pMem && p->pFunc && p->pFunc->xFinalize );
return p->pMem->n;
}
#endif
@@ -85446,7 +85446,7 @@ SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
/*
** Return the number of columns in the result set for the statement pStmt.
*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
return pVm ? pVm->nResColumn : 0;
}
@@ -85455,7 +85455,7 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
** Return the number of values available from the current row of the
** currently executing statement pStmt.
*/
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
if( pVm==0 || pVm->pResultSet==0 ) return 0;
return pVm->nResColumn;
@@ -85480,18 +85480,18 @@ static const Mem *columnNullValue(void){
#endif
= {
/* .u = */ {0},
- /* .flags = */ (u16)MEM_Null,
- /* .enc = */ (u8)0,
- /* .eSubtype = */ (u8)0,
- /* .n = */ (int)0,
- /* .z = */ (char*)0,
- /* .zMalloc = */ (char*)0,
- /* .szMalloc = */ (int)0,
- /* .uTemp = */ (u32)0,
- /* .db = */ (sqlite3*)0,
- /* .xDel = */ (void(*)(void*))0,
+ /* .flags = */ (u16)MEM_Null,
+ /* .enc = */ (u8)0,
+ /* .eSubtype = */ (u8)0,
+ /* .n = */ (int)0,
+ /* .z = */ (char*)0,
+ /* .zMalloc = */ (char*)0,
+ /* .szMalloc = */ (int)0,
+ /* .uTemp = */ (u32)0,
+ /* .db = */ (sqlite3*)0,
+ /* .xDel = */ (void(*)(void*))0,
#ifdef SQLITE_DEBUG
- /* .pScopyFrom = */ (Mem*)0,
+ /* .pScopyFrom = */ (Mem*)0,
/* .mScopyFlags= */ 0,
#endif
};
@@ -85509,13 +85509,13 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
Mem *pOut;
pVm = (Vdbe *)pStmt;
- if( pVm==0 ) return (Mem*)columnNullValue();
- assert( pVm->db );
- sqlite3_mutex_enter(pVm->db->mutex);
- if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
+ if( pVm==0 ) return (Mem*)columnNullValue();
+ assert( pVm->db );
+ sqlite3_mutex_enter(pVm->db->mutex);
+ if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
pOut = &pVm->pResultSet[i];
}else{
- sqlite3Error(pVm->db, SQLITE_RANGE);
+ sqlite3Error(pVm->db, SQLITE_RANGE);
pOut = (Mem*)columnNullValue();
}
return pOut;
@@ -85548,8 +85548,8 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
*/
Vdbe *p = (Vdbe *)pStmt;
if( p ){
- assert( p->db!=0 );
- assert( sqlite3_mutex_held(p->db->mutex) );
+ assert( p->db!=0 );
+ assert( sqlite3_mutex_held(p->db->mutex) );
p->rc = sqlite3ApiExit(p->db, p->rc);
sqlite3_mutex_leave(p->db->mutex);
}
@@ -85559,7 +85559,7 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
** The following routines are used to access elements of the current row
** in the result set.
*/
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
+SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
const void *val;
val = sqlite3_value_blob( columnMem(pStmt,i) );
/* Even though there is no encoding conversion, value_blob() might
@@ -85569,37 +85569,37 @@ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_bytes( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_bytes16( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
+SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
double val = sqlite3_value_double( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_int( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
+SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
+SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
+SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
Mem *pOut = columnMem(pStmt, i);
if( pOut->flags&MEM_Static ){
pOut->flags &= ~MEM_Static;
@@ -85609,13 +85609,13 @@ SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
return (sqlite3_value *)pOut;
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
+SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
const void *val = sqlite3_value_text16( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
int iType = sqlite3_value_type( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return iType;
@@ -85674,7 +85674,7 @@ static const void *columnName(
** is the case, clear the mallocFailed flag and return NULL.
*/
if( db->mallocFailed ){
- sqlite3OomClear(db);
+ sqlite3OomClear(db);
ret = 0;
}
sqlite3_mutex_leave(db->mutex);
@@ -85686,11 +85686,11 @@ static const void *columnName(
** Return the name of the Nth column of the result set returned by SQL
** statement pStmt.
*/
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
return columnName(pStmt, N, 0, COLNAME_NAME);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
return columnName(pStmt, N, 1, COLNAME_NAME);
}
#endif
@@ -85709,11 +85709,11 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt.
*/
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
return columnName(pStmt, N, 0, COLNAME_DECLTYPE);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
return columnName(pStmt, N, 1, COLNAME_DECLTYPE);
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -85725,11 +85725,11 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
return columnName(pStmt, N, 0, COLNAME_DATABASE);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
return columnName(pStmt, N, 1, COLNAME_DATABASE);
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -85739,11 +85739,11 @@ SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
return columnName(pStmt, N, 0, COLNAME_TABLE);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
return columnName(pStmt, N, 1, COLNAME_TABLE);
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -85753,11 +85753,11 @@ SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
return columnName(pStmt, N, 0, COLNAME_COLUMN);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
return columnName(pStmt, N, 1, COLNAME_COLUMN);
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -85812,8 +85812,8 @@ static int vdbeUnbind(Vdbe *p, int i){
** as if there had been a schema change, on the first sqlite3_step() call
** following any change to the bindings of that parameter.
*/
- assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 );
- if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<<i))!=0 ){
+ assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 );
+ if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<<i))!=0 ){
p->expired = 1;
}
return SQLITE_OK;
@@ -85842,10 +85842,10 @@ static int bindText(
if( rc==SQLITE_OK && encoding!=0 ){
rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
}
- if( rc ){
- sqlite3Error(p->db, rc);
- rc = sqlite3ApiExit(p->db, rc);
- }
+ if( rc ){
+ sqlite3Error(p->db, rc);
+ rc = sqlite3ApiExit(p->db, rc);
+ }
}
sqlite3_mutex_leave(p->db->mutex);
}else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){
@@ -85858,19 +85858,19 @@ static int bindText(
/*
** Bind a blob value to an SQL statement variable.
*/
-SQLITE_API int sqlite3_bind_blob(
+SQLITE_API int sqlite3_bind_blob(
sqlite3_stmt *pStmt,
int i,
const void *zData,
int nData,
void (*xDel)(void*)
){
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( nData<0 ) return SQLITE_MISUSE_BKPT;
-#endif
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( nData<0 ) return SQLITE_MISUSE_BKPT;
+#endif
return bindText(pStmt, i, zData, nData, xDel, 0);
}
-SQLITE_API int sqlite3_bind_blob64(
+SQLITE_API int sqlite3_bind_blob64(
sqlite3_stmt *pStmt,
int i,
const void *zData,
@@ -85880,7 +85880,7 @@ SQLITE_API int sqlite3_bind_blob64(
assert( xDel!=SQLITE_DYNAMIC );
return bindText(pStmt, i, zData, nData, xDel, 0);
}
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
+SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -85890,10 +85890,10 @@ SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
}
return rc;
}
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
+SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
return sqlite3_bind_int64(p, i, (i64)iValue);
}
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
+SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -85903,33 +85903,33 @@ SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValu
}
return rc;
}
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
+ int rc;
+ Vdbe *p = (Vdbe*)pStmt;
+ rc = vdbeUnbind(p, i);
+ if( rc==SQLITE_OK ){
+ sqlite3_mutex_leave(p->db->mutex);
+ }
+ return rc;
+}
+SQLITE_API int sqlite3_bind_pointer(
+ sqlite3_stmt *pStmt,
+ int i,
+ void *pPtr,
+ const char *zPTtype,
+ void (*xDestructor)(void*)
+){
int rc;
Vdbe *p = (Vdbe*)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
+ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor);
sqlite3_mutex_leave(p->db->mutex);
+ }else if( xDestructor ){
+ xDestructor(pPtr);
}
return rc;
}
-SQLITE_API int sqlite3_bind_pointer(
- sqlite3_stmt *pStmt,
- int i,
- void *pPtr,
- const char *zPTtype,
- void (*xDestructor)(void*)
-){
- int rc;
- Vdbe *p = (Vdbe*)pStmt;
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor);
- sqlite3_mutex_leave(p->db->mutex);
- }else if( xDestructor ){
- xDestructor(pPtr);
- }
- return rc;
-}
SQLITE_API int sqlite3_bind_text(
sqlite3_stmt *pStmt,
int i,
@@ -85952,7 +85952,7 @@ SQLITE_API int sqlite3_bind_text64(
return bindText(pStmt, i, zData, nData, xDel, enc);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int sqlite3_bind_text16(
+SQLITE_API int sqlite3_bind_text16(
sqlite3_stmt *pStmt,
int i,
const void *zData,
@@ -85962,7 +85962,7 @@ SQLITE_API int sqlite3_bind_text16(
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
}
#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
+SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
int rc;
switch( sqlite3_value_type((sqlite3_value*)pValue) ){
case SQLITE_INTEGER: {
@@ -85993,7 +85993,7 @@ SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_valu
}
return rc;
}
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
+SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -86007,7 +86007,7 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
}
return rc;
}
-SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
+SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
int rc;
Vdbe *p = (Vdbe *)pStmt;
sqlite3_mutex_enter(p->db->mutex);
@@ -86026,7 +86026,7 @@ SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint6
** Return the number of wildcards that can be potentially bound to.
** This routine is added to support DBD::SQLite.
*/
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p ? p->nVar : 0;
}
@@ -86037,10 +86037,10 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
**
** The result is always UTF-8.
*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
+SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
Vdbe *p = (Vdbe*)pStmt;
- if( p==0 ) return 0;
- return sqlite3VListNumToName(p->pVList, i);
+ if( p==0 ) return 0;
+ return sqlite3VListNumToName(p->pVList, i);
}
/*
@@ -86049,10 +86049,10 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
** return 0.
*/
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
- if( p==0 || zName==0 ) return 0;
- return sqlite3VListNameToNum(p->pVList, zName, nName);
+ if( p==0 || zName==0 ) return 0;
+ return sqlite3VListNameToNum(p->pVList, zName, nName);
}
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
+SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
}
@@ -86086,18 +86086,18 @@ SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt
** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise
** SQLITE_OK is returned.
*/
-SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
+SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
Vdbe *pFrom = (Vdbe*)pFromStmt;
Vdbe *pTo = (Vdbe*)pToStmt;
if( pFrom->nVar!=pTo->nVar ){
return SQLITE_ERROR;
}
- assert( (pTo->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || pTo->expmask==0 );
- if( pTo->expmask ){
+ assert( (pTo->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || pTo->expmask==0 );
+ if( pTo->expmask ){
pTo->expired = 1;
}
- assert( (pFrom->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || pFrom->expmask==0 );
- if( pFrom->expmask ){
+ assert( (pFrom->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || pFrom->expmask==0 );
+ if( pFrom->expmask ){
pFrom->expired = 1;
}
return sqlite3TransferBindings(pFromStmt, pToStmt);
@@ -86110,7 +86110,7 @@ SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
+SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->db : 0;
}
@@ -86118,7 +86118,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
** Return true if the prepared statement is guaranteed to not modify the
** database.
*/
-SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
}
@@ -86133,7 +86133,7 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){
/*
** Return true if the prepared statement is in need of being reset.
*/
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
Vdbe *v = (Vdbe*)pStmt;
return v!=0 && v->iVdbeMagic==VDBE_MAGIC_RUN && v->pc>=0;
}
@@ -86144,7 +86144,7 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
** prepared statement for the database connection. Return NULL if there
** are no more.
*/
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
+SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
sqlite3_stmt *pNext;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(pDb) ){
@@ -86165,7 +86165,7 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
/*
** Return the value of a status counter for a prepared statement
*/
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
+SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
u32 v;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -86176,55 +86176,55 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
return 0;
}
#endif
- if( op==SQLITE_STMTSTATUS_MEMUSED ){
- sqlite3 *db = pVdbe->db;
- sqlite3_mutex_enter(db->mutex);
- v = 0;
- db->pnBytesFreed = (int*)&v;
- sqlite3VdbeClearObject(db, pVdbe);
- sqlite3DbFree(db, pVdbe);
- db->pnBytesFreed = 0;
- sqlite3_mutex_leave(db->mutex);
- }else{
- v = pVdbe->aCounter[op];
- if( resetFlag ) pVdbe->aCounter[op] = 0;
- }
+ if( op==SQLITE_STMTSTATUS_MEMUSED ){
+ sqlite3 *db = pVdbe->db;
+ sqlite3_mutex_enter(db->mutex);
+ v = 0;
+ db->pnBytesFreed = (int*)&v;
+ sqlite3VdbeClearObject(db, pVdbe);
+ sqlite3DbFree(db, pVdbe);
+ db->pnBytesFreed = 0;
+ sqlite3_mutex_leave(db->mutex);
+ }else{
+ v = pVdbe->aCounter[op];
+ if( resetFlag ) pVdbe->aCounter[op] = 0;
+ }
return (int)v;
}
-/*
-** Return the SQL associated with a prepared statement
-*/
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){
- Vdbe *p = (Vdbe *)pStmt;
- return p ? p->zSql : 0;
-}
-
-/*
-** Return the SQL associated with a prepared statement with
-** bound parameters expanded. Space to hold the returned string is
-** obtained from sqlite3_malloc(). The caller is responsible for
-** freeing the returned string by passing it to sqlite3_free().
-**
-** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of
-** expanded bound parameters.
-*/
-SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
-#ifdef SQLITE_OMIT_TRACE
- return 0;
-#else
- char *z = 0;
- const char *zSql = sqlite3_sql(pStmt);
- if( zSql ){
- Vdbe *p = (Vdbe *)pStmt;
- sqlite3_mutex_enter(p->db->mutex);
- z = sqlite3VdbeExpandSql(p, zSql);
- sqlite3_mutex_leave(p->db->mutex);
- }
- return z;
-#endif
-}
-
+/*
+** Return the SQL associated with a prepared statement
+*/
+SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){
+ Vdbe *p = (Vdbe *)pStmt;
+ return p ? p->zSql : 0;
+}
+
+/*
+** Return the SQL associated with a prepared statement with
+** bound parameters expanded. Space to hold the returned string is
+** obtained from sqlite3_malloc(). The caller is responsible for
+** freeing the returned string by passing it to sqlite3_free().
+**
+** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of
+** expanded bound parameters.
+*/
+SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
+#ifdef SQLITE_OMIT_TRACE
+ return 0;
+#else
+ char *z = 0;
+ const char *zSql = sqlite3_sql(pStmt);
+ if( zSql ){
+ Vdbe *p = (Vdbe *)pStmt;
+ sqlite3_mutex_enter(p->db->mutex);
+ z = sqlite3VdbeExpandSql(p, zSql);
+ sqlite3_mutex_leave(p->db->mutex);
+ }
+ return z;
+#endif
+}
+
#ifdef SQLITE_ENABLE_NORMALIZE
/*
** Return the normalized SQL associated with a prepared statement.
@@ -86241,121 +86241,121 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){
}
#endif /* SQLITE_ENABLE_NORMALIZE */
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
-/*
-** Allocate and populate an UnpackedRecord structure based on the serialized
-** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure
-** if successful, or a NULL pointer if an OOM error is encountered.
-*/
-static UnpackedRecord *vdbeUnpackRecord(
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** Allocate and populate an UnpackedRecord structure based on the serialized
+** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure
+** if successful, or a NULL pointer if an OOM error is encountered.
+*/
+static UnpackedRecord *vdbeUnpackRecord(
KeyInfo *pKeyInfo,
int nKey,
- const void *pKey
-){
- UnpackedRecord *pRet; /* Return value */
-
- pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
- if( pRet ){
- memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1));
- sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet);
- }
- return pRet;
-}
-
-/*
-** This function is called from within a pre-update callback to retrieve
-** a field of the row currently being updated or deleted.
-*/
-SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
- PreUpdate *p = db->pPreUpdate;
- Mem *pMem;
- int rc = SQLITE_OK;
-
- /* Test that this call is being made from within an SQLITE_DELETE or
- ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
- if( !p || p->op==SQLITE_INSERT ){
- rc = SQLITE_MISUSE_BKPT;
- goto preupdate_old_out;
- }
- if( p->pPk ){
+ const void *pKey
+){
+ UnpackedRecord *pRet; /* Return value */
+
+ pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
+ if( pRet ){
+ memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1));
+ sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet);
+ }
+ return pRet;
+}
+
+/*
+** This function is called from within a pre-update callback to retrieve
+** a field of the row currently being updated or deleted.
+*/
+SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
+ PreUpdate *p = db->pPreUpdate;
+ Mem *pMem;
+ int rc = SQLITE_OK;
+
+ /* Test that this call is being made from within an SQLITE_DELETE or
+ ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
+ if( !p || p->op==SQLITE_INSERT ){
+ rc = SQLITE_MISUSE_BKPT;
+ goto preupdate_old_out;
+ }
+ if( p->pPk ){
iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx);
- }
- if( iIdx>=p->pCsr->nField || iIdx<0 ){
- rc = SQLITE_RANGE;
- goto preupdate_old_out;
- }
-
- /* If the old.* record has not yet been loaded into memory, do so now. */
- if( p->pUnpacked==0 ){
- u32 nRec;
- u8 *aRec;
-
+ }
+ if( iIdx>=p->pCsr->nField || iIdx<0 ){
+ rc = SQLITE_RANGE;
+ goto preupdate_old_out;
+ }
+
+ /* If the old.* record has not yet been loaded into memory, do so now. */
+ if( p->pUnpacked==0 ){
+ u32 nRec;
+ u8 *aRec;
+
assert( p->pCsr->eCurType==CURTYPE_BTREE );
- nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
- aRec = sqlite3DbMallocRaw(db, nRec);
- if( !aRec ) goto preupdate_old_out;
- rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
- if( rc==SQLITE_OK ){
- p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec);
- if( !p->pUnpacked ) rc = SQLITE_NOMEM;
- }
- if( rc!=SQLITE_OK ){
- sqlite3DbFree(db, aRec);
- goto preupdate_old_out;
- }
- p->aRecord = aRec;
- }
-
- pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
- if( iIdx==p->pTab->iPKey ){
- sqlite3VdbeMemSetInt64(pMem, p->iKey1);
- }else if( iIdx>=p->pUnpacked->nField ){
- *ppValue = (sqlite3_value *)columnNullValue();
- }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
+ nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
+ aRec = sqlite3DbMallocRaw(db, nRec);
+ if( !aRec ) goto preupdate_old_out;
+ rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
+ if( rc==SQLITE_OK ){
+ p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec);
+ if( !p->pUnpacked ) rc = SQLITE_NOMEM;
+ }
+ if( rc!=SQLITE_OK ){
+ sqlite3DbFree(db, aRec);
+ goto preupdate_old_out;
+ }
+ p->aRecord = aRec;
+ }
+
+ pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
+ if( iIdx==p->pTab->iPKey ){
+ sqlite3VdbeMemSetInt64(pMem, p->iKey1);
+ }else if( iIdx>=p->pUnpacked->nField ){
+ *ppValue = (sqlite3_value *)columnNullValue();
+ }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
if( pMem->flags & (MEM_Int|MEM_IntReal) ){
testcase( pMem->flags & MEM_Int );
testcase( pMem->flags & MEM_IntReal );
- sqlite3VdbeMemRealify(pMem);
- }
- }
-
- preupdate_old_out:
- sqlite3Error(db, rc);
- return sqlite3ApiExit(db, rc);
-}
-#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
-
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
-/*
-** This function is called from within a pre-update callback to retrieve
-** the number of columns in the row being updated, deleted or inserted.
-*/
-SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){
- PreUpdate *p = db->pPreUpdate;
- return (p ? p->keyinfo.nKeyField : 0);
-}
-#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
-
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
-/*
-** This function is designed to be called from within a pre-update callback
-** only. It returns zero if the change that caused the callback was made
-** immediately by a user SQL statement. Or, if the change was made by a
-** trigger program, it returns the number of trigger programs currently
+ sqlite3VdbeMemRealify(pMem);
+ }
+ }
+
+ preupdate_old_out:
+ sqlite3Error(db, rc);
+ return sqlite3ApiExit(db, rc);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** This function is called from within a pre-update callback to retrieve
+** the number of columns in the row being updated, deleted or inserted.
+*/
+SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){
+ PreUpdate *p = db->pPreUpdate;
+ return (p ? p->keyinfo.nKeyField : 0);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** This function is designed to be called from within a pre-update callback
+** only. It returns zero if the change that caused the callback was made
+** immediately by a user SQL statement. Or, if the change was made by a
+** trigger program, it returns the number of trigger programs currently
** on the stack (1 for a top-level trigger, 2 for a trigger fired by a
-** top-level trigger etc.).
-**
-** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL
-** or SET DEFAULT action is considered a trigger.
-*/
-SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){
- PreUpdate *p = db->pPreUpdate;
- return (p ? p->v->nFrame : 0);
-}
-#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
-
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
-/*
+** top-level trigger etc.).
+**
+** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL
+** or SET DEFAULT action is considered a trigger.
+*/
+SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){
+ PreUpdate *p = db->pPreUpdate;
+ return (p ? p->v->nFrame : 0);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
** This function is designed to be called from within a pre-update callback
** only.
*/
@@ -86367,85 +86367,85 @@ SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *db){
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
/*
-** This function is called from within a pre-update callback to retrieve
-** a field of the row currently being updated or inserted.
-*/
-SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
- PreUpdate *p = db->pPreUpdate;
- int rc = SQLITE_OK;
- Mem *pMem;
-
- if( !p || p->op==SQLITE_DELETE ){
- rc = SQLITE_MISUSE_BKPT;
- goto preupdate_new_out;
- }
- if( p->pPk && p->op!=SQLITE_UPDATE ){
+** This function is called from within a pre-update callback to retrieve
+** a field of the row currently being updated or inserted.
+*/
+SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
+ PreUpdate *p = db->pPreUpdate;
+ int rc = SQLITE_OK;
+ Mem *pMem;
+
+ if( !p || p->op==SQLITE_DELETE ){
+ rc = SQLITE_MISUSE_BKPT;
+ goto preupdate_new_out;
+ }
+ if( p->pPk && p->op!=SQLITE_UPDATE ){
iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx);
- }
- if( iIdx>=p->pCsr->nField || iIdx<0 ){
- rc = SQLITE_RANGE;
- goto preupdate_new_out;
- }
-
- if( p->op==SQLITE_INSERT ){
- /* For an INSERT, memory cell p->iNewReg contains the serialized record
- ** that is being inserted. Deserialize it. */
- UnpackedRecord *pUnpack = p->pNewUnpacked;
- if( !pUnpack ){
- Mem *pData = &p->v->aMem[p->iNewReg];
- rc = ExpandBlob(pData);
- if( rc!=SQLITE_OK ) goto preupdate_new_out;
- pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z);
- if( !pUnpack ){
- rc = SQLITE_NOMEM;
- goto preupdate_new_out;
- }
- p->pNewUnpacked = pUnpack;
- }
- pMem = &pUnpack->aMem[iIdx];
- if( iIdx==p->pTab->iPKey ){
- sqlite3VdbeMemSetInt64(pMem, p->iKey2);
- }else if( iIdx>=pUnpack->nField ){
- pMem = (sqlite3_value *)columnNullValue();
- }
- }else{
- /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
- ** value. Make a copy of the cell contents and return a pointer to it.
- ** It is not safe to return a pointer to the memory cell itself as the
- ** caller may modify the value text encoding.
- */
- assert( p->op==SQLITE_UPDATE );
- if( !p->aNew ){
- p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField);
- if( !p->aNew ){
- rc = SQLITE_NOMEM;
- goto preupdate_new_out;
- }
- }
- assert( iIdx>=0 && iIdx<p->pCsr->nField );
- pMem = &p->aNew[iIdx];
- if( pMem->flags==0 ){
- if( iIdx==p->pTab->iPKey ){
- sqlite3VdbeMemSetInt64(pMem, p->iKey2);
- }else{
- rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
- if( rc!=SQLITE_OK ) goto preupdate_new_out;
- }
- }
- }
- *ppValue = pMem;
-
- preupdate_new_out:
- sqlite3Error(db, rc);
- return sqlite3ApiExit(db, rc);
-}
-#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
-
+ }
+ if( iIdx>=p->pCsr->nField || iIdx<0 ){
+ rc = SQLITE_RANGE;
+ goto preupdate_new_out;
+ }
+
+ if( p->op==SQLITE_INSERT ){
+ /* For an INSERT, memory cell p->iNewReg contains the serialized record
+ ** that is being inserted. Deserialize it. */
+ UnpackedRecord *pUnpack = p->pNewUnpacked;
+ if( !pUnpack ){
+ Mem *pData = &p->v->aMem[p->iNewReg];
+ rc = ExpandBlob(pData);
+ if( rc!=SQLITE_OK ) goto preupdate_new_out;
+ pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z);
+ if( !pUnpack ){
+ rc = SQLITE_NOMEM;
+ goto preupdate_new_out;
+ }
+ p->pNewUnpacked = pUnpack;
+ }
+ pMem = &pUnpack->aMem[iIdx];
+ if( iIdx==p->pTab->iPKey ){
+ sqlite3VdbeMemSetInt64(pMem, p->iKey2);
+ }else if( iIdx>=pUnpack->nField ){
+ pMem = (sqlite3_value *)columnNullValue();
+ }
+ }else{
+ /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
+ ** value. Make a copy of the cell contents and return a pointer to it.
+ ** It is not safe to return a pointer to the memory cell itself as the
+ ** caller may modify the value text encoding.
+ */
+ assert( p->op==SQLITE_UPDATE );
+ if( !p->aNew ){
+ p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField);
+ if( !p->aNew ){
+ rc = SQLITE_NOMEM;
+ goto preupdate_new_out;
+ }
+ }
+ assert( iIdx>=0 && iIdx<p->pCsr->nField );
+ pMem = &p->aNew[iIdx];
+ if( pMem->flags==0 ){
+ if( iIdx==p->pTab->iPKey ){
+ sqlite3VdbeMemSetInt64(pMem, p->iKey2);
+ }else{
+ rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
+ if( rc!=SQLITE_OK ) goto preupdate_new_out;
+ }
+ }
+ }
+ *ppValue = pMem;
+
+ preupdate_new_out:
+ sqlite3Error(db, rc);
+ return sqlite3ApiExit(db, rc);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
/*
** Return status data for a single loop within query pStmt.
*/
-SQLITE_API int sqlite3_stmt_scanstatus(
+SQLITE_API int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement being queried */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Which metric to return */
@@ -86504,7 +86504,7 @@ SQLITE_API int sqlite3_stmt_scanstatus(
/*
** Zero all counters associated with the sqlite3_stmt_scanstatus() data.
*/
-SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
+SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
memset(p->anExec, 0, p->nOp * sizeof(i64));
}
@@ -86595,9 +86595,9 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
int i; /* Loop counter */
Mem *pVar; /* Value of a host parameter */
StrAccum out; /* Accumulate the output here */
-#ifndef SQLITE_OMIT_UTF16
- Mem utf8; /* Used to convert UTF16 into UTF8 for display */
-#endif
+#ifndef SQLITE_OMIT_UTF16
+ Mem utf8; /* Used to convert UTF16 into UTF8 for display */
+#endif
db = p->db;
sqlite3StrAccumInit(&out, 0, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
@@ -86654,10 +86654,10 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
memset(&utf8, 0, sizeof(utf8));
utf8.db = db;
sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
- if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
+ if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
out.accError = SQLITE_NOMEM;
- out.nAlloc = 0;
- }
+ out.nAlloc = 0;
+ }
pVar = &utf8;
}
#endif
@@ -86796,16 +86796,16 @@ static void updateMaxBlobsize(Mem *p){
#endif
/*
-** This macro evaluates to true if either the update hook or the preupdate
-** hook are enabled for database connect DB.
-*/
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
-# define HAS_UPDATE_HOOK(DB) ((DB)->xPreUpdateCallback||(DB)->xUpdateCallback)
-#else
-# define HAS_UPDATE_HOOK(DB) ((DB)->xUpdateCallback)
-#endif
-
-/*
+** This macro evaluates to true if either the update hook or the preupdate
+** hook are enabled for database connect DB.
+*/
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+# define HAS_UPDATE_HOOK(DB) ((DB)->xPreUpdateCallback||(DB)->xUpdateCallback)
+#else
+# define HAS_UPDATE_HOOK(DB) ((DB)->xUpdateCallback)
+#endif
+
+/*
** The next global variable is incremented each time the OP_Found opcode
** is executed. This is used to test whether or not the foreign key
** operation implemented using OP_FkIsZero is working. This variable
@@ -86820,7 +86820,7 @@ SQLITE_API int sqlite3_found_count = 0;
** Test a register to see if it exceeds the current maximum blob size.
** If it does, record the new maximum blob size.
*/
-#if defined(SQLITE_TEST) && !defined(SQLITE_UNTESTABLE)
+#if defined(SQLITE_TEST) && !defined(SQLITE_UNTESTABLE)
# define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P)
#else
# define UPDATE_MAX_BLOBSIZE(P)
@@ -86940,7 +86940,7 @@ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){
&& sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}
/* Return true if the cursor was opened using the OP_OpenSorter opcode. */
-#define isSorter(x) ((x)->eCurType==CURTYPE_SORTER)
+#define isSorter(x) ((x)->eCurType==CURTYPE_SORTER)
/*
** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL
@@ -86951,7 +86951,7 @@ static VdbeCursor *allocateCursor(
int iCur, /* Index of the new VdbeCursor */
int nField, /* Number of fields in the table or index */
int iDb, /* Database the cursor belongs to, or -1 */
- u8 eCurType /* Type of the new cursor */
+ u8 eCurType /* Type of the new cursor */
){
/* Find the memory cell that will be used to store the blob of memory
** required for this VdbeCursor structure. It is convenient to use a
@@ -86967,20 +86967,20 @@ static VdbeCursor *allocateCursor(
** be freed lazily via the sqlite3_release_memory() API. This
** minimizes the number of malloc calls made by the system.
**
- ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from
- ** the top of the register space. Cursor 1 is at Mem[p->nMem-1].
- ** Cursor 2 is at Mem[p->nMem-2]. And so forth.
+ ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from
+ ** the top of the register space. Cursor 1 is at Mem[p->nMem-1].
+ ** Cursor 2 is at Mem[p->nMem-2]. And so forth.
*/
- Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem;
+ Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem;
int nByte;
VdbeCursor *pCx = 0;
nByte =
ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField +
- (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);
+ (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);
- assert( iCur>=0 && iCur<p->nCursor );
- if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
+ assert( iCur>=0 && iCur<p->nCursor );
+ if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
p->apCsr[iCur] = 0;
}
@@ -87096,7 +87096,7 @@ static void applyAffinity(
if( affinity>=SQLITE_AFF_NUMERIC ){
assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
|| affinity==SQLITE_AFF_NUMERIC );
- if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/
+ if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/
if( (pRec->flags & MEM_Real)==0 ){
if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1);
}else{
@@ -87107,15 +87107,15 @@ static void applyAffinity(
/* Only attempt the conversion to TEXT if there is an integer or real
** representation (blob and NULL do not get converted) but no string
** representation. It would be harmless to repeat the conversion if
- ** there is already a string rep, but it is pointless to waste those
- ** CPU cycles. */
- if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
+ ** there is already a string rep, but it is pointless to waste those
+ ** CPU cycles. */
+ if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){
testcase( pRec->flags & MEM_Int );
testcase( pRec->flags & MEM_Real );
testcase( pRec->flags & MEM_IntReal );
- sqlite3VdbeMemStringify(pRec, enc, 1);
- }
+ sqlite3VdbeMemStringify(pRec, enc, 1);
+ }
}
pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal);
}
@@ -87127,7 +87127,7 @@ static void applyAffinity(
** is appropriate. But only do the conversion if it is possible without
** loss of information and return the revised type of the argument.
*/
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){
int eType = sqlite3_value_type(pVal);
if( eType==SQLITE_TEXT ){
Mem *pMem = (Mem*)pVal;
@@ -87270,7 +87270,7 @@ static void memTracePrint(Mem *p){
if( p->flags & MEM_Undefined ){
printf(" undefined");
}else if( p->flags & MEM_Null ){
- printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
+ printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
printf(" si:%lld", p->u.i);
}else if( (p->flags & (MEM_IntReal))!=0 ){
@@ -87290,7 +87290,7 @@ static void memTracePrint(Mem *p){
sqlite3VdbeMemPrettyPrint(p, &acc);
printf(" %s", sqlite3StrAccumFinish(&acc));
}
- if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
+ if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
}
static void registerTrace(int iReg, Mem *p){
printf("R[%d] = ", iReg);
@@ -87299,7 +87299,7 @@ static void registerTrace(int iReg, Mem *p){
printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg]));
}
printf("\n");
- sqlite3VdbeCheckMemInvariants(p);
+ sqlite3VdbeCheckMemInvariants(p);
}
/**/ void sqlite3PrintMem(Mem *pMem){
memTracePrint(pMem);
@@ -87360,24 +87360,24 @@ static int checkSavepointCount(sqlite3 *db){
/*
** Return the register of pOp->p2 after first preparing it to be
** overwritten with an integer value.
-*/
-static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){
- sqlite3VdbeMemSetNull(pOut);
- pOut->flags = MEM_Int;
- return pOut;
-}
+*/
+static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){
+ sqlite3VdbeMemSetNull(pOut);
+ pOut->flags = MEM_Int;
+ return pOut;
+}
static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
Mem *pOut;
assert( pOp->p2>0 );
- assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
+ assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
pOut = &p->aMem[pOp->p2];
memAboutToChange(p, pOut);
- if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/
- return out2PrereleaseWithClear(pOut);
- }else{
- pOut->flags = MEM_Int;
- return pOut;
- }
+ if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/
+ return out2PrereleaseWithClear(pOut);
+ }else{
+ pOut->flags = MEM_Int;
+ return pOut;
+ }
}
/*
@@ -87406,14 +87406,14 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
Op *pOrigOp; /* Value of pOp at the top of the loop */
#endif
-#ifdef SQLITE_DEBUG
- int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */
-#endif
+#ifdef SQLITE_DEBUG
+ int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */
+#endif
int rc = SQLITE_OK; /* Value to return */
sqlite3 *db = p->db; /* The database */
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
u8 encoding = ENC(db); /* The database encoding */
- int iCompare = 0; /* Result of last comparison */
+ int iCompare = 0; /* Result of last comparison */
u64 nVmStep = 0; /* Number of virtual machine steps */
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
u64 nProgressLimit; /* Invoke xProgress() when nVmStep reaches this */
@@ -87444,7 +87444,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
** sqlite3_column_text16() failed. */
goto no_mem;
}
- assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
+ assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
testcase( p->rc!=SQLITE_OK );
p->rc = SQLITE_OK;
assert( p->bIsReader || p->readOnly!=0 );
@@ -87481,11 +87481,11 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
}
sqlite3EndBenignMalloc();
#endif
- for(pOp=&aOp[p->pc]; 1; pOp++){
- /* Errors are detected by individual opcodes, with an immediate
- ** jumps to abort_due_to_error. */
- assert( rc==SQLITE_OK );
-
+ for(pOp=&aOp[p->pc]; 1; pOp++){
+ /* Errors are detected by individual opcodes, with an immediate
+ ** jumps to abort_due_to_error. */
+ assert( rc==SQLITE_OK );
+
assert( pOp>=aOp && pOp<&aOp[p->nOp]);
#ifdef VDBE_PROFILE
start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
@@ -87519,39 +87519,39 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
/* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
- {
- u8 opProperty = sqlite3OpcodeProperty[pOp->opcode];
- if( (opProperty & OPFLG_IN1)!=0 ){
- assert( pOp->p1>0 );
- assert( pOp->p1<=(p->nMem+1 - p->nCursor) );
- assert( memIsValid(&aMem[pOp->p1]) );
- assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
- REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
- }
- if( (opProperty & OPFLG_IN2)!=0 ){
- assert( pOp->p2>0 );
- assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
- assert( memIsValid(&aMem[pOp->p2]) );
- assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
- REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
- }
- if( (opProperty & OPFLG_IN3)!=0 ){
- assert( pOp->p3>0 );
- assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
- assert( memIsValid(&aMem[pOp->p3]) );
- assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
- REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
- }
- if( (opProperty & OPFLG_OUT2)!=0 ){
- assert( pOp->p2>0 );
- assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
- memAboutToChange(p, &aMem[pOp->p2]);
- }
- if( (opProperty & OPFLG_OUT3)!=0 ){
- assert( pOp->p3>0 );
- assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
- memAboutToChange(p, &aMem[pOp->p3]);
- }
+ {
+ u8 opProperty = sqlite3OpcodeProperty[pOp->opcode];
+ if( (opProperty & OPFLG_IN1)!=0 ){
+ assert( pOp->p1>0 );
+ assert( pOp->p1<=(p->nMem+1 - p->nCursor) );
+ assert( memIsValid(&aMem[pOp->p1]) );
+ assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
+ REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
+ }
+ if( (opProperty & OPFLG_IN2)!=0 ){
+ assert( pOp->p2>0 );
+ assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
+ assert( memIsValid(&aMem[pOp->p2]) );
+ assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
+ REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
+ }
+ if( (opProperty & OPFLG_IN3)!=0 ){
+ assert( pOp->p3>0 );
+ assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+ assert( memIsValid(&aMem[pOp->p3]) );
+ assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
+ REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
+ }
+ if( (opProperty & OPFLG_OUT2)!=0 ){
+ assert( pOp->p2>0 );
+ assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
+ memAboutToChange(p, &aMem[pOp->p2]);
+ }
+ if( (opProperty & OPFLG_OUT3)!=0 ){
+ assert( pOp->p3>0 );
+ assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+ memAboutToChange(p, &aMem[pOp->p3]);
+ }
}
#endif
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
@@ -87626,7 +87626,7 @@ jump_to_p2_and_check_for_interrupt:
pOp = &aOp[pOp->p2 - 1];
/* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
- ** OP_VNext, or OP_SorterNext) all jump here upon
+ ** OP_VNext, or OP_SorterNext) all jump here upon
** completion. Check to see if sqlite3_interrupt() has been called
** or if the progress callback needs to be invoked.
**
@@ -87650,7 +87650,7 @@ check_for_interrupt:
if( db->xProgress(db->pProgressArg) ){
nProgressLimit = LARGEST_UINT64;
rc = SQLITE_INTERRUPT;
- goto abort_due_to_error;
+ goto abort_due_to_error;
}
}
#endif
@@ -87664,7 +87664,7 @@ check_for_interrupt:
** and then jump to address P2.
*/
case OP_Gosub: { /* jump */
- assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
pIn1 = &aMem[pOp->p1];
assert( VdbeMemDynamic(pIn1)==0 );
memAboutToChange(p, pIn1);
@@ -87704,7 +87704,7 @@ case OP_Return: { /* in1 */
** See also: EndCoroutine
*/
case OP_InitCoroutine: { /* jump */
- assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
assert( pOp->p2>=0 && pOp->p2<p->nOp );
assert( pOp->p3>=0 && pOp->p3<p->nOp );
pOut = &aMem[pOp->p1];
@@ -87762,7 +87762,7 @@ case OP_Yield: { /* in1, jump */
}
/* Opcode: HaltIfNull P1 P2 P3 P4 P5
-** Synopsis: if r[P3]=null halt
+** Synopsis: if r[P3]=null halt
**
** Check the value in register P3. If it is NULL then Halt using
** parameter P1, P2, and P4 as if this were a Halt instruction. If the
@@ -87840,7 +87840,7 @@ case OP_Halt: {
p->rc = pOp->p1;
p->errorAction = (u8)pOp->p2;
p->pc = pcx;
- assert( pOp->p5<=4 );
+ assert( pOp->p5<=4 );
if( p->rc ){
if( pOp->p5 ){
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
@@ -87849,19 +87849,19 @@ case OP_Halt: {
testcase( pOp->p5==2 );
testcase( pOp->p5==3 );
testcase( pOp->p5==4 );
- sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]);
- if( pOp->p4.z ){
- p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
- }
+ sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]);
+ if( pOp->p4.z ){
+ p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
+ }
}else{
sqlite3VdbeError(p, "%s", pOp->p4.z);
}
- sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg);
+ sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg);
}
rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
if( rc==SQLITE_BUSY ){
- p->rc = SQLITE_BUSY;
+ p->rc = SQLITE_BUSY;
}else{
assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
@@ -87926,7 +87926,7 @@ case OP_String8: { /* same as TK_STRING, out2 */
#ifndef SQLITE_OMIT_UTF16
if( encoding!=SQLITE_UTF8 ){
rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
- assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG );
+ assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG );
if( rc ) goto too_big;
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z );
@@ -87945,7 +87945,7 @@ case OP_String8: { /* same as TK_STRING, out2 */
goto too_big;
}
pOp->opcode = OP_String;
- assert( rc==SQLITE_OK );
+ assert( rc==SQLITE_OK );
/* Fall through to the next case, OP_String */
/* no break */ deliberate_fall_through
}
@@ -87955,12 +87955,12 @@ case OP_String8: { /* same as TK_STRING, out2 */
**
** The string value P4 of length P1 (bytes) is stored in register P2.
**
-** If P3 is not zero and the content of register P3 is equal to P5, then
+** If P3 is not zero and the content of register P3 is equal to P5, then
** the datatype of the register P2 is converted to BLOB. The content is
** the same sequence of bytes, it is merely interpreted as a BLOB instead
-** of a string, as if it had been CAST. In other words:
-**
-** if( P3!=0 and reg[P3]==P5 ) reg[P2] := CAST(reg[P2] as BLOB)
+** of a string, as if it had been CAST. In other words:
+**
+** if( P3!=0 and reg[P3]==P5 ) reg[P2] := CAST(reg[P2] as BLOB)
*/
case OP_String: { /* out2 */
assert( pOp->p4.z!=0 );
@@ -87970,19 +87970,19 @@ case OP_String: { /* out2 */
pOut->n = pOp->p1;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
-#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
- if( pOp->p3>0 ){
- assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ if( pOp->p3>0 ){
+ assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
pIn3 = &aMem[pOp->p3];
assert( pIn3->flags & MEM_Int );
- if( pIn3->u.i==pOp->p5 ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
+ if( pIn3->u.i==pOp->p5 ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
}
-#endif
+#endif
break;
}
/* Opcode: Null P1 P2 P3 * *
-** Synopsis: r[P2..P3]=NULL
+** Synopsis: r[P2..P3]=NULL
**
** Write a NULL into registers P2. If P3 greater than P2, then also write
** NULL into register P3 and every register in between P2 and P3. If P3
@@ -87998,9 +87998,9 @@ case OP_Null: { /* out2 */
u16 nullFlag;
pOut = out2Prerelease(p, pOp);
cnt = pOp->p3-pOp->p2;
- assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+ assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
- pOut->n = 0;
+ pOut->n = 0;
#ifdef SQLITE_DEBUG
pOut->uTemp = 0;
#endif
@@ -88009,14 +88009,14 @@ case OP_Null: { /* out2 */
memAboutToChange(p, pOut);
sqlite3VdbeMemSetNull(pOut);
pOut->flags = nullFlag;
- pOut->n = 0;
+ pOut->n = 0;
cnt--;
}
break;
}
/* Opcode: SoftNull P1 * * * *
-** Synopsis: r[P1]=NULL
+** Synopsis: r[P1]=NULL
**
** Set register P1 to have the value NULL as seen by the OP_MakeRecord
** instruction, but do not free any string or blob memory associated with
@@ -88024,9 +88024,9 @@ case OP_Null: { /* out2 */
** previously copied using OP_SCopy, the copies will continue to be valid.
*/
case OP_SoftNull: {
- assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
pOut = &aMem[pOp->p1];
- pOut->flags = (pOut->flags&~(MEM_Undefined|MEM_AffMask))|MEM_Null;
+ pOut->flags = (pOut->flags&~(MEM_Undefined|MEM_AffMask))|MEM_Null;
break;
}
@@ -88057,12 +88057,12 @@ case OP_Variable: { /* out2 */
Mem *pVar; /* Value being transferred */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
- assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) );
+ assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) );
pVar = &p->aVar[pOp->p1 - 1];
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
- pOut = &aMem[pOp->p2];
+ pOut = &aMem[pOp->p2];
if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
memcpy(pOut, pVar, MEMCELLSIZE);
pOut->flags &= ~(MEM_Dyn|MEM_Ephem);
@@ -88072,7 +88072,7 @@ case OP_Variable: { /* out2 */
}
/* Opcode: Move P1 P2 P3 * *
-** Synopsis: r[P2@P3]=r[P1@P3]
+** Synopsis: r[P2@P3]=r[P1@P3]
**
** Move the P3 values in register P1..P1+P3-1 over into
** registers P2..P2+P3-1. Registers P1..P1+P3-1 are
@@ -88094,8 +88094,8 @@ case OP_Move: {
pIn1 = &aMem[p1];
pOut = &aMem[p2];
do{
- assert( pOut<=&aMem[(p->nMem+1 - p->nCursor)] );
- assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] );
+ assert( pOut<=&aMem[(p->nMem+1 - p->nCursor)] );
+ assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
sqlite3VdbeMemMove(pOut, pIn1);
@@ -88172,22 +88172,22 @@ case OP_SCopy: { /* out2 */
break;
}
-/* Opcode: IntCopy P1 P2 * * *
-** Synopsis: r[P2]=r[P1]
-**
-** Transfer the integer value held in register P1 into register P2.
-**
-** This is an optimized version of SCopy that works only for integer
-** values.
-*/
-case OP_IntCopy: { /* out2 */
- pIn1 = &aMem[pOp->p1];
- assert( (pIn1->flags & MEM_Int)!=0 );
- pOut = &aMem[pOp->p2];
- sqlite3VdbeMemSetInt64(pOut, pIn1->u.i);
- break;
-}
-
+/* Opcode: IntCopy P1 P2 * * *
+** Synopsis: r[P2]=r[P1]
+**
+** Transfer the integer value held in register P1 into register P2.
+**
+** This is an optimized version of SCopy that works only for integer
+** values.
+*/
+case OP_IntCopy: { /* out2 */
+ pIn1 = &aMem[pOp->p1];
+ assert( (pIn1->flags & MEM_Int)!=0 );
+ pOut = &aMem[pOp->p2];
+ sqlite3VdbeMemSetInt64(pOut, pIn1->u.i);
+ break;
+}
+
/* Opcode: ChngCntRow P1 P2 * * *
** Synopsis: output=r[P1]
**
@@ -88209,7 +88209,7 @@ case OP_ChngCntRow: {
}
/* Opcode: ResultRow P1 P2 * * *
-** Synopsis: output=r[P1@P2]
+** Synopsis: output=r[P1@P2]
**
** The registers P1 through P1+P2-1 contain a single row of
** results. This opcode causes the sqlite3_step() call to terminate
@@ -88222,7 +88222,7 @@ case OP_ResultRow: {
int i;
assert( p->nResColumn==pOp->p2 );
assert( pOp->p1>0 || CORRUPT_DB );
- assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
+ assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
/* Invalidate all ephemeral cursor row caches */
p->cacheCtr = (p->cacheCtr + 2)|1;
@@ -88250,10 +88250,10 @@ case OP_ResultRow: {
}
if( db->mallocFailed ) goto no_mem;
- if( db->mTrace & SQLITE_TRACE_ROW ){
+ if( db->mTrace & SQLITE_TRACE_ROW ){
db->trace.xV2(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
- }
-
+ }
+
/* Return SQLITE_ROW
*/
@@ -88334,14 +88334,14 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
}
/* Opcode: Add P1 P2 P3 * *
-** Synopsis: r[P3]=r[P1]+r[P2]
+** Synopsis: r[P3]=r[P1]+r[P2]
**
** Add the value in register P1 to the value in register P2
** and store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: Multiply P1 P2 P3 * *
-** Synopsis: r[P3]=r[P1]*r[P2]
+** Synopsis: r[P3]=r[P1]*r[P2]
**
**
** Multiply the value in register P1 by the value in register P2
@@ -88349,14 +88349,14 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
** If either input is NULL, the result is NULL.
*/
/* Opcode: Subtract P1 P2 P3 * *
-** Synopsis: r[P3]=r[P2]-r[P1]
+** Synopsis: r[P3]=r[P2]-r[P1]
**
** Subtract the value in register P1 from the value in register P2
** and store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: Divide P1 P2 P3 * *
-** Synopsis: r[P3]=r[P2]/r[P1]
+** Synopsis: r[P3]=r[P2]/r[P1]
**
** Divide the value in register P1 by the value in register P2
** and store the result in register P3 (P3=P2/P1). If the value in
@@ -88364,7 +88364,7 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
** NULL, the result is NULL.
*/
/* Opcode: Remainder P1 P2 P3 * *
-** Synopsis: r[P3]=r[P2]%r[P1]
+** Synopsis: r[P3]=r[P2]%r[P1]
**
** Compute the remainder after integer register P2 is divided by
** register P1 and store the result in register P3.
@@ -88412,8 +88412,8 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
}
pOut->u.i = iB;
MemSetTypeFlag(pOut, MEM_Int);
- }else if( (flags & MEM_Null)!=0 ){
- goto arithmetic_result_is_null;
+ }else if( (flags & MEM_Null)!=0 ){
+ goto arithmetic_result_is_null;
}else{
fp_math:
rA = sqlite3VdbeRealValue(pIn1);
@@ -88457,7 +88457,7 @@ arithmetic_result_is_null:
/* Opcode: CollSeq P1 * * P4
**
-** P4 is a pointer to a CollSeq object. If the next call to a user function
+** P4 is a pointer to a CollSeq object. If the next call to a user function
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
** be returned. This is used by the built-in min(), max() and nullif()
** functions.
@@ -88479,21 +88479,21 @@ case OP_CollSeq: {
}
/* Opcode: BitAnd P1 P2 P3 * *
-** Synopsis: r[P3]=r[P1]&r[P2]
+** Synopsis: r[P3]=r[P1]&r[P2]
**
** Take the bit-wise AND of the values in register P1 and P2 and
** store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: BitOr P1 P2 P3 * *
-** Synopsis: r[P3]=r[P1]|r[P2]
+** Synopsis: r[P3]=r[P1]|r[P2]
**
** Take the bit-wise OR of the values in register P1 and P2 and
** store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: ShiftLeft P1 P2 P3 * *
-** Synopsis: r[P3]=r[P2]<<r[P1]
+** Synopsis: r[P3]=r[P2]<<r[P1]
**
** Shift the integer value in register P2 to the left by the
** number of bits specified by the integer in register P1.
@@ -88501,7 +88501,7 @@ case OP_CollSeq: {
** If either input is NULL, the result is NULL.
*/
/* Opcode: ShiftRight P1 P2 P3 * *
-** Synopsis: r[P3]=r[P2]>>r[P1]
+** Synopsis: r[P3]=r[P2]>>r[P1]
**
** Shift the integer value in register P2 to the right by the
** number of bits specified by the integer in register P1.
@@ -88561,7 +88561,7 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
}
/* Opcode: AddImm P1 P2 * * *
-** Synopsis: r[P1]=r[P1]+P2
+** Synopsis: r[P1]=r[P1]+P2
**
** Add the constant P2 to the value in register P1.
** The result is always an integer.
@@ -88631,11 +88631,11 @@ case OP_RealAffinity: { /* in1 */
** Force the value in register P1 to be the type defined by P2.
**
** <ul>
-** <li> P2=='A' &rarr; BLOB
-** <li> P2=='B' &rarr; TEXT
-** <li> P2=='C' &rarr; NUMERIC
-** <li> P2=='D' &rarr; INTEGER
-** <li> P2=='E' &rarr; REAL
+** <li> P2=='A' &rarr; BLOB
+** <li> P2=='B' &rarr; TEXT
+** <li> P2=='C' &rarr; NUMERIC
+** <li> P2=='D' &rarr; INTEGER
+** <li> P2=='E' &rarr; REAL
** </ul>
**
** A NULL value is not changed by this routine. It remains NULL.
@@ -88659,10 +88659,10 @@ case OP_Cast: { /* in1 */
}
#endif /* SQLITE_OMIT_CAST */
-/* Opcode: Eq P1 P2 P3 P4 P5
-** Synopsis: IF r[P3]==r[P1]
+/* Opcode: Eq P1 P2 P3 P4 P5
+** Synopsis: IF r[P3]==r[P1]
**
-** Compare the values in register P1 and P3. If reg(P3)==reg(P1) then
+** Compare the values in register P1 and P3. If reg(P3)==reg(P1) then
** jump to address P2.
**
** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
@@ -88677,75 +88677,75 @@ case OP_Cast: { /* in1 */
** the values are compared. If both values are blobs then memcmp() is
** used to determine the results of the comparison. If both values
** are text, then the appropriate collating function specified in
-** P4 is used to do the comparison. If P4 is not specified then
+** P4 is used to do the comparison. If P4 is not specified then
** memcmp() is used to compare text string. If both values are
** numeric, then a numeric comparison is used. If the two values
** are of different types, then numbers are considered less than
** strings and strings are considered less than blobs.
**
-** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
-** true or false and is never NULL. If both operands are NULL then the result
-** of comparison is true. If either operand is NULL then the result is false.
-** If neither operand is NULL the result is the same as it would be if
-** the SQLITE_NULLEQ flag were omitted from P5.
+** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
+** true or false and is never NULL. If both operands are NULL then the result
+** of comparison is true. If either operand is NULL then the result is false.
+** If neither operand is NULL the result is the same as it would be if
+** the SQLITE_NULLEQ flag were omitted from P5.
**
** This opcode saves the result of comparison for use by the new
** OP_Jump opcode.
*/
/* Opcode: Ne P1 P2 P3 P4 P5
-** Synopsis: IF r[P3]!=r[P1]
+** Synopsis: IF r[P3]!=r[P1]
**
-** This works just like the Eq opcode except that the jump is taken if
-** the operands in registers P1 and P3 are not equal. See the Eq opcode for
+** This works just like the Eq opcode except that the jump is taken if
+** the operands in registers P1 and P3 are not equal. See the Eq opcode for
** additional information.
*/
-/* Opcode: Lt P1 P2 P3 P4 P5
-** Synopsis: IF r[P3]<r[P1]
+/* Opcode: Lt P1 P2 P3 P4 P5
+** Synopsis: IF r[P3]<r[P1]
**
-** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then
+** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then
** jump to address P2.
**
-** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
+** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
** reg(P3) is NULL then the take the jump. If the SQLITE_JUMPIFNULL
-** bit is clear then fall through if either operand is NULL.
-**
-** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
+** bit is clear then fall through if either operand is NULL.
+**
+** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made
-** to coerce both inputs according to this affinity before the
-** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric
-** affinity is used. Note that the affinity conversions are stored
-** back into the input registers P1 and P3. So this opcode can cause
-** persistent changes to registers P1 and P3.
-**
+** to coerce both inputs according to this affinity before the
+** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric
+** affinity is used. Note that the affinity conversions are stored
+** back into the input registers P1 and P3. So this opcode can cause
+** persistent changes to registers P1 and P3.
+**
** Once any conversions have taken place, and neither value is NULL,
-** the values are compared. If both values are blobs then memcmp() is
-** used to determine the results of the comparison. If both values
-** are text, then the appropriate collating function specified in
-** P4 is used to do the comparison. If P4 is not specified then
-** memcmp() is used to compare text string. If both values are
-** numeric, then a numeric comparison is used. If the two values
-** are of different types, then numbers are considered less than
-** strings and strings are considered less than blobs.
+** the values are compared. If both values are blobs then memcmp() is
+** used to determine the results of the comparison. If both values
+** are text, then the appropriate collating function specified in
+** P4 is used to do the comparison. If P4 is not specified then
+** memcmp() is used to compare text string. If both values are
+** numeric, then a numeric comparison is used. If the two values
+** are of different types, then numbers are considered less than
+** strings and strings are considered less than blobs.
**
** This opcode saves the result of comparison for use by the new
** OP_Jump opcode.
*/
/* Opcode: Le P1 P2 P3 P4 P5
-** Synopsis: IF r[P3]<=r[P1]
+** Synopsis: IF r[P3]<=r[P1]
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is less than or equal to the content of
** register P1. See the Lt opcode for additional information.
*/
/* Opcode: Gt P1 P2 P3 P4 P5
-** Synopsis: IF r[P3]>r[P1]
+** Synopsis: IF r[P3]>r[P1]
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is greater than the content of
** register P1. See the Lt opcode for additional information.
*/
/* Opcode: Ge P1 P2 P3 P4 P5
-** Synopsis: IF r[P3]>=r[P1]
+** Synopsis: IF r[P3]>=r[P1]
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is greater than or equal to the content of
@@ -88757,7 +88757,7 @@ case OP_Lt: /* same as TK_LT, jump, in1, in3 */
case OP_Le: /* same as TK_LE, jump, in1, in3 */
case OP_Gt: /* same as TK_GT, jump, in1, in3 */
case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
- int res, res2; /* Result of the comparison of pIn1 against pIn3 */
+ int res, res2; /* Result of the comparison of pIn1 against pIn3 */
char affinity; /* Affinity to use for comparison */
u16 flags1; /* Copy of initial value of pIn1->flags */
u16 flags3; /* Copy of initial value of pIn3->flags */
@@ -88801,10 +88801,10 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
assert( (flags1 & MEM_Cleared)==0 );
assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB );
testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 );
- if( (flags1&flags3&MEM_Null)!=0
+ if( (flags1&flags3&MEM_Null)!=0
&& (flags3&MEM_Cleared)==0
){
- res = 0; /* Operands are equal */
+ res = 0; /* Operands are equal */
}else{
res = ((flags3 & MEM_Null) ? -1 : +1); /* Operands are not equal */
}
@@ -88825,15 +88825,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** integer comparison case. So do a general-case comparison. */
affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity>=SQLITE_AFF_NUMERIC ){
- if( (flags1 | flags3)&MEM_Str ){
+ if( (flags1 | flags3)&MEM_Str ){
if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
- applyNumericAffinity(pIn1,0);
+ applyNumericAffinity(pIn1,0);
testcase( flags3==pIn3->flags );
- flags3 = pIn3->flags;
- }
+ flags3 = pIn3->flags;
+ }
if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
- applyNumericAffinity(pIn3,0);
- }
+ applyNumericAffinity(pIn3,0);
+ }
}
}else if( affinity==SQLITE_AFF_TEXT ){
if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
@@ -88858,19 +88858,19 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
}
- /* At this point, res is negative, zero, or positive if reg[P1] is
- ** less than, equal to, or greater than reg[P3], respectively. Compute
- ** the answer to this operator in res2, depending on what the comparison
- ** operator actually is. The next block of code depends on the fact
- ** that the 6 comparison operators are consecutive integers in this
- ** order: NE, EQ, GT, LE, LT, GE */
- assert( OP_Eq==OP_Ne+1 ); assert( OP_Gt==OP_Ne+2 ); assert( OP_Le==OP_Ne+3 );
- assert( OP_Lt==OP_Ne+4 ); assert( OP_Ge==OP_Ne+5 );
+ /* At this point, res is negative, zero, or positive if reg[P1] is
+ ** less than, equal to, or greater than reg[P3], respectively. Compute
+ ** the answer to this operator in res2, depending on what the comparison
+ ** operator actually is. The next block of code depends on the fact
+ ** that the 6 comparison operators are consecutive integers in this
+ ** order: NE, EQ, GT, LE, LT, GE */
+ assert( OP_Eq==OP_Ne+1 ); assert( OP_Gt==OP_Ne+2 ); assert( OP_Le==OP_Ne+3 );
+ assert( OP_Lt==OP_Ne+4 ); assert( OP_Ge==OP_Ne+5 );
if( res<0 ){
res2 = sqlite3aLTb[pOp->opcode];
- }else if( res==0 ){
+ }else if( res==0 ){
res2 = sqlite3aEQb[pOp->opcode];
- }else{
+ }else{
res2 = sqlite3aGTb[pOp->opcode];
}
iCompare = res;
@@ -88889,7 +88889,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
}
/* Opcode: ElseEq * P2 * * *
-**
+**
** This opcode must follow an OP_Lt or OP_Gt comparison operator. There
** can be zero or more OP_ReleaseReg opcodes intervening, but no other
** opcodes are allowed to occur between this instruction and the previous
@@ -88899,7 +88899,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** prior OP_Lt or OP_Gt would have been true, then jump to P2.
** If the result of an OP_Eq comparison on the two previous
** operands would have been false or NULL, then fall through.
-*/
+*/
case OP_ElseEq: { /* same as TK_ESCAPE, jump */
#ifdef SQLITE_DEBUG
@@ -88914,27 +88914,27 @@ case OP_ElseEq: { /* same as TK_ESCAPE, jump */
#endif /* SQLITE_DEBUG */
VdbeBranchTaken(iCompare==0, 2);
if( iCompare==0 ) goto jump_to_p2;
- break;
-}
-
-
+ break;
+}
+
+
/* Opcode: Permutation * * * P4 *
**
-** Set the permutation used by the OP_Compare operator in the next
-** instruction. The permutation is stored in the P4 operand.
+** Set the permutation used by the OP_Compare operator in the next
+** instruction. The permutation is stored in the P4 operand.
**
** The permutation is only valid until the next OP_Compare that has
** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
** occur immediately prior to the OP_Compare.
-**
-** The first integer in the P4 integer array is the length of the array
-** and does not become part of the permutation.
+**
+** The first integer in the P4 integer array is the length of the array
+** and does not become part of the permutation.
*/
case OP_Permutation: {
assert( pOp->p4type==P4_INTARRAY );
assert( pOp->p4.ai );
- assert( pOp[1].opcode==OP_Compare );
- assert( pOp[1].p5 & OPFLAG_PERMUTE );
+ assert( pOp[1].opcode==OP_Compare );
+ assert( pOp[1].p5 & OPFLAG_PERMUTE );
break;
}
@@ -88969,30 +88969,30 @@ case OP_Compare: {
int bRev; /* True for DESCENDING sort order */
u32 *aPermute; /* The permutation */
- if( (pOp->p5 & OPFLAG_PERMUTE)==0 ){
- aPermute = 0;
- }else{
- assert( pOp>aOp );
- assert( pOp[-1].opcode==OP_Permutation );
- assert( pOp[-1].p4type==P4_INTARRAY );
- aPermute = pOp[-1].p4.ai + 1;
- assert( aPermute!=0 );
- }
+ if( (pOp->p5 & OPFLAG_PERMUTE)==0 ){
+ aPermute = 0;
+ }else{
+ assert( pOp>aOp );
+ assert( pOp[-1].opcode==OP_Permutation );
+ assert( pOp[-1].p4type==P4_INTARRAY );
+ aPermute = pOp[-1].p4.ai + 1;
+ assert( aPermute!=0 );
+ }
n = pOp->p3;
pKeyInfo = pOp->p4.pKeyInfo;
assert( n>0 );
assert( pKeyInfo!=0 );
p1 = pOp->p1;
p2 = pOp->p2;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
if( aPermute ){
int k, mx = 0;
for(k=0; k<n; k++) if( aPermute[k]>(u32)mx ) mx = aPermute[k];
- assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 );
- assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 );
+ assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 );
+ assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 );
}else{
- assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 );
- assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 );
+ assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 );
+ assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 );
}
#endif /* SQLITE_DEBUG */
for(i=0; i<n; i++){
@@ -89001,7 +89001,7 @@ case OP_Compare: {
assert( memIsValid(&aMem[p2+idx]) );
REGISTER_TRACE(p1+idx, &aMem[p1+idx]);
REGISTER_TRACE(p2+idx, &aMem[p2+idx]);
- assert( i<pKeyInfo->nKeyField );
+ assert( i<pKeyInfo->nKeyField );
pColl = pKeyInfo->aColl[i];
bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC);
iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl);
@@ -89146,39 +89146,39 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
/* Opcode: Once P1 P2 * * *
**
-** Fall through to the next instruction the first time this opcode is
-** encountered on each invocation of the byte-code program. Jump to P2
-** on the second and all subsequent encounters during the same invocation.
-**
-** Top-level programs determine first invocation by comparing the P1
-** operand against the P1 operand on the OP_Init opcode at the beginning
-** of the program. If the P1 values differ, then fall through and make
-** the P1 of this opcode equal to the P1 of OP_Init. If P1 values are
-** the same then take the jump.
-**
-** For subprograms, there is a bitmask in the VdbeFrame that determines
-** whether or not the jump should be taken. The bitmask is necessary
-** because the self-altering code trick does not work for recursive
-** triggers.
+** Fall through to the next instruction the first time this opcode is
+** encountered on each invocation of the byte-code program. Jump to P2
+** on the second and all subsequent encounters during the same invocation.
+**
+** Top-level programs determine first invocation by comparing the P1
+** operand against the P1 operand on the OP_Init opcode at the beginning
+** of the program. If the P1 values differ, then fall through and make
+** the P1 of this opcode equal to the P1 of OP_Init. If P1 values are
+** the same then take the jump.
+**
+** For subprograms, there is a bitmask in the VdbeFrame that determines
+** whether or not the jump should be taken. The bitmask is necessary
+** because the self-altering code trick does not work for recursive
+** triggers.
*/
case OP_Once: { /* jump */
- u32 iAddr; /* Address of this instruction */
- assert( p->aOp[0].opcode==OP_Init );
- if( p->pFrame ){
- iAddr = (int)(pOp - p->aOp);
- if( (p->pFrame->aOnce[iAddr/8] & (1<<(iAddr & 7)))!=0 ){
- VdbeBranchTaken(1, 2);
- goto jump_to_p2;
- }
- p->pFrame->aOnce[iAddr/8] |= 1<<(iAddr & 7);
- }else{
- if( p->aOp[0].p1==pOp->p1 ){
- VdbeBranchTaken(1, 2);
- goto jump_to_p2;
- }
- }
- VdbeBranchTaken(0, 2);
- pOp->p1 = p->aOp[0].p1;
+ u32 iAddr; /* Address of this instruction */
+ assert( p->aOp[0].opcode==OP_Init );
+ if( p->pFrame ){
+ iAddr = (int)(pOp - p->aOp);
+ if( (p->pFrame->aOnce[iAddr/8] & (1<<(iAddr & 7)))!=0 ){
+ VdbeBranchTaken(1, 2);
+ goto jump_to_p2;
+ }
+ p->pFrame->aOnce[iAddr/8] |= 1<<(iAddr & 7);
+ }else{
+ if( p->aOp[0].p1==pOp->p1 ){
+ VdbeBranchTaken(1, 2);
+ goto jump_to_p2;
+ }
+ }
+ VdbeBranchTaken(0, 2);
+ pOp->p1 = p->aOp[0].p1;
break;
}
@@ -89211,7 +89211,7 @@ case OP_IfNot: { /* jump, in1 */
}
/* Opcode: IsNull P1 P2 * * *
-** Synopsis: if r[P1]==NULL goto P2
+** Synopsis: if r[P1]==NULL goto P2
**
** Jump to P2 if the value in register P1 is NULL.
*/
@@ -89272,56 +89272,56 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
break;
}
-/* Opcode: IfNullRow P1 P2 P3 * *
-** Synopsis: if P1.nullRow then r[P3]=NULL, goto P2
-**
-** Check the cursor P1 to see if it is currently pointing at a NULL row.
-** If it is, then set register P3 to NULL and jump immediately to P2.
-** If P1 is not on a NULL row, then fall through without making any
-** changes.
-*/
-case OP_IfNullRow: { /* jump */
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- assert( p->apCsr[pOp->p1]!=0 );
- if( p->apCsr[pOp->p1]->nullRow ){
- sqlite3VdbeMemSetNull(aMem + pOp->p3);
- goto jump_to_p2;
- }
- break;
-}
-
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
-/* Opcode: Offset P1 P2 P3 * *
-** Synopsis: r[P3] = sqlite_offset(P1)
-**
-** Store in register r[P3] the byte offset into the database file that is the
-** start of the payload for the record at which that cursor P1 is currently
-** pointing.
-**
-** P2 is the column number for the argument to the sqlite_offset() function.
-** This opcode does not use P2 itself, but the P2 value is used by the
-** code generator. The P1, P2, and P3 operands to this opcode are the
+/* Opcode: IfNullRow P1 P2 P3 * *
+** Synopsis: if P1.nullRow then r[P3]=NULL, goto P2
+**
+** Check the cursor P1 to see if it is currently pointing at a NULL row.
+** If it is, then set register P3 to NULL and jump immediately to P2.
+** If P1 is not on a NULL row, then fall through without making any
+** changes.
+*/
+case OP_IfNullRow: { /* jump */
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ assert( p->apCsr[pOp->p1]!=0 );
+ if( p->apCsr[pOp->p1]->nullRow ){
+ sqlite3VdbeMemSetNull(aMem + pOp->p3);
+ goto jump_to_p2;
+ }
+ break;
+}
+
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+/* Opcode: Offset P1 P2 P3 * *
+** Synopsis: r[P3] = sqlite_offset(P1)
+**
+** Store in register r[P3] the byte offset into the database file that is the
+** start of the payload for the record at which that cursor P1 is currently
+** pointing.
+**
+** P2 is the column number for the argument to the sqlite_offset() function.
+** This opcode does not use P2 itself, but the P2 value is used by the
+** code generator. The P1, P2, and P3 operands to this opcode are the
** same as for OP_Column.
-**
-** This opcode is only available if SQLite is compiled with the
-** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option.
-*/
-case OP_Offset: { /* out3 */
- VdbeCursor *pC; /* The VDBE cursor */
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- pC = p->apCsr[pOp->p1];
- pOut = &p->aMem[pOp->p3];
- if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){
- sqlite3VdbeMemSetNull(pOut);
- }else{
- sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
- }
- break;
-}
-#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
-
+**
+** This opcode is only available if SQLite is compiled with the
+** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option.
+*/
+case OP_Offset: { /* out3 */
+ VdbeCursor *pC; /* The VDBE cursor */
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ pOut = &p->aMem[pOp->p3];
+ if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){
+ sqlite3VdbeMemSetNull(pOut);
+ }else{
+ sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
+ }
+ break;
+}
+#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
+
/* Opcode: Column P1 P2 P3 P4 P5
-** Synopsis: r[P3]=PX
+** Synopsis: r[P3]=PX
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction. (See the MakeRecord opcode for additional
@@ -89331,11 +89331,11 @@ case OP_Offset: { /* out3 */
**
** The value extracted is stored in register P3.
**
-** If the record contains fewer than P2 fields, then extract a NULL. Or,
+** If the record contains fewer than P2 fields, then extract a NULL. Or,
** if the P4 argument is a P4_MEM use the value of the P4 argument as
** the result.
**
-** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then
+** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then
** the result is guaranteed to only be used as the argument of a length()
** or typeof() function, respectively. The loading of large blobs can be
** skipped for length() and all content loading can be skipped for typeof().
@@ -89352,102 +89352,102 @@ case OP_Column: {
const u8 *zData; /* Part of the record being decoded */
const u8 *zHdr; /* Next unparsed byte of the header */
const u8 *zEndHdr; /* Pointer to first byte after the header */
- u64 offset64; /* 64-bit offset */
+ u64 offset64; /* 64-bit offset */
u32 t; /* A type code from the record header */
Mem *pReg; /* PseudoTable input register */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- pC = p->apCsr[pOp->p1];
+ pC = p->apCsr[pOp->p1];
assert( pC!=0 );
p2 = (u32)pOp->p2;
-
- /* If the cursor cache is stale (meaning it is not currently point at
+
+ /* If the cursor cache is stale (meaning it is not currently point at
** the correct row) then bring it up-to-date by doing the necessary
- ** B-Tree seek. */
- rc = sqlite3VdbeCursorMoveto(&pC, &p2);
- if( rc ) goto abort_due_to_error;
-
- assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+ ** B-Tree seek. */
+ rc = sqlite3VdbeCursorMoveto(&pC, &p2);
+ if( rc ) goto abort_due_to_error;
+
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
pDest = &aMem[pOp->p3];
memAboutToChange(p, pDest);
assert( pC!=0 );
assert( p2<(u32)pC->nField );
aOffset = pC->aOffset;
- assert( pC->eCurType!=CURTYPE_VTAB );
- assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
- assert( pC->eCurType!=CURTYPE_SORTER );
+ assert( pC->eCurType!=CURTYPE_VTAB );
+ assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
+ assert( pC->eCurType!=CURTYPE_SORTER );
- if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/
+ if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/
if( pC->nullRow ){
- if( pC->eCurType==CURTYPE_PSEUDO ){
- /* For the special case of as pseudo-cursor, the seekResult field
- ** identifies the register that holds the record */
- assert( pC->seekResult>0 );
- pReg = &aMem[pC->seekResult];
+ if( pC->eCurType==CURTYPE_PSEUDO ){
+ /* For the special case of as pseudo-cursor, the seekResult field
+ ** identifies the register that holds the record */
+ assert( pC->seekResult>0 );
+ pReg = &aMem[pC->seekResult];
assert( pReg->flags & MEM_Blob );
assert( memIsValid(pReg) );
- pC->payloadSize = pC->szRow = pReg->n;
+ pC->payloadSize = pC->szRow = pReg->n;
pC->aRow = (u8*)pReg->z;
}else{
sqlite3VdbeMemSetNull(pDest);
goto op_column_out;
}
}else{
- pCrsr = pC->uc.pCursor;
- assert( pC->eCurType==CURTYPE_BTREE );
+ pCrsr = pC->uc.pCursor;
+ assert( pC->eCurType==CURTYPE_BTREE );
assert( pCrsr );
- assert( sqlite3BtreeCursorIsValid(pCrsr) );
- pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
- pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
- assert( pC->szRow<=pC->payloadSize );
- assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
+ assert( sqlite3BtreeCursorIsValid(pCrsr) );
+ pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
+ pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
+ assert( pC->szRow<=pC->payloadSize );
+ assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
}
pC->cacheStatus = p->cacheCtr;
- pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
+ pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
pC->nHdrParsed = 0;
- if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
+ if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
/* pC->aRow does not have to hold the entire row, but it does at least
** need to cover the header of the record. If pC->aRow does not contain
** the complete header, then set it to zero, forcing the header to be
** dynamically allocated. */
pC->aRow = 0;
pC->szRow = 0;
-
- /* Make sure a corrupt database has not given us an oversize header.
- ** Do this now to avoid an oversize memory allocation.
- **
- ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
- ** types use so much data space that there can only be 4096 and 32 of
- ** them, respectively. So the maximum header length results from a
- ** 3-byte type for each of the maximum of 32768 columns plus three
- ** extra bytes for the header length itself. 32768*3 + 3 = 98307.
- */
- if( aOffset[0] > 98307 || aOffset[0] > pC->payloadSize ){
- goto op_column_corrupt;
- }
- }else{
- /* This is an optimization. By skipping over the first few tests
- ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a
- ** measurable performance gain.
- **
- ** This branch is taken even if aOffset[0]==0. Such a record is never
- ** generated by SQLite, and could be considered corruption, but we
- ** accept it for historical reasons. When aOffset[0]==0, the code this
- ** branch jumps to reads past the end of the record, but never more
- ** than a few bytes. Even if the record occurs at the end of the page
- ** content area, the "page header" comes after the page content and so
- ** this overread is harmless. Similar overreads can occur for a corrupt
- ** database file.
- */
- zData = pC->aRow;
- assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
- testcase( aOffset[0]==0 );
- goto op_column_read_header;
+
+ /* Make sure a corrupt database has not given us an oversize header.
+ ** Do this now to avoid an oversize memory allocation.
+ **
+ ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
+ ** types use so much data space that there can only be 4096 and 32 of
+ ** them, respectively. So the maximum header length results from a
+ ** 3-byte type for each of the maximum of 32768 columns plus three
+ ** extra bytes for the header length itself. 32768*3 + 3 = 98307.
+ */
+ if( aOffset[0] > 98307 || aOffset[0] > pC->payloadSize ){
+ goto op_column_corrupt;
+ }
+ }else{
+ /* This is an optimization. By skipping over the first few tests
+ ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a
+ ** measurable performance gain.
+ **
+ ** This branch is taken even if aOffset[0]==0. Such a record is never
+ ** generated by SQLite, and could be considered corruption, but we
+ ** accept it for historical reasons. When aOffset[0]==0, the code this
+ ** branch jumps to reads past the end of the record, but never more
+ ** than a few bytes. Even if the record occurs at the end of the page
+ ** content area, the "page header" comes after the page content and so
+ ** this overread is harmless. Similar overreads can occur for a corrupt
+ ** database file.
+ */
+ zData = pC->aRow;
+ assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
+ testcase( aOffset[0]==0 );
+ goto op_column_read_header;
}
}
@@ -89463,53 +89463,53 @@ case OP_Column: {
if( pC->aRow==0 ){
memset(&sMem, 0, sizeof(sMem));
rc = sqlite3VdbeMemFromBtreeZeroOffset(pC->uc.pCursor,aOffset[0],&sMem);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
zData = (u8*)sMem.z;
}else{
zData = pC->aRow;
}
/* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */
- op_column_read_header:
+ op_column_read_header:
i = pC->nHdrParsed;
- offset64 = aOffset[i];
+ offset64 = aOffset[i];
zHdr = zData + pC->iHdrOffset;
zEndHdr = zData + aOffset[0];
- testcase( zHdr>=zEndHdr );
+ testcase( zHdr>=zEndHdr );
do{
if( (pC->aType[i] = t = zHdr[0])<0x80 ){
zHdr++;
- offset64 += sqlite3VdbeOneByteSerialTypeLen(t);
+ offset64 += sqlite3VdbeOneByteSerialTypeLen(t);
}else{
zHdr += sqlite3GetVarint32(zHdr, &t);
pC->aType[i] = t;
- offset64 += sqlite3VdbeSerialTypeLen(t);
+ offset64 += sqlite3VdbeSerialTypeLen(t);
}
aOffset[++i] = (u32)(offset64 & 0xffffffff);
}while( (u32)i<=p2 && zHdr<zEndHdr );
-
+
/* The record is corrupt if any of the following are true:
** (1) the bytes of the header extend past the declared header size
** (2) the entire header was used but not all data was used
** (3) the end of the data extends beyond the end of the record.
*/
- if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize))
- || (offset64 > pC->payloadSize)
+ if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize))
+ || (offset64 > pC->payloadSize)
){
- if( aOffset[0]==0 ){
- i = 0;
- zHdr = zEndHdr;
- }else{
- if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
- goto op_column_corrupt;
- }
- }
-
- pC->nHdrParsed = i;
- pC->iHdrOffset = (u32)(zHdr - zData);
- if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
- }else{
- t = 0;
+ if( aOffset[0]==0 ){
+ i = 0;
+ zHdr = zEndHdr;
+ }else{
+ if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
+ goto op_column_corrupt;
+ }
+ }
+
+ pC->nHdrParsed = i;
+ pC->iHdrOffset = (u32)(zHdr - zData);
+ if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
+ }else{
+ t = 0;
}
/* If after trying to extract new entries from the header, nHdrParsed is
@@ -89524,8 +89524,8 @@ case OP_Column: {
}
goto op_column_out;
}
- }else{
- t = pC->aType[p2];
+ }else{
+ t = pC->aType[p2];
}
/* Extract the content for the p2+1-th column. Control can only
@@ -89535,37 +89535,37 @@ case OP_Column: {
assert( p2<pC->nHdrParsed );
assert( rc==SQLITE_OK );
assert( sqlite3VdbeCheckMemInvariants(pDest) );
- if( VdbeMemDynamic(pDest) ){
- sqlite3VdbeMemSetNull(pDest);
- }
- assert( t==pC->aType[p2] );
+ if( VdbeMemDynamic(pDest) ){
+ sqlite3VdbeMemSetNull(pDest);
+ }
+ assert( t==pC->aType[p2] );
if( pC->szRow>=aOffset[p2+1] ){
/* This is the common case where the desired content fits on the original
** page - where the content is not on an overflow page */
- zData = pC->aRow + aOffset[p2];
- if( t<12 ){
- sqlite3VdbeSerialGet(zData, t, pDest);
- }else{
- /* If the column value is a string, we need a persistent value, not
- ** a MEM_Ephem value. This branch is a fast short-cut that is equivalent
- ** to calling sqlite3VdbeSerialGet() and sqlite3VdbeDeephemeralize().
- */
- static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term };
- pDest->n = len = (t-12)/2;
- pDest->enc = encoding;
- if( pDest->szMalloc < len+2 ){
- pDest->flags = MEM_Null;
- if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem;
- }else{
- pDest->z = pDest->zMalloc;
- }
- memcpy(pDest->z, zData, len);
- pDest->z[len] = 0;
- pDest->z[len+1] = 0;
- pDest->flags = aFlag[t&1];
- }
- }else{
- pDest->enc = encoding;
+ zData = pC->aRow + aOffset[p2];
+ if( t<12 ){
+ sqlite3VdbeSerialGet(zData, t, pDest);
+ }else{
+ /* If the column value is a string, we need a persistent value, not
+ ** a MEM_Ephem value. This branch is a fast short-cut that is equivalent
+ ** to calling sqlite3VdbeSerialGet() and sqlite3VdbeDeephemeralize().
+ */
+ static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term };
+ pDest->n = len = (t-12)/2;
+ pDest->enc = encoding;
+ if( pDest->szMalloc < len+2 ){
+ pDest->flags = MEM_Null;
+ if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem;
+ }else{
+ pDest->z = pDest->zMalloc;
+ }
+ memcpy(pDest->z, zData, len);
+ pDest->z[len] = 0;
+ pDest->z[len+1] = 0;
+ pDest->flags = aFlag[t&1];
+ }
+ }else{
+ pDest->enc = encoding;
/* This branch happens only when content is on overflow pages */
if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
&& ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
@@ -89577,17 +89577,17 @@ case OP_Column: {
** 3. if the content length is zero.
** So we might as well use bogus content rather than reading
** content from disk.
- **
- ** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the
- ** buffer passed to it, debugging function VdbeMemPrettyPrint() may
+ **
+ ** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the
+ ** buffer passed to it, debugging function VdbeMemPrettyPrint() may
** read more. Use the global constant sqlite3CtypeMap[] as the array,
** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
** and it begins with a bunch of zeros.
- */
+ */
sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
}else{
- rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
pDest->flags &= ~MEM_Ephem;
}
@@ -89597,15 +89597,15 @@ op_column_out:
UPDATE_MAX_BLOBSIZE(pDest);
REGISTER_TRACE(pOp->p3, pDest);
break;
-
-op_column_corrupt:
- if( aOp[0].p3>0 ){
- pOp = &aOp[aOp[0].p3-1];
- break;
- }else{
- rc = SQLITE_CORRUPT_BKPT;
- goto abort_due_to_error;
- }
+
+op_column_corrupt:
+ if( aOp[0].p3>0 ){
+ pOp = &aOp[aOp[0].p3-1];
+ break;
+ }else{
+ rc = SQLITE_CORRUPT_BKPT;
+ goto abort_due_to_error;
+ }
}
/* Opcode: TypeCheck P1 P2 P3 P4 *
@@ -89715,8 +89715,8 @@ vdbe_type_error:
**
** Apply affinities to a range of P2 registers starting with P1.
**
-** P4 is a string that is P2 characters long. The N-th character of the
-** string indicates the column affinity that should be used for the N-th
+** P4 is a string that is P2 characters long. The N-th character of the
+** string indicates the column affinity that should be used for the N-th
** memory cell in the range.
*/
case OP_Affinity: {
@@ -89724,11 +89724,11 @@ case OP_Affinity: {
zAffinity = pOp->p4.z;
assert( zAffinity!=0 );
- assert( pOp->p2>0 );
+ assert( pOp->p2>0 );
assert( zAffinity[pOp->p2]==0 );
pIn1 = &aMem[pOp->p1];
while( 1 /*exit-by-break*/ ){
- assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
+ assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
assert( zAffinity[0]==SQLITE_AFF_NONE || memIsValid(pIn1) );
applyAffinity(pIn1, zAffinity[0], encoding);
if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
@@ -89764,8 +89764,8 @@ case OP_Affinity: {
** use as a data record in a database table or as a key
** in an index. The OP_Column opcode can decode the record later.
**
-** P4 may be a string that is P2 characters long. The N-th character of the
-** string indicates the column affinity that should be used for the N-th
+** P4 may be a string that is P2 characters long. The N-th character of the
+** string indicates the column affinity that should be used for the N-th
** field of the index key.
**
** The mapping from character to affinity is given by the SQLITE_AFF_
@@ -89797,7 +89797,7 @@ case OP_MakeRecord: {
int nField; /* Number of fields in the record */
char *zAffinity; /* The affinity string for the record */
int file_format; /* File format to use for encoding */
- u32 len; /* Length of a field */
+ u32 len; /* Length of a field */
u8 *zHdr; /* Where to write next byte of the header */
u8 *zPayload; /* Where to write next byte of the payload */
@@ -89821,7 +89821,7 @@ case OP_MakeRecord: {
nZero = 0; /* Number of zero bytes at the end of the record */
nField = pOp->p1;
zAffinity = pOp->p4.z;
- assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 );
+ assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 );
pData0 = &aMem[nField];
nField = pOp->p2;
pLast = &pData0[nField-1];
@@ -89850,20 +89850,20 @@ case OP_MakeRecord: {
}while( zAffinity[0] );
}
-#ifdef SQLITE_ENABLE_NULL_TRIM
- /* NULLs can be safely trimmed from the end of the record, as long as
- ** as the schema format is 2 or more and none of the omitted columns
- ** have a non-NULL default value. Also, the record must be left with
- ** at least one field. If P5>0 then it will be one more than the
- ** index of the right-most column with a non-NULL default value */
- if( pOp->p5 ){
- while( (pLast->flags & MEM_Null)!=0 && nField>pOp->p5 ){
- pLast--;
- nField--;
- }
- }
-#endif
-
+#ifdef SQLITE_ENABLE_NULL_TRIM
+ /* NULLs can be safely trimmed from the end of the record, as long as
+ ** as the schema format is 2 or more and none of the omitted columns
+ ** have a non-NULL default value. Also, the record must be left with
+ ** at least one field. If P5>0 then it will be one more than the
+ ** index of the right-most column with a non-NULL default value */
+ if( pOp->p5 ){
+ while( (pLast->flags & MEM_Null)!=0 && nField>pOp->p5 ){
+ pLast--;
+ nField--;
+ }
+ }
+#endif
+
/* Loop through the elements that will make up the record to figure
** out how much space is required for the new record. After this loop,
** the Mem.uTemp field of each term should hold the serial-type that will
@@ -89895,14 +89895,14 @@ case OP_MakeRecord: {
assert( memIsValid(pRec) );
if( pRec->flags & MEM_Null ){
if( pRec->flags & MEM_Zero ){
- /* Values with MEM_Null and MEM_Zero are created by xColumn virtual
- ** table methods that never invoke sqlite3_result_xxxxx() while
- ** computing an unchanging column value in an UPDATE statement.
- ** Give such values a special internal-use-only serial-type of 10
- ** so that they can be passed through to xUpdate and have
- ** a true sqlite3_value_nochange(). */
+ /* Values with MEM_Null and MEM_Zero are created by xColumn virtual
+ ** table methods that never invoke sqlite3_result_xxxxx() while
+ ** computing an unchanging column value in an UPDATE statement.
+ ** Give such values a special internal-use-only serial-type of 10
+ ** so that they can be passed through to xUpdate and have
+ ** a true sqlite3_value_nochange(). */
#ifndef SQLITE_ENABLE_NULL_TRIM
- assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
+ assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
#endif
pRec->uTemp = 10;
}else{
@@ -89981,9 +89981,9 @@ case OP_MakeRecord: {
nHdr += sqlite3VarintLen(serial_type);
pRec->uTemp = serial_type;
}
- if( pRec==pData0 ) break;
- pRec--;
- }while(1);
+ if( pRec==pData0 ) break;
+ pRec--;
+ }while(1);
/* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
** which determines the total number of bytes in the header. The varint
@@ -90047,7 +90047,7 @@ case OP_MakeRecord: {
assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
assert( nByte==(int)(zPayload - (u8*)pOut->z) );
- assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
REGISTER_TRACE(pOp->p3, pOut);
break;
}
@@ -90066,8 +90066,8 @@ case OP_Count: { /* out2 */
i64 nEntry;
BtCursor *pCrsr;
- assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
- pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
+ assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
+ pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
assert( pCrsr );
if( pOp->p3 ){
nEntry = sqlite3BtreeRowCountEst(pCrsr);
@@ -90132,7 +90132,7 @@ case OP_Savepoint: {
#endif
/* Create a new savepoint structure. */
- pNew = sqlite3DbMallocRawNN(db, sizeof(Savepoint)+nName+1);
+ pNew = sqlite3DbMallocRawNN(db, sizeof(Savepoint)+nName+1);
if( pNew ){
pNew->zName = (char *)&pNew[1];
memcpy(pNew->zName, zName, nName+1);
@@ -90145,7 +90145,7 @@ case OP_Savepoint: {
}else{
db->nSavepoint++;
}
-
+
/* Link the new savepoint into the database handle's list. */
pNew->pNext = db->pSavepoint;
db->pSavepoint = pNew;
@@ -90204,7 +90204,7 @@ case OP_Savepoint: {
int isSchemaChange;
iSavepoint = db->nSavepoint - iSavepoint - 1;
if( p1==SAVEPOINT_ROLLBACK ){
- isSchemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0;
+ isSchemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0;
for(ii=0; ii<db->nDb; ii++){
rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt,
SQLITE_ABORT_ROLLBACK,
@@ -90224,7 +90224,7 @@ case OP_Savepoint: {
if( isSchemaChange ){
sqlite3ExpirePreparedStatements(db, 0);
sqlite3ResetAllSchemasOfConnection(db);
- db->mDbFlags |= DBFLAG_SchemaChange;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
}
if( rc ) goto abort_due_to_error;
@@ -90261,7 +90261,7 @@ case OP_Savepoint: {
}
}
}
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -90286,30 +90286,30 @@ case OP_AutoCommit: {
assert( db->nVdbeActive>0 ); /* At least this one VM is active */
assert( p->bIsReader );
- if( desiredAutoCommit!=db->autoCommit ){
+ if( desiredAutoCommit!=db->autoCommit ){
if( iRollback ){
assert( desiredAutoCommit==1 );
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
db->autoCommit = 1;
- }else if( desiredAutoCommit && db->nVdbeWrite>0 ){
- /* If this instruction implements a COMMIT and other VMs are writing
+ }else if( desiredAutoCommit && db->nVdbeWrite>0 ){
+ /* If this instruction implements a COMMIT and other VMs are writing
** return an error indicating that the other VMs must complete first.
- */
- sqlite3VdbeError(p, "cannot commit transaction - "
- "SQL statements in progress");
- rc = SQLITE_BUSY;
- goto abort_due_to_error;
+ */
+ sqlite3VdbeError(p, "cannot commit transaction - "
+ "SQL statements in progress");
+ rc = SQLITE_BUSY;
+ goto abort_due_to_error;
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
db->autoCommit = (u8)desiredAutoCommit;
}
- if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = (int)(pOp - aOp);
- db->autoCommit = (u8)(1-desiredAutoCommit);
- p->rc = rc = SQLITE_BUSY;
- goto vdbe_return;
- }
+ if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
+ p->pc = (int)(pOp - aOp);
+ db->autoCommit = (u8)(1-desiredAutoCommit);
+ p->rc = rc = SQLITE_BUSY;
+ goto vdbe_return;
+ }
sqlite3CloseSavepoints(db);
if( p->rc==SQLITE_OK ){
rc = SQLITE_DONE;
@@ -90324,7 +90324,7 @@ case OP_AutoCommit: {
"cannot commit - no transaction is active"));
rc = SQLITE_ERROR;
- goto abort_due_to_error;
+ goto abort_due_to_error;
}
/*NOTREACHED*/ assert(0);
}
@@ -90389,14 +90389,14 @@ case OP_Transaction: {
if( pBt ){
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta);
- testcase( rc==SQLITE_BUSY_SNAPSHOT );
- testcase( rc==SQLITE_BUSY_RECOVERY );
+ testcase( rc==SQLITE_BUSY_SNAPSHOT );
+ testcase( rc==SQLITE_BUSY_RECOVERY );
if( rc!=SQLITE_OK ){
- if( (rc&0xff)==SQLITE_BUSY ){
- p->pc = (int)(pOp - aOp);
- p->rc = rc;
- goto vdbe_return;
- }
+ if( (rc&0xff)==SQLITE_BUSY ){
+ p->pc = (int)(pOp - aOp);
+ p->rc = rc;
+ goto vdbe_return;
+ }
goto abort_due_to_error;
}
@@ -90430,9 +90430,9 @@ case OP_Transaction: {
|| db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
){
/*
- ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
- ** version is checked to ensure that the schema has not changed since the
- ** SQL statement was prepared.
+ ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
+ ** version is checked to ensure that the schema has not changed since the
+ ** SQL statement was prepared.
*/
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
@@ -90455,7 +90455,7 @@ case OP_Transaction: {
p->expired = 1;
rc = SQLITE_SCHEMA;
}
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -90492,8 +90492,8 @@ case OP_ReadCookie: { /* out2 */
/* Opcode: SetCookie P1 P2 P3 * P5
**
-** Write the integer value P3 into cookie number P2 of database P1.
-** P2==1 is the schema version. P2==2 is the database format.
+** Write the integer value P3 into cookie number P2 of database P1.
+** P2==1 is the schema version. P2==2 is the database format.
** P2==3 is the recommended pager cache
** size, and so forth. P1==0 is the main database file and P1==1 is the
** database file used to store temporary tables.
@@ -90505,7 +90505,7 @@ case OP_ReadCookie: { /* out2 */
** has P5 set to 1, so that the internal schema version will be different
** from the database schema version, resulting in a schema reset.
*/
-case OP_SetCookie: {
+case OP_SetCookie: {
Db *pDb;
sqlite3VdbeIncrWriteCounter(p, 0);
@@ -90517,15 +90517,15 @@ case OP_SetCookie: {
assert( pDb->pBt!=0 );
assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
/* See note about index shifting on OP_ReadCookie */
- rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3);
+ rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3);
if( pOp->p2==BTREE_SCHEMA_VERSION ){
/* When the schema cookie changes, record the new cookie internally */
pDb->pSchema->schema_cookie = pOp->p3 - pOp->p5;
- db->mDbFlags |= DBFLAG_SchemaChange;
+ db->mDbFlags |= DBFLAG_SchemaChange;
sqlite3FkClearTriggerCache(db, pOp->p1);
}else if( pOp->p2==BTREE_FILE_FORMAT ){
/* Record changes in the file format */
- pDb->pSchema->file_format = pOp->p3;
+ pDb->pSchema->file_format = pOp->p3;
}
if( pOp->p1==1 ){
/* Invalidate all prepared statements whenever the TEMP database
@@ -90533,7 +90533,7 @@ case OP_SetCookie: {
sqlite3ExpirePreparedStatements(db, 0);
p->expired = 0;
}
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -90652,7 +90652,7 @@ case OP_OpenWrite:
if( p->expired==1 ){
rc = SQLITE_ABORT_ROLLBACK;
- goto abort_due_to_error;
+ goto abort_due_to_error;
}
nField = 0;
@@ -90665,8 +90665,8 @@ case OP_OpenWrite:
pX = pDb->pBt;
assert( pX!=0 );
if( pOp->opcode==OP_OpenWrite ){
- assert( OPFLAG_FORDELETE==BTREE_FORDELETE );
- wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE);
+ assert( OPFLAG_FORDELETE==BTREE_FORDELETE );
+ wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE);
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( pDb->pSchema->file_format < p->minWriteFileFormat ){
p->minWriteFileFormat = pDb->pSchema->file_format;
@@ -90683,32 +90683,32 @@ case OP_OpenWrite:
assert( (pIn2->flags & MEM_Int)!=0 );
sqlite3VdbeMemIntegerify(pIn2);
p2 = (int)pIn2->u.i;
- /* The p2 value always comes from a prior OP_CreateBtree opcode and
+ /* The p2 value always comes from a prior OP_CreateBtree opcode and
** that opcode will always set the p2 value to 2 or more or else fail.
** If there were a failure, the prepared statement would have halted
** before reaching this instruction. */
- assert( p2>=2 );
+ assert( p2>=2 );
}
if( pOp->p4type==P4_KEYINFO ){
pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->enc==ENC(db) );
assert( pKeyInfo->db==db );
- nField = pKeyInfo->nAllField;
+ nField = pKeyInfo->nAllField;
}else if( pOp->p4type==P4_INT32 ){
nField = pOp->p4.i;
}
assert( pOp->p1>=0 );
assert( nField>=0 );
testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */
- pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE);
+ pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE);
if( pCur==0 ) goto no_mem;
pCur->nullRow = 1;
pCur->isOrdered = 1;
pCur->pgnoRoot = p2;
-#ifdef SQLITE_DEBUG
- pCur->wrFlag = wrFlag;
-#endif
- rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor);
+#ifdef SQLITE_DEBUG
+ pCur->wrFlag = wrFlag;
+#endif
+ rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor);
pCur->pKeyInfo = pKeyInfo;
/* Set the VdbeCursor.isTable variable. Previous versions of
** SQLite used to check if the root-page flags were sane at this point
@@ -90719,51 +90719,51 @@ case OP_OpenWrite:
open_cursor_set_hints:
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ );
- testcase( pOp->p5 & OPFLAG_BULKCSR );
- testcase( pOp->p2 & OPFLAG_SEEKEQ );
- sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
- (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
- if( rc ) goto abort_due_to_error;
+ testcase( pOp->p5 & OPFLAG_BULKCSR );
+ testcase( pOp->p2 & OPFLAG_SEEKEQ );
+ sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
+ (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
+ if( rc ) goto abort_due_to_error;
break;
}
-/* Opcode: OpenDup P1 P2 * * *
-**
-** Open a new cursor P1 that points to the same ephemeral table as
-** cursor P2. The P2 cursor must have been opened by a prior OP_OpenEphemeral
-** opcode. Only ephemeral cursors may be duplicated.
-**
-** Duplicate ephemeral cursors are used for self-joins of materialized views.
-*/
-case OP_OpenDup: {
- VdbeCursor *pOrig; /* The original cursor to be duplicated */
- VdbeCursor *pCx; /* The new cursor */
-
- pOrig = p->apCsr[pOp->p2];
+/* Opcode: OpenDup P1 P2 * * *
+**
+** Open a new cursor P1 that points to the same ephemeral table as
+** cursor P2. The P2 cursor must have been opened by a prior OP_OpenEphemeral
+** opcode. Only ephemeral cursors may be duplicated.
+**
+** Duplicate ephemeral cursors are used for self-joins of materialized views.
+*/
+case OP_OpenDup: {
+ VdbeCursor *pOrig; /* The original cursor to be duplicated */
+ VdbeCursor *pCx; /* The new cursor */
+
+ pOrig = p->apCsr[pOp->p2];
assert( pOrig );
assert( pOrig->isEphemeral ); /* Only ephemeral cursors can be duplicated */
-
- pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
- if( pCx==0 ) goto no_mem;
- pCx->nullRow = 1;
- pCx->isEphemeral = 1;
- pCx->pKeyInfo = pOrig->pKeyInfo;
- pCx->isTable = pOrig->isTable;
+
+ pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
+ if( pCx==0 ) goto no_mem;
+ pCx->nullRow = 1;
+ pCx->isEphemeral = 1;
+ pCx->pKeyInfo = pOrig->pKeyInfo;
+ pCx->isTable = pOrig->isTable;
pCx->pgnoRoot = pOrig->pgnoRoot;
pCx->isOrdered = pOrig->isOrdered;
pCx->pBtx = pOrig->pBtx;
pCx->hasBeenDuped = 1;
pOrig->hasBeenDuped = 1;
rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
- pCx->pKeyInfo, pCx->uc.pCursor);
- /* The sqlite3BtreeCursor() routine can only fail for the first cursor
- ** opened for a database. Since there is already an open cursor when this
- ** opcode is run, the sqlite3BtreeCursor() cannot fail */
- assert( rc==SQLITE_OK );
- break;
-}
-
-
+ pCx->pKeyInfo, pCx->uc.pCursor);
+ /* The sqlite3BtreeCursor() routine can only fail for the first cursor
+ ** opened for a database. Since there is already an open cursor when this
+ ** opcode is run, the sqlite3BtreeCursor() cannot fail */
+ assert( rc==SQLITE_OK );
+ break;
+}
+
+
/* Opcode: OpenEphemeral P1 P2 P3 P4 P5
** Synopsis: nColumn=P2
**
@@ -90868,7 +90868,7 @@ case OP_OpenEphemeral: {
}
}
}
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
pCx->nullRow = 1;
break;
}
@@ -90888,13 +90888,13 @@ case OP_SorterOpen: {
assert( pOp->p1>=0 );
assert( pOp->p2>=0 );
- pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_SORTER);
+ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_SORTER);
if( pCx==0 ) goto no_mem;
pCx->pKeyInfo = pOp->p4.pKeyInfo;
assert( pCx->pKeyInfo->db==db );
assert( pCx->pKeyInfo->enc==ENC(db) );
rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx);
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -90909,7 +90909,7 @@ case OP_SequenceTest: {
VdbeCursor *pC;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
- assert( isSorter(pC) );
+ assert( isSorter(pC) );
if( (pC->seqCount++)==0 ){
goto jump_to_p2;
}
@@ -90937,16 +90937,16 @@ case OP_OpenPseudo: {
assert( pOp->p1>=0 );
assert( pOp->p3>=0 );
- pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO);
+ pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO);
if( pCx==0 ) goto no_mem;
pCx->nullRow = 1;
- pCx->seekResult = pOp->p2;
+ pCx->seekResult = pOp->p2;
pCx->isTable = 1;
- /* Give this pseudo-cursor a fake BtCursor pointer so that pCx
- ** can be safely passed to sqlite3VdbeCursorMoveto(). This avoids a test
- ** for pCx->eCurType==CURTYPE_BTREE inside of sqlite3VdbeCursorMoveto()
- ** which is a performance optimization */
- pCx->uc.pCursor = sqlite3BtreeFakeValidCursor();
+ /* Give this pseudo-cursor a fake BtCursor pointer so that pCx
+ ** can be safely passed to sqlite3VdbeCursorMoveto(). This avoids a test
+ ** for pCx->eCurType==CURTYPE_BTREE inside of sqlite3VdbeCursorMoveto()
+ ** which is a performance optimization */
+ pCx->uc.pCursor = sqlite3BtreeFakeValidCursor();
assert( pOp->p5==0 );
break;
}
@@ -90977,7 +90977,7 @@ case OP_Close: {
case OP_ColumnsUsed: {
VdbeCursor *pC;
pC = p->apCsr[pOp->p1];
- assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->eCurType==CURTYPE_BTREE );
pC->maskUsed = *(u64*)pOp->p4.pI64;
break;
}
@@ -90995,7 +90995,7 @@ case OP_ColumnsUsed: {
** is greater than or equal to the key value. If there are no records
** greater than or equal to the key and P2 is not zero, then jump to P2.
**
-** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
+** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
** opcode will either land on a record that exactly matches the key, or
** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ,
** this opcode must be followed by an IdxLE opcode with the same arguments.
@@ -91003,7 +91003,7 @@ case OP_ColumnsUsed: {
** IdxGT opcode will be used on subsequent loop iterations. The
** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
** is an equality search.
-**
+**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end. In other words, the cursor is
** configured to use Next, not Prev.
@@ -91062,41 +91062,41 @@ case OP_ColumnsUsed: {
** from the end toward the beginning. In other words, the cursor is
** configured to use Prev, not Next.
**
-** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
+** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
** opcode will either land on a record that exactly matches the key, or
** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ,
** this opcode must be followed by an IdxLE opcode with the same arguments.
-** The IdxGE opcode will be skipped if this opcode succeeds, but the
+** The IdxGE opcode will be skipped if this opcode succeeds, but the
** IdxGE opcode will be used on subsequent loop iterations. The
** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
** is an equality search.
-**
+**
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
*/
case OP_SeekLT: /* jump, in3, group */
case OP_SeekLE: /* jump, in3, group */
case OP_SeekGE: /* jump, in3, group */
case OP_SeekGT: { /* jump, in3, group */
- int res; /* Comparison result */
- int oc; /* Opcode */
- VdbeCursor *pC; /* The cursor to seek */
- UnpackedRecord r; /* The key to seek for */
- int nField; /* Number of columns or fields in the key */
- i64 iKey; /* The rowid we are to seek to */
- int eqOnly; /* Only interested in == results */
+ int res; /* Comparison result */
+ int oc; /* Opcode */
+ VdbeCursor *pC; /* The cursor to seek */
+ UnpackedRecord r; /* The key to seek for */
+ int nField; /* Number of columns or fields in the key */
+ i64 iKey; /* The rowid we are to seek to */
+ int eqOnly; /* Only interested in == results */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p2!=0 );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
- assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->eCurType==CURTYPE_BTREE );
assert( OP_SeekLE == OP_SeekLT+1 );
assert( OP_SeekGE == OP_SeekLT+2 );
assert( OP_SeekGT == OP_SeekLT+3 );
assert( pC->isOrdered );
- assert( pC->uc.pCursor!=0 );
+ assert( pC->uc.pCursor!=0 );
oc = pOp->opcode;
- eqOnly = 0;
+ eqOnly = 0;
pC->nullRow = 0;
#ifdef SQLITE_DEBUG
pC->seekOp = pOp->opcode;
@@ -91107,9 +91107,9 @@ case OP_SeekGT: { /* jump, in3, group */
if( pC->isTable ){
u16 flags3, newType;
/* The OPFLAG_SEEKEQ/BTREE_SEEK_EQ flag is only set on index cursors */
- assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
- || CORRUPT_DB );
-
+ assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
+ || CORRUPT_DB );
+
/* The input value in P3 might be of any type: integer, real, string,
** blob, or NULL. But it needs to be an integer before we can do
** the seek, so convert it. */
@@ -91171,19 +91171,19 @@ case OP_SeekGT: { /* jump, in3, group */
** OP_SeekGE and OP_SeekLE opcodes are allowed, and these must be
** immediately followed by an OP_IdxGT or OP_IdxLT opcode, respectively,
** with the same key.
- */
- if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){
- eqOnly = 1;
- assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
- assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
+ */
+ if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){
+ eqOnly = 1;
+ assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
+ assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
assert( pOp->opcode==OP_SeekGE || pOp[1].opcode==OP_IdxLT );
assert( pOp->opcode==OP_SeekLE || pOp[1].opcode==OP_IdxGT );
- assert( pOp[1].p1==pOp[0].p1 );
- assert( pOp[1].p2==pOp[0].p2 );
- assert( pOp[1].p3==pOp[0].p3 );
- assert( pOp[1].p4.i==pOp[0].p4.i );
- }
-
+ assert( pOp[1].p1==pOp[0].p1 );
+ assert( pOp[1].p2==pOp[0].p2 );
+ assert( pOp[1].p3==pOp[0].p3 );
+ assert( pOp[1].p4.i==pOp[0].p4.i );
+ }
+
nField = pOp->p4.i;
assert( pOp->p4type==P4_INT32 );
assert( nField>0 );
@@ -91207,15 +91207,15 @@ case OP_SeekGT: { /* jump, in3, group */
#ifdef SQLITE_DEBUG
{ int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
#endif
- r.eqSeen = 0;
+ r.eqSeen = 0;
rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- if( eqOnly && r.eqSeen==0 ){
- assert( res!=0 );
- goto seek_not_found;
- }
+ if( eqOnly && r.eqSeen==0 ){
+ assert( res!=0 );
+ goto seek_not_found;
+ }
}
#ifdef SQLITE_TEST
sqlite3_search_count++;
@@ -91223,15 +91223,15 @@ case OP_SeekGT: { /* jump, in3, group */
if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
if( res<0 || (res==0 && oc==OP_SeekGT) ){
res = 0;
- rc = sqlite3BtreeNext(pC->uc.pCursor, 0);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_DONE ){
- rc = SQLITE_OK;
- res = 1;
- }else{
- goto abort_due_to_error;
- }
- }
+ rc = sqlite3BtreeNext(pC->uc.pCursor, 0);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_DONE ){
+ rc = SQLITE_OK;
+ res = 1;
+ }else{
+ goto abort_due_to_error;
+ }
+ }
}else{
res = 0;
}
@@ -91239,30 +91239,30 @@ case OP_SeekGT: { /* jump, in3, group */
assert( oc==OP_SeekLT || oc==OP_SeekLE );
if( res>0 || (res==0 && oc==OP_SeekLT) ){
res = 0;
- rc = sqlite3BtreePrevious(pC->uc.pCursor, 0);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_DONE ){
- rc = SQLITE_OK;
- res = 1;
- }else{
- goto abort_due_to_error;
- }
- }
+ rc = sqlite3BtreePrevious(pC->uc.pCursor, 0);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_DONE ){
+ rc = SQLITE_OK;
+ res = 1;
+ }else{
+ goto abort_due_to_error;
+ }
+ }
}else{
/* res might be negative because the table is empty. Check to
** see if this is the case.
*/
- res = sqlite3BtreeEof(pC->uc.pCursor);
+ res = sqlite3BtreeEof(pC->uc.pCursor);
}
}
-seek_not_found:
+seek_not_found:
assert( pOp->p2>0 );
VdbeBranchTaken(res!=0,2);
if( res ){
goto jump_to_p2;
- }else if( eqOnly ){
- assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
- pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */
+ }else if( eqOnly ){
+ assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
+ pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */
}
break;
}
@@ -91573,7 +91573,7 @@ case OP_Found: { /* jump, in3 */
int ii;
VdbeCursor *pC;
int res;
- UnpackedRecord *pFree;
+ UnpackedRecord *pFree;
UnpackedRecord *pIdxKey;
UnpackedRecord r;
@@ -91589,28 +91589,28 @@ case OP_Found: { /* jump, in3 */
pC->seekOp = pOp->opcode;
#endif
pIn3 = &aMem[pOp->p3];
- assert( pC->eCurType==CURTYPE_BTREE );
- assert( pC->uc.pCursor!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
assert( pC->isTable==0 );
if( pOp->p4.i>0 ){
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p4.i;
r.aMem = pIn3;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
for(ii=0; ii<r.nField; ii++){
assert( memIsValid(&r.aMem[ii]) );
- assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 );
+ assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 );
if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
- }
+ }
#endif
pIdxKey = &r;
- pFree = 0;
+ pFree = 0;
}else{
- assert( pIn3->flags & MEM_Blob );
- rc = ExpandBlob(pIn3);
- assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
- if( rc ) goto no_mem;
- pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
+ assert( pIn3->flags & MEM_Blob );
+ rc = ExpandBlob(pIn3);
+ assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+ if( rc ) goto no_mem;
+ pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
if( pIdxKey==0 ) goto no_mem;
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
}
@@ -91628,9 +91628,9 @@ case OP_Found: { /* jump, in3 */
}
}
rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &res);
- if( pFree ) sqlite3DbFreeNN(db, pFree);
+ if( pFree ) sqlite3DbFreeNN(db, pFree);
if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
+ goto abort_due_to_error;
}
pC->seekResult = res;
alreadyExists = (res==0);
@@ -91648,44 +91648,44 @@ case OP_Found: { /* jump, in3 */
break;
}
-/* Opcode: SeekRowid P1 P2 P3 * *
-** Synopsis: intkey=r[P3]
-**
-** P1 is the index of a cursor open on an SQL table btree (with integer
-** keys). If register P3 does not contain an integer or if P1 does not
+/* Opcode: SeekRowid P1 P2 P3 * *
+** Synopsis: intkey=r[P3]
+**
+** P1 is the index of a cursor open on an SQL table btree (with integer
+** keys). If register P3 does not contain an integer or if P1 does not
** contain a record with rowid P3 then jump immediately to P2.
-** Or, if P2 is 0, raise an SQLITE_CORRUPT error. If P1 does contain
+** Or, if P2 is 0, raise an SQLITE_CORRUPT error. If P1 does contain
** a record with rowid P3 then
-** leave the cursor pointing at that record and fall through to the next
-** instruction.
-**
-** The OP_NotExists opcode performs the same operation, but with OP_NotExists
-** the P3 register must be guaranteed to contain an integer value. With this
-** opcode, register P3 might not contain an integer.
-**
-** The OP_NotFound opcode performs the same operation on index btrees
-** (with arbitrary multi-value keys).
-**
-** This opcode leaves the cursor in a state where it cannot be advanced
-** in either direction. In other words, the Next and Prev opcodes will
-** not work following this opcode.
-**
-** See also: Found, NotFound, NoConflict, SeekRowid
-*/
+** leave the cursor pointing at that record and fall through to the next
+** instruction.
+**
+** The OP_NotExists opcode performs the same operation, but with OP_NotExists
+** the P3 register must be guaranteed to contain an integer value. With this
+** opcode, register P3 might not contain an integer.
+**
+** The OP_NotFound opcode performs the same operation on index btrees
+** (with arbitrary multi-value keys).
+**
+** This opcode leaves the cursor in a state where it cannot be advanced
+** in either direction. In other words, the Next and Prev opcodes will
+** not work following this opcode.
+**
+** See also: Found, NotFound, NoConflict, SeekRowid
+*/
/* Opcode: NotExists P1 P2 P3 * *
** Synopsis: intkey=r[P3]
**
** P1 is the index of a cursor open on an SQL table btree (with integer
** keys). P3 is an integer rowid. If P1 does not contain a record with
-** rowid P3 then jump immediately to P2. Or, if P2 is 0, raise an
+** rowid P3 then jump immediately to P2. Or, if P2 is 0, raise an
** SQLITE_CORRUPT error. If P1 does contain a record with rowid P3 then
-** leave the cursor pointing at that record and fall through to the next
-** instruction.
+** leave the cursor pointing at that record and fall through to the next
+** instruction.
+**
+** The OP_SeekRowid opcode performs the same operation but also allows the
+** P3 register to contain a non-integer value, in which case the jump is
+** always taken. This opcode requires that P3 always contain an integer.
**
-** The OP_SeekRowid opcode performs the same operation but also allows the
-** P3 register to contain a non-integer value, in which case the jump is
-** always taken. This opcode requires that P3 always contain an integer.
-**
** The OP_NotFound opcode performs the same operation on index btrees
** (with arbitrary multi-value keys).
**
@@ -91693,9 +91693,9 @@ case OP_Found: { /* jump, in3 */
** in either direction. In other words, the Next and Prev opcodes will
** not work following this opcode.
**
-** See also: Found, NotFound, NoConflict, SeekRowid
+** See also: Found, NotFound, NoConflict, SeekRowid
*/
-case OP_SeekRowid: { /* jump, in3 */
+case OP_SeekRowid: { /* jump, in3 */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
@@ -91717,11 +91717,11 @@ case OP_SeekRowid: { /* jump, in3 */
if( (x.flags & MEM_Int)==0 ) goto jump_to_p2;
iKey = x.u.i;
goto notExistsWithKey;
- }
- /* Fall through into OP_NotExists */
+ }
+ /* Fall through into OP_NotExists */
/* no break */ deliberate_fall_through
-case OP_NotExists: /* jump, in3 */
- pIn3 = &aMem[pOp->p3];
+case OP_NotExists: /* jump, in3 */
+ pIn3 = &aMem[pOp->p3];
assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
iKey = pIn3->u.i;
@@ -91732,27 +91732,27 @@ notExistsWithKey:
if( pOp->opcode==OP_SeekRowid ) pC->seekOp = OP_SeekRowid;
#endif
assert( pC->isTable );
- assert( pC->eCurType==CURTYPE_BTREE );
- pCrsr = pC->uc.pCursor;
+ assert( pC->eCurType==CURTYPE_BTREE );
+ pCrsr = pC->uc.pCursor;
assert( pCrsr!=0 );
res = 0;
rc = sqlite3BtreeTableMoveto(pCrsr, iKey, 0, &res);
- assert( rc==SQLITE_OK || res==0 );
+ assert( rc==SQLITE_OK || res==0 );
pC->movetoTarget = iKey; /* Used by OP_Delete */
pC->nullRow = 0;
pC->cacheStatus = CACHE_STALE;
pC->deferredMoveto = 0;
VdbeBranchTaken(res!=0,2);
pC->seekResult = res;
- if( res!=0 ){
- assert( rc==SQLITE_OK );
- if( pOp->p2==0 ){
- rc = SQLITE_CORRUPT_BKPT;
- }else{
- goto jump_to_p2;
- }
- }
- if( rc ) goto abort_due_to_error;
+ if( res!=0 ){
+ assert( rc==SQLITE_OK );
+ if( pOp->p2==0 ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }else{
+ goto jump_to_p2;
+ }
+ }
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -91767,7 +91767,7 @@ notExistsWithKey:
case OP_Sequence: { /* out2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( p->apCsr[pOp->p1]!=0 );
- assert( p->apCsr[pOp->p1]->eCurType!=CURTYPE_VTAB );
+ assert( p->apCsr[pOp->p1]->eCurType!=CURTYPE_VTAB );
pOut = out2Prerelease(p, pOp);
pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
break;
@@ -91806,8 +91806,8 @@ case OP_NewRowid: { /* out2 */
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->isTable );
- assert( pC->eCurType==CURTYPE_BTREE );
- assert( pC->uc.pCursor!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
{
/* The next rowid or record number (different terms for the same
** thing) is obtained in a two-step algorithm.
@@ -91835,15 +91835,15 @@ case OP_NewRowid: { /* out2 */
#endif
if( !pC->useRandomRowid ){
- rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
+ rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
if( res ){
v = 1; /* IMP: R-61914-48074 */
}else{
- assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) );
- v = sqlite3BtreeIntegerKey(pC->uc.pCursor);
+ assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) );
+ v = sqlite3BtreeIntegerKey(pC->uc.pCursor);
if( v>=MAX_ROWID ){
pC->useRandomRowid = 1;
}else{
@@ -91863,7 +91863,7 @@ case OP_NewRowid: { /* out2 */
pMem = &pFrame->aMem[pOp->p3];
}else{
/* Assert that P3 is a valid memory cell. */
- assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+ assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
pMem = &aMem[pOp->p3];
memAboutToChange(p, pMem);
}
@@ -91873,7 +91873,7 @@ case OP_NewRowid: { /* out2 */
sqlite3VdbeMemIntegerify(pMem);
assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
- rc = SQLITE_FULL; /* IMP: R-17817-00630 */
+ rc = SQLITE_FULL; /* IMP: R-17817-00630 */
goto abort_due_to_error;
}
if( v<pMem->u.i+1 ){
@@ -91897,8 +91897,8 @@ case OP_NewRowid: { /* out2 */
0, &res))==SQLITE_OK)
&& (res==0)
&& (++cnt<100));
- if( rc ) goto abort_due_to_error;
- if( res==0 ){
+ if( rc ) goto abort_due_to_error;
+ if( res==0 ){
rc = SQLITE_FULL; /* IMP: R-38219-53002 */
goto abort_due_to_error;
}
@@ -91925,10 +91925,10 @@ case OP_NewRowid: { /* out2 */
** then rowid is stored for subsequent return by the
** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
**
-** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might
-** run faster by avoiding an unnecessary seek on cursor P1. However,
-** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior
-** seeks on the cursor or if the most recent seek used a key equal to P3.
+** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might
+** run faster by avoiding an unnecessary seek on cursor P1. However,
+** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior
+** seeks on the cursor or if the most recent seek used a key equal to P3.
**
** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an
** UPDATE operation. Otherwise (if the flag is clear) then this opcode
@@ -91937,7 +91937,7 @@ case OP_NewRowid: { /* out2 */
**
** Parameter P4 may point to a Table structure, or may be NULL. If it is
** not NULL, then the update-hook (sqlite3.xUpdateCallback) is invoked
-** following a successful insert.
+** following a successful insert.
**
** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically
** allocated, then ownership of P2 is transferred to the pseudo-cursor
@@ -91954,19 +91954,19 @@ case OP_Insert: {
VdbeCursor *pC; /* Cursor to table into which insert is written */
int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */
const char *zDb; /* database name - used by the update hook */
- Table *pTab; /* Table structure - used by update and pre-update hooks */
- BtreePayload x; /* Payload to be inserted */
+ Table *pTab; /* Table structure - used by update and pre-update hooks */
+ BtreePayload x; /* Payload to be inserted */
pData = &aMem[pOp->p2];
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( memIsValid(pData) );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
- assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->deferredMoveto==0 );
- assert( pC->uc.pCursor!=0 );
- assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable );
- assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC );
+ assert( pC->uc.pCursor!=0 );
+ assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable );
+ assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC );
REGISTER_TRACE(pOp->p2, pData);
sqlite3VdbeIncrWriteCounter(p, pC);
@@ -91976,43 +91976,43 @@ case OP_Insert: {
REGISTER_TRACE(pOp->p3, pKey);
x.nKey = pKey->u.i;
- if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
- assert( pC->iDb>=0 );
- zDb = db->aDb[pC->iDb].zDbSName;
- pTab = pOp->p4.pTab;
- assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
+ if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
+ assert( pC->iDb>=0 );
+ zDb = db->aDb[pC->iDb].zDbSName;
+ pTab = pOp->p4.pTab;
+ assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
}else{
- pTab = 0;
+ pTab = 0;
zDb = 0;
}
-
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
- /* Invoke the pre-update hook, if any */
- if( pTab ){
- if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ /* Invoke the pre-update hook, if any */
+ if( pTab ){
+ if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){
sqlite3VdbePreUpdateHook(p,pC,SQLITE_INSERT,zDb,pTab,x.nKey,pOp->p2,-1);
- }
- if( db->xUpdateCallback==0 || pTab->aCol==0 ){
- /* Prevent post-update hook from running in cases when it should not */
- pTab = 0;
- }
- }
- if( pOp->p5 & OPFLAG_ISNOOP ) break;
-#endif
-
- if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
+ }
+ if( db->xUpdateCallback==0 || pTab->aCol==0 ){
+ /* Prevent post-update hook from running in cases when it should not */
+ pTab = 0;
+ }
+ }
+ if( pOp->p5 & OPFLAG_ISNOOP ) break;
+#endif
+
+ if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
+ if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 );
- x.pData = pData->z;
- x.nData = pData->n;
+ x.pData = pData->z;
+ x.nData = pData->n;
seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
if( pData->flags & MEM_Zero ){
- x.nZero = pData->u.nZero;
+ x.nZero = pData->u.nZero;
}else{
- x.nZero = 0;
+ x.nZero = 0;
}
- x.pKey = 0;
- rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
+ x.pKey = 0;
+ rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
(pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)),
seekResult
);
@@ -92020,13 +92020,13 @@ case OP_Insert: {
pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
- if( rc ) goto abort_due_to_error;
- if( pTab ){
- assert( db->xUpdateCallback!=0 );
- assert( pTab->aCol!=0 );
- db->xUpdateCallback(db->pUpdateArg,
- (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT,
- zDb, pTab->zName, x.nKey);
+ if( rc ) goto abort_due_to_error;
+ if( pTab ){
+ assert( db->xUpdateCallback!=0 );
+ assert( pTab->aCol!=0 );
+ db->xUpdateCallback(db->pUpdateArg,
+ (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT,
+ zDb, pTab->zName, x.nKey);
}
break;
}
@@ -92058,53 +92058,53 @@ case OP_RowCell: {
break;
};
-/* Opcode: Delete P1 P2 P3 P4 P5
+/* Opcode: Delete P1 P2 P3 P4 P5
**
** Delete the record at which the P1 cursor is currently pointing.
**
-** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then
-** the cursor will be left pointing at either the next or the previous
+** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then
+** the cursor will be left pointing at either the next or the previous
** record in the table. If it is left pointing at the next record, then
-** the next Next instruction will be a no-op. As a result, in this case
+** the next Next instruction will be a no-op. As a result, in this case
** it is ok to delete a record from within a Next loop. If
-** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be
-** left in an undefined state.
-**
-** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this
-** delete one of several associated with deleting a table row and all its
-** associated index entries. Exactly one of those deletes is the "primary"
-** delete. The others are all on OPFLAG_FORDELETE cursors or else are
-** marked with the AUXDELETE flag.
-**
-** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row
-** change count is incremented (otherwise not).
-**
+** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be
+** left in an undefined state.
+**
+** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this
+** delete one of several associated with deleting a table row and all its
+** associated index entries. Exactly one of those deletes is the "primary"
+** delete. The others are all on OPFLAG_FORDELETE cursors or else are
+** marked with the AUXDELETE flag.
+**
+** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row
+** change count is incremented (otherwise not).
+**
** P1 must not be pseudo-table. It has to be a real table with
** multiple rows.
**
** If P4 is not NULL then it points to a Table object. In this case either
-** the update or pre-update hook, or both, may be invoked. The P1 cursor must
+** the update or pre-update hook, or both, may be invoked. The P1 cursor must
** have been positioned using OP_NotFound prior to invoking this opcode in
** this case. Specifically, if one is configured, the pre-update hook is
** invoked if P4 is not NULL. The update-hook is invoked if one is configured,
-** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2.
-**
-** If the OPFLAG_ISUPDATE flag is set in P2, then P3 contains the address
-** of the memory cell that contains the value that the rowid of the row will
-** be set to by the update.
+** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2.
+**
+** If the OPFLAG_ISUPDATE flag is set in P2, then P3 contains the address
+** of the memory cell that contains the value that the rowid of the row will
+** be set to by the update.
*/
case OP_Delete: {
VdbeCursor *pC;
- const char *zDb;
- Table *pTab;
- int opflags;
+ const char *zDb;
+ Table *pTab;
+ int opflags;
- opflags = pOp->p2;
+ opflags = pOp->p2;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
- assert( pC->eCurType==CURTYPE_BTREE );
- assert( pC->uc.pCursor!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
assert( pC->deferredMoveto==0 );
sqlite3VdbeIncrWriteCounter(p, pC);
@@ -92114,83 +92114,83 @@ case OP_Delete: {
&& pOp->p5==0
&& sqlite3BtreeCursorIsValidNN(pC->uc.pCursor)
){
- /* If p5 is zero, the seek operation that positioned the cursor prior to
- ** OP_Delete will have also set the pC->movetoTarget field to the rowid of
- ** the row that is being deleted */
- i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor);
+ /* If p5 is zero, the seek operation that positioned the cursor prior to
+ ** OP_Delete will have also set the pC->movetoTarget field to the rowid of
+ ** the row that is being deleted */
+ i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor);
assert( CORRUPT_DB || pC->movetoTarget==iKey );
}
#endif
-
- /* If the update-hook or pre-update-hook will be invoked, set zDb to
- ** the name of the db to pass as to it. Also set local pTab to a copy
- ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was
+
+ /* If the update-hook or pre-update-hook will be invoked, set zDb to
+ ** the name of the db to pass as to it. Also set local pTab to a copy
+ ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was
** last moved with OP_Next or OP_Prev, not Seek or NotFound, set
- ** VdbeCursor.movetoTarget to the current rowid. */
- if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
- assert( pC->iDb>=0 );
- assert( pOp->p4.pTab!=0 );
- zDb = db->aDb[pC->iDb].zDbSName;
- pTab = pOp->p4.pTab;
- if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
- pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor);
- }
- }else{
+ ** VdbeCursor.movetoTarget to the current rowid. */
+ if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
+ assert( pC->iDb>=0 );
+ assert( pOp->p4.pTab!=0 );
+ zDb = db->aDb[pC->iDb].zDbSName;
+ pTab = pOp->p4.pTab;
+ if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
+ pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor);
+ }
+ }else{
zDb = 0;
pTab = 0;
- }
-
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
- /* Invoke the pre-update-hook if required. */
+ }
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ /* Invoke the pre-update-hook if required. */
assert( db->xPreUpdateCallback==0 || pTab==pOp->p4.pTab );
if( db->xPreUpdateCallback && pTab ){
assert( !(opflags & OPFLAG_ISUPDATE)
|| HasRowid(pTab)==0
|| (aMem[pOp->p3].flags & MEM_Int)
- );
- sqlite3VdbePreUpdateHook(p, pC,
+ );
+ sqlite3VdbePreUpdateHook(p, pC,
(opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE,
- zDb, pTab, pC->movetoTarget,
+ zDb, pTab, pC->movetoTarget,
pOp->p3, -1
- );
- }
- if( opflags & OPFLAG_ISNOOP ) break;
-#endif
+ );
+ }
+ if( opflags & OPFLAG_ISNOOP ) break;
+#endif
/* Only flags that can be set are SAVEPOISTION and AUXDELETE */
- assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 );
- assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION );
- assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE );
-
-#ifdef SQLITE_DEBUG
- if( p->pFrame==0 ){
- if( pC->isEphemeral==0
- && (pOp->p5 & OPFLAG_AUXDELETE)==0
- && (pC->wrFlag & OPFLAG_FORDELETE)==0
- ){
- nExtraDelete++;
- }
- if( pOp->p2 & OPFLAG_NCHANGE ){
- nExtraDelete--;
- }
- }
-#endif
-
- rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
+ assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 );
+ assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION );
+ assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE );
+
+#ifdef SQLITE_DEBUG
+ if( p->pFrame==0 ){
+ if( pC->isEphemeral==0
+ && (pOp->p5 & OPFLAG_AUXDELETE)==0
+ && (pC->wrFlag & OPFLAG_FORDELETE)==0
+ ){
+ nExtraDelete++;
+ }
+ if( pOp->p2 & OPFLAG_NCHANGE ){
+ nExtraDelete--;
+ }
+ }
+#endif
+
+ rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
pC->cacheStatus = CACHE_STALE;
- pC->seekResult = 0;
- if( rc ) goto abort_due_to_error;
+ pC->seekResult = 0;
+ if( rc ) goto abort_due_to_error;
/* Invoke the update-hook if required. */
- if( opflags & OPFLAG_NCHANGE ){
- p->nChange++;
+ if( opflags & OPFLAG_NCHANGE ){
+ p->nChange++;
if( db->xUpdateCallback && ALWAYS(pTab!=0) && HasRowid(pTab) ){
- db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,
- pC->movetoTarget);
- assert( pC->iDb>=0 );
- }
+ db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,
+ pC->movetoTarget);
+ assert( pC->iDb>=0 );
+ }
}
-
+
break;
}
/* Opcode: ResetCount * * * * *
@@ -92207,7 +92207,7 @@ case OP_ResetCount: {
}
/* Opcode: SorterCompare P1 P2 P3 P4
-** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2
+** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2
**
** P1 is a sorter cursor. This instruction compares a prefix of the
** record blob in register P3 against a prefix of the entry that
@@ -92234,7 +92234,7 @@ case OP_SorterCompare: {
res = 0;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
VdbeBranchTaken(res!=0,2);
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
if( res ) goto jump_to_p2;
break;
};
@@ -92260,59 +92260,59 @@ case OP_SorterData: {
rc = sqlite3VdbeSorterRowkey(pC, pOut);
assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
break;
}
-/* Opcode: RowData P1 P2 P3 * *
+/* Opcode: RowData P1 P2 P3 * *
** Synopsis: r[P2]=data
**
** Write into register P2 the complete row content for the row at
-** which cursor P1 is currently pointing.
+** which cursor P1 is currently pointing.
** There is no interpretation of the data.
** It is just copied onto the P2 register exactly as
** it is found in the database file.
**
-** If cursor P1 is an index, then the content is the key of the row.
-** If cursor P2 is a table, then the content extracted is the data.
-**
+** If cursor P1 is an index, then the content is the key of the row.
+** If cursor P2 is a table, then the content extracted is the data.
+**
** If the P1 cursor must be pointing to a valid row (not a NULL row)
** of a real table, not a pseudo-table.
**
** If P3!=0 then this opcode is allowed to make an ephemeral pointer
-** into the database page. That means that the content of the output
-** register will be invalidated as soon as the cursor moves - including
+** into the database page. That means that the content of the output
+** register will be invalidated as soon as the cursor moves - including
** moves caused by other cursors that "save" the current cursors
-** position in order that they can write to the same table. If P3==0
-** then a copy of the data is made into memory. P3!=0 is faster, but
-** P3==0 is safer.
+** position in order that they can write to the same table. If P3==0
+** then a copy of the data is made into memory. P3!=0 is faster, but
+** P3==0 is safer.
**
-** If P3!=0 then the content of the P2 register is unsuitable for use
-** in OP_Result and any OP_Result will invalidate the P2 register content.
-** The P2 register content is invalidated by opcodes like OP_Function or
-** by any use of another cursor pointing to the same table.
+** If P3!=0 then the content of the P2 register is unsuitable for use
+** in OP_Result and any OP_Result will invalidate the P2 register content.
+** The P2 register content is invalidated by opcodes like OP_Function or
+** by any use of another cursor pointing to the same table.
*/
case OP_RowData: {
VdbeCursor *pC;
BtCursor *pCrsr;
u32 n;
- pOut = out2Prerelease(p, pOp);
+ pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
- assert( pC!=0 );
- assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
assert( isSorter(pC)==0 );
assert( pC->nullRow==0 );
- assert( pC->uc.pCursor!=0 );
- pCrsr = pC->uc.pCursor;
+ assert( pC->uc.pCursor!=0 );
+ pCrsr = pC->uc.pCursor;
- /* The OP_RowData opcodes always follow OP_NotExists or
- ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions
- ** that might invalidate the cursor.
- ** If this where not the case, on of the following assert()s
+ /* The OP_RowData opcodes always follow OP_NotExists or
+ ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions
+ ** that might invalidate the cursor.
+ ** If this where not the case, on of the following assert()s
** would fail. Should this ever change (because of changes in the code
** generator) then the fix would be to insert a call to
** sqlite3VdbeCursorMoveto().
@@ -92320,14 +92320,14 @@ case OP_RowData: {
assert( pC->deferredMoveto==0 );
assert( sqlite3BtreeCursorIsValid(pCrsr) );
- n = sqlite3BtreePayloadSize(pCrsr);
- if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
+ n = sqlite3BtreePayloadSize(pCrsr);
+ if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ goto too_big;
}
testcase( n==0 );
rc = sqlite3VdbeMemFromBtreeZeroOffset(pCrsr, n, pOut);
- if( rc ) goto abort_due_to_error;
- if( !pOp->p3 ) Deephemeralize(pOut);
+ if( rc ) goto abort_due_to_error;
+ if( !pOp->p3 ) Deephemeralize(pOut);
UPDATE_MAX_BLOBSIZE(pOut);
REGISTER_TRACE(pOp->p2, pOut);
break;
@@ -92353,32 +92353,32 @@ case OP_Rowid: { /* out2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
- assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
+ assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
if( pC->nullRow ){
pOut->flags = MEM_Null;
break;
}else if( pC->deferredMoveto ){
v = pC->movetoTarget;
#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( pC->eCurType==CURTYPE_VTAB ){
- assert( pC->uc.pVCur!=0 );
- pVtab = pC->uc.pVCur->pVtab;
+ }else if( pC->eCurType==CURTYPE_VTAB ){
+ assert( pC->uc.pVCur!=0 );
+ pVtab = pC->uc.pVCur->pVtab;
pModule = pVtab->pModule;
assert( pModule->xRowid );
- rc = pModule->xRowid(pC->uc.pVCur, &v);
+ rc = pModule->xRowid(pC->uc.pVCur, &v);
sqlite3VtabImportErrmsg(p, pVtab);
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
- assert( pC->eCurType==CURTYPE_BTREE );
- assert( pC->uc.pCursor!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
rc = sqlite3VdbeCursorRestore(pC);
if( rc ) goto abort_due_to_error;
if( pC->nullRow ){
pOut->flags = MEM_Null;
break;
}
- v = sqlite3BtreeIntegerKey(pC->uc.pCursor);
+ v = sqlite3BtreeIntegerKey(pC->uc.pCursor);
}
pOut->u.i = v;
break;
@@ -92398,9 +92398,9 @@ case OP_NullRow: {
assert( pC!=0 );
pC->nullRow = 1;
pC->cacheStatus = CACHE_STALE;
- if( pC->eCurType==CURTYPE_BTREE ){
- assert( pC->uc.pCursor!=0 );
- sqlite3BtreeClearCursor(pC->uc.pCursor);
+ if( pC->eCurType==CURTYPE_BTREE ){
+ assert( pC->uc.pCursor!=0 );
+ sqlite3BtreeClearCursor(pC->uc.pCursor);
}
#ifdef SQLITE_DEBUG
if( pC->seekOp==0 ) pC->seekOp = OP_NullRow;
@@ -92408,18 +92408,18 @@ case OP_NullRow: {
break;
}
-/* Opcode: SeekEnd P1 * * * *
+/* Opcode: SeekEnd P1 * * * *
+**
+** Position cursor P1 at the end of the btree for the purpose of
+** appending a new entry onto the btree.
+**
+** It is assumed that the cursor is used only for appending and so
+** if the cursor is valid, then the cursor must already be pointing
+** at the end of the btree and so no changes are made to
+** the cursor.
+*/
+/* Opcode: Last P1 P2 * * *
**
-** Position cursor P1 at the end of the btree for the purpose of
-** appending a new entry onto the btree.
-**
-** It is assumed that the cursor is used only for appending and so
-** if the cursor is valid, then the cursor must already be pointing
-** at the end of the btree and so no changes are made to
-** the cursor.
-*/
-/* Opcode: Last P1 P2 * * *
-**
** The next use of the Rowid or Column or Prev instruction for P1
** will refer to the last entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
@@ -92430,7 +92430,7 @@ case OP_NullRow: {
** from the end toward the beginning. In other words, the cursor is
** configured to use Prev, not Next.
*/
-case OP_SeekEnd:
+case OP_SeekEnd:
case OP_Last: { /* jump */
VdbeCursor *pC;
BtCursor *pCrsr;
@@ -92439,25 +92439,25 @@ case OP_Last: { /* jump */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
- assert( pC->eCurType==CURTYPE_BTREE );
- pCrsr = pC->uc.pCursor;
+ assert( pC->eCurType==CURTYPE_BTREE );
+ pCrsr = pC->uc.pCursor;
res = 0;
assert( pCrsr!=0 );
-#ifdef SQLITE_DEBUG
- pC->seekOp = pOp->opcode;
-#endif
- if( pOp->opcode==OP_SeekEnd ){
- assert( pOp->p2==0 );
- pC->seekResult = -1;
- if( sqlite3BtreeCursorIsValidNN(pCrsr) ){
- break;
- }
- }
+#ifdef SQLITE_DEBUG
+ pC->seekOp = pOp->opcode;
+#endif
+ if( pOp->opcode==OP_SeekEnd ){
+ assert( pOp->p2==0 );
+ pC->seekResult = -1;
+ if( sqlite3BtreeCursorIsValidNN(pCrsr) ){
+ break;
+ }
+ }
rc = sqlite3BtreeLast(pCrsr, &res);
pC->nullRow = (u8)res;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
@@ -92465,43 +92465,43 @@ case OP_Last: { /* jump */
break;
}
-/* Opcode: IfSmaller P1 P2 P3 * *
-**
-** Estimate the number of rows in the table P1. Jump to P2 if that
-** estimate is less than approximately 2**(0.1*P3).
-*/
-case OP_IfSmaller: { /* jump */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- i64 sz;
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- pC = p->apCsr[pOp->p1];
- assert( pC!=0 );
- pCrsr = pC->uc.pCursor;
- assert( pCrsr );
- rc = sqlite3BtreeFirst(pCrsr, &res);
- if( rc ) goto abort_due_to_error;
- if( res==0 ){
- sz = sqlite3BtreeRowCountEst(pCrsr);
- if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)<pOp->p3 ) res = 1;
- }
- VdbeBranchTaken(res!=0,2);
- if( res ) goto jump_to_p2;
- break;
-}
-
-
-/* Opcode: SorterSort P1 P2 * * *
-**
-** After all records have been inserted into the Sorter object
-** identified by P1, invoke this opcode to actually do the sorting.
-** Jump to P2 if there are no records to be sorted.
-**
-** This opcode is an alias for OP_Sort and OP_Rewind that is used
-** for Sorter objects.
-*/
+/* Opcode: IfSmaller P1 P2 P3 * *
+**
+** Estimate the number of rows in the table P1. Jump to P2 if that
+** estimate is less than approximately 2**(0.1*P3).
+*/
+case OP_IfSmaller: { /* jump */
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int res;
+ i64 sz;
+
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ pCrsr = pC->uc.pCursor;
+ assert( pCrsr );
+ rc = sqlite3BtreeFirst(pCrsr, &res);
+ if( rc ) goto abort_due_to_error;
+ if( res==0 ){
+ sz = sqlite3BtreeRowCountEst(pCrsr);
+ if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)<pOp->p3 ) res = 1;
+ }
+ VdbeBranchTaken(res!=0,2);
+ if( res ) goto jump_to_p2;
+ break;
+}
+
+
+/* Opcode: SorterSort P1 P2 * * *
+**
+** After all records have been inserted into the Sorter object
+** identified by P1, invoke this opcode to actually do the sorting.
+** Jump to P2 if there are no records to be sorted.
+**
+** This opcode is an alias for OP_Sort and OP_Rewind that is used
+** for Sorter objects.
+*/
/* Opcode: Sort P1 P2 * * *
**
** This opcode does exactly the same thing as OP_Rewind except that
@@ -92553,14 +92553,14 @@ case OP_Rewind: { /* jump */
if( isSorter(pC) ){
rc = sqlite3VdbeSorterRewind(pC, &res);
}else{
- assert( pC->eCurType==CURTYPE_BTREE );
- pCrsr = pC->uc.pCursor;
+ assert( pC->eCurType==CURTYPE_BTREE );
+ pCrsr = pC->uc.pCursor;
assert( pCrsr );
rc = sqlite3BtreeFirst(pCrsr, &res);
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
VdbeBranchTaken(res!=0,2);
@@ -92621,19 +92621,19 @@ case OP_Rewind: { /* jump */
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
*/
-/* Opcode: SorterNext P1 P2 * * P5
-**
-** This opcode works just like OP_Next except that P1 must be a
-** sorter object for which the OP_SorterSort opcode has been
-** invoked. This opcode advances the cursor to the next sorted
-** record, or jumps to P2 if there are no more sorted records.
-*/
+/* Opcode: SorterNext P1 P2 * * P5
+**
+** This opcode works just like OP_Next except that P1 must be a
+** sorter object for which the OP_SorterSort opcode has been
+** invoked. This opcode advances the cursor to the next sorted
+** record, or jumps to P2 if there are no more sorted records.
+*/
case OP_SorterNext: { /* jump */
VdbeCursor *pC;
pC = p->apCsr[pOp->p1];
assert( isSorter(pC) );
- rc = sqlite3VdbeSorterNext(db, pC);
+ rc = sqlite3VdbeSorterNext(db, pC);
goto next_tail;
case OP_Prev: /* jump */
case OP_Next: /* jump */
@@ -92642,7 +92642,7 @@ case OP_Next: /* jump */
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->deferredMoveto==0 );
- assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->eCurType==CURTYPE_BTREE );
assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
@@ -92658,11 +92658,11 @@ case OP_Next: /* jump */
|| pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope
|| pC->seekOp==OP_NullRow);
- rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
+ rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
next_tail:
pC->cacheStatus = CACHE_STALE;
- VdbeBranchTaken(rc==SQLITE_OK,2);
- if( rc==SQLITE_OK ){
+ VdbeBranchTaken(rc==SQLITE_OK,2);
+ if( rc==SQLITE_OK ){
pC->nullRow = 0;
p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST
@@ -92670,35 +92670,35 @@ next_tail:
#endif
goto jump_to_p2_and_check_for_interrupt;
}
- if( rc!=SQLITE_DONE ) goto abort_due_to_error;
- rc = SQLITE_OK;
- pC->nullRow = 1;
+ if( rc!=SQLITE_DONE ) goto abort_due_to_error;
+ rc = SQLITE_OK;
+ pC->nullRow = 1;
goto check_for_interrupt;
}
-/* Opcode: IdxInsert P1 P2 P3 P4 P5
+/* Opcode: IdxInsert P1 P2 P3 P4 P5
** Synopsis: key=r[P2]
**
** Register P2 holds an SQL index key made using the
** MakeRecord instructions. This opcode writes that key
** into the index P1. Data for the entry is nil.
**
-** If P4 is not zero, then it is the number of values in the unpacked
-** key of reg(P2). In that case, P3 is the index of the first register
-** for the unpacked key. The availability of the unpacked key can sometimes
-** be an optimization.
+** If P4 is not zero, then it is the number of values in the unpacked
+** key of reg(P2). In that case, P3 is the index of the first register
+** for the unpacked key. The availability of the unpacked key can sometimes
+** be an optimization.
+**
+** If P5 has the OPFLAG_APPEND bit set, that is a hint to the b-tree layer
+** that this insert is likely to be an append.
**
-** If P5 has the OPFLAG_APPEND bit set, that is a hint to the b-tree layer
-** that this insert is likely to be an append.
-**
** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is
** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear,
** then the change counter is unchanged.
**
-** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might
-** run faster by avoiding an unnecessary seek on cursor P1. However,
-** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior
-** seeks on the cursor or if the most recent seek used a key equivalent
+** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might
+** run faster by avoiding an unnecessary seek on cursor P1. However,
+** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior
+** seeks on the cursor or if the most recent seek used a key equivalent
** to P2.
**
** This instruction only works for indices. The equivalent instruction
@@ -92734,13 +92734,13 @@ case OP_IdxInsert: { /* in2 */
break;
}
-/* Opcode: SorterInsert P1 P2 * * *
-** Synopsis: key=r[P2]
-**
-** Register P2 holds an SQL index key made using the
-** MakeRecord instructions. This opcode writes that key
-** into the sorter P1. Data for the entry is nil.
-*/
+/* Opcode: SorterInsert P1 P2 * * *
+** Synopsis: key=r[P2]
+**
+** Register P2 holds an SQL index key made using the
+** MakeRecord instructions. This opcode writes that key
+** into the sorter P1. Data for the entry is nil.
+*/
case OP_SorterInsert: { /* in2 */
VdbeCursor *pC;
@@ -92753,9 +92753,9 @@ case OP_SorterInsert: { /* in2 */
assert( pIn2->flags & MEM_Blob );
assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
rc = sqlite3VdbeSorterWrite(pC, pIn2);
- if( rc) goto abort_due_to_error;
+ if( rc) goto abort_due_to_error;
break;
}
@@ -92781,52 +92781,52 @@ case OP_IdxDelete: {
UnpackedRecord r;
assert( pOp->p3>0 );
- assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 );
+ assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
- assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->eCurType==CURTYPE_BTREE );
sqlite3VdbeIncrWriteCounter(p, pC);
- pCrsr = pC->uc.pCursor;
+ pCrsr = pC->uc.pCursor;
assert( pCrsr!=0 );
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p3;
r.default_rc = 0;
r.aMem = &aMem[pOp->p2];
rc = sqlite3BtreeIndexMoveto(pCrsr, &r, &res);
- if( rc ) goto abort_due_to_error;
- if( res==0 ){
- rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
+ if( res==0 ){
+ rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
+ if( rc ) goto abort_due_to_error;
}else if( pOp->p5 && !sqlite3WritableSchema(db) ){
rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption");
goto abort_due_to_error;
}
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;
- pC->seekResult = 0;
+ pC->seekResult = 0;
break;
}
-/* Opcode: DeferredSeek P1 * P3 P4 *
-** Synopsis: Move P3 to P1.rowid if needed
-**
-** P1 is an open index cursor and P3 is a cursor on the corresponding
-** table. This opcode does a deferred seek of the P3 table cursor
-** to the row that corresponds to the current row of P1.
-**
-** This is a deferred seek. Nothing actually happens until
-** the cursor is used to read a record. That way, if no reads
-** occur, no unnecessary I/O happens.
-**
-** P4 may be an array of integers (type P4_INTARRAY) containing
-** one entry for each column in the P3 table. If array entry a(i)
+/* Opcode: DeferredSeek P1 * P3 P4 *
+** Synopsis: Move P3 to P1.rowid if needed
+**
+** P1 is an open index cursor and P3 is a cursor on the corresponding
+** table. This opcode does a deferred seek of the P3 table cursor
+** to the row that corresponds to the current row of P1.
+**
+** This is a deferred seek. Nothing actually happens until
+** the cursor is used to read a record. That way, if no reads
+** occur, no unnecessary I/O happens.
+**
+** P4 may be an array of integers (type P4_INTARRAY) containing
+** one entry for each column in the P3 table. If array entry a(i)
** is non-zero, then reading column a(i)-1 from cursor P3 is
** equivalent to performing the deferred seek and then reading column i
-** from P1. This information is stored in P3 and used to redirect
-** reads against P3 over to P1, thus possibly avoiding the need to
-** seek and read cursor P3.
-*/
+** from P1. This information is stored in P3 and used to redirect
+** reads against P3 over to P1, thus possibly avoiding the need to
+** seek and read cursor P3.
+*/
/* Opcode: IdxRowid P1 P2 * * *
** Synopsis: r[P2]=rowid
**
@@ -92836,58 +92836,58 @@ case OP_IdxDelete: {
**
** See also: Rowid, MakeRecord.
*/
-case OP_DeferredSeek:
-case OP_IdxRowid: { /* out2 */
- VdbeCursor *pC; /* The P1 index cursor */
- VdbeCursor *pTabCur; /* The P2 table cursor (OP_DeferredSeek only) */
- i64 rowid; /* Rowid that P1 current points to */
+case OP_DeferredSeek:
+case OP_IdxRowid: { /* out2 */
+ VdbeCursor *pC; /* The P1 index cursor */
+ VdbeCursor *pTabCur; /* The P2 table cursor (OP_DeferredSeek only) */
+ i64 rowid; /* Rowid that P1 current points to */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
- assert( pC->eCurType==CURTYPE_BTREE );
- assert( pC->uc.pCursor!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
assert( pC->isTable==0 );
assert( pC->deferredMoveto==0 );
- assert( !pC->nullRow || pOp->opcode==OP_IdxRowid );
+ assert( !pC->nullRow || pOp->opcode==OP_IdxRowid );
+
+ /* The IdxRowid and Seek opcodes are combined because of the commonality
+ ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */
+ rc = sqlite3VdbeCursorRestore(pC);
- /* The IdxRowid and Seek opcodes are combined because of the commonality
- ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */
- rc = sqlite3VdbeCursorRestore(pC);
-
/* sqlite3VbeCursorRestore() can only fail if the record has been deleted
- ** out from under the cursor. That will never happens for an IdxRowid
- ** or Seek opcode */
+ ** out from under the cursor. That will never happens for an IdxRowid
+ ** or Seek opcode */
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
if( !pC->nullRow ){
rowid = 0; /* Not needed. Only used to silence a warning. */
- rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid);
+ rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- if( pOp->opcode==OP_DeferredSeek ){
- assert( pOp->p3>=0 && pOp->p3<p->nCursor );
- pTabCur = p->apCsr[pOp->p3];
- assert( pTabCur!=0 );
- assert( pTabCur->eCurType==CURTYPE_BTREE );
- assert( pTabCur->uc.pCursor!=0 );
- assert( pTabCur->isTable );
- pTabCur->nullRow = 0;
- pTabCur->movetoTarget = rowid;
- pTabCur->deferredMoveto = 1;
- assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
- pTabCur->aAltMap = pOp->p4.ai;
+ if( pOp->opcode==OP_DeferredSeek ){
+ assert( pOp->p3>=0 && pOp->p3<p->nCursor );
+ pTabCur = p->apCsr[pOp->p3];
+ assert( pTabCur!=0 );
+ assert( pTabCur->eCurType==CURTYPE_BTREE );
+ assert( pTabCur->uc.pCursor!=0 );
+ assert( pTabCur->isTable );
+ pTabCur->nullRow = 0;
+ pTabCur->movetoTarget = rowid;
+ pTabCur->deferredMoveto = 1;
+ assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
+ pTabCur->aAltMap = pOp->p4.ai;
assert( !pC->isEphemeral );
assert( !pTabCur->isEphemeral );
- pTabCur->pAltCursor = pC;
- }else{
- pOut = out2Prerelease(p, pOp);
- pOut->u.i = rowid;
- }
- }else{
- assert( pOp->opcode==OP_IdxRowid );
- sqlite3VdbeMemSetNull(&aMem[pOp->p2]);
+ pTabCur->pAltCursor = pC;
+ }else{
+ pOut = out2Prerelease(p, pOp);
+ pOut->u.i = rowid;
+ }
+ }else{
+ assert( pOp->opcode==OP_IdxRowid );
+ sqlite3VdbeMemSetNull(&aMem[pOp->p2]);
}
break;
}
@@ -92966,8 +92966,8 @@ case OP_IdxGE: { /* jump */
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->isOrdered );
- assert( pC->eCurType==CURTYPE_BTREE );
- assert( pC->uc.pCursor!=0);
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0);
assert( pC->deferredMoveto==0 );
assert( pOp->p4type==P4_INT32 );
r.pKeyInfo = pC->pKeyInfo;
@@ -93041,18 +93041,18 @@ case OP_IdxGE: { /* jump */
** might be moved into the newly deleted root page in order to keep all
** root pages contiguous at the beginning of the database. The former
** value of the root page that moved - its value before the move occurred -
-** is stored in register P2. If no page movement was required (because the
+** is stored in register P2. If no page movement was required (because the
** table being dropped was already the last one in the database) then a
** zero is stored in register P2. If AUTOVACUUM is disabled then a zero
-** is stored in register P2.
+** is stored in register P2.
**
-** This opcode throws an error if there are any active reader VMs when
+** This opcode throws an error if there are any active reader VMs when
** it is invoked. This is done to avoid the difficulty associated with
** updating existing cursors when a root page is moved in an AUTOVACUUM
** database. This error is thrown even if the database is not an AUTOVACUUM
** db in order to avoid introducing an incompatibility between autovacuum
-** and non-autovacuum modes.
-**
+** and non-autovacuum modes.
+**
** See also: Clear
*/
case OP_Destroy: { /* out2 */
@@ -93061,13 +93061,13 @@ case OP_Destroy: { /* out2 */
sqlite3VdbeIncrWriteCounter(p, 0);
assert( p->readOnly==0 );
- assert( pOp->p1>1 );
+ assert( pOp->p1>1 );
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Null;
if( db->nVdbeRead > db->nVDestroy+1 ){
rc = SQLITE_LOCKED;
p->errorAction = OE_Abort;
- goto abort_due_to_error;
+ goto abort_due_to_error;
}else{
iDb = pOp->p3;
assert( DbMaskTest(p->btreeMask, iDb) );
@@ -93075,9 +93075,9 @@ case OP_Destroy: { /* out2 */
rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
pOut->flags = MEM_Int;
pOut->u.i = iMoved;
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( iMoved!=0 ){
+ if( iMoved!=0 ){
sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1);
/* All OP_Destroy operations occur on the same btree */
assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 );
@@ -93121,7 +93121,7 @@ case OP_Clear: {
aMem[pOp->p3].u.i += nChange;
}
}
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -93139,58 +93139,58 @@ case OP_ResetSorter: {
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
- if( isSorter(pC) ){
- sqlite3VdbeSorterReset(db, pC->uc.pSorter);
+ if( isSorter(pC) ){
+ sqlite3VdbeSorterReset(db, pC->uc.pSorter);
}else{
- assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->isEphemeral );
- rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor);
- if( rc ) goto abort_due_to_error;
+ rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor);
+ if( rc ) goto abort_due_to_error;
}
break;
}
-/* Opcode: CreateBtree P1 P2 P3 * *
-** Synopsis: r[P2]=root iDb=P1 flags=P3
+/* Opcode: CreateBtree P1 P2 P3 * *
+** Synopsis: r[P2]=root iDb=P1 flags=P3
**
-** Allocate a new b-tree in the main database file if P1==0 or in the
-** TEMP database file if P1==1 or in an attached database if
-** P1>1. The P3 argument must be 1 (BTREE_INTKEY) for a rowid table
+** Allocate a new b-tree in the main database file if P1==0 or in the
+** TEMP database file if P1==1 or in an attached database if
+** P1>1. The P3 argument must be 1 (BTREE_INTKEY) for a rowid table
** it must be 2 (BTREE_BLOBKEY) for an index or WITHOUT ROWID table.
-** The root page number of the new b-tree is stored in register P2.
+** The root page number of the new b-tree is stored in register P2.
*/
-case OP_CreateBtree: { /* out2 */
+case OP_CreateBtree: { /* out2 */
Pgno pgno;
Db *pDb;
sqlite3VdbeIncrWriteCounter(p, 0);
pOut = out2Prerelease(p, pOp);
pgno = 0;
- assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY );
+ assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 );
pDb = &db->aDb[pOp->p1];
assert( pDb->pBt!=0 );
- rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, pOp->p3);
- if( rc ) goto abort_due_to_error;
+ rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, pOp->p3);
+ if( rc ) goto abort_due_to_error;
pOut->u.i = pgno;
break;
}
-/* Opcode: SqlExec * * * P4 *
-**
-** Run the SQL statement or statements specified in the P4 string.
-*/
-case OP_SqlExec: {
+/* Opcode: SqlExec * * * P4 *
+**
+** Run the SQL statement or statements specified in the P4 string.
+*/
+case OP_SqlExec: {
sqlite3VdbeIncrWriteCounter(p, 0);
- db->nSqlExec++;
- rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0);
- db->nSqlExec--;
- if( rc ) goto abort_due_to_error;
- break;
-}
-
+ db->nSqlExec++;
+ rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0);
+ db->nSqlExec--;
+ if( rc ) goto abort_due_to_error;
+ break;
+}
+
/* Opcode: ParseSchema P1 * * P4 *
**
** Read and parse all entries from the schema table of database P1
@@ -93242,7 +93242,7 @@ case OP_ParseSchema: {
"SELECT*FROM\"%w\".%s WHERE %s ORDER BY rowid",
db->aDb[iDb].zDbSName, zSchema, pOp->p4.z);
if( zSql==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}else{
assert( db->init.busy==0 );
db->init.busy = 1;
@@ -93257,16 +93257,16 @@ case OP_ParseSchema: {
** the sqlite_schema table is corrupt. */
rc = SQLITE_CORRUPT_BKPT;
}
- sqlite3DbFreeNN(db, zSql);
+ sqlite3DbFreeNN(db, zSql);
db->init.busy = 0;
}
}
- if( rc ){
- sqlite3ResetAllSchemasOfConnection(db);
- if( rc==SQLITE_NOMEM ){
- goto no_mem;
- }
- goto abort_due_to_error;
+ if( rc ){
+ sqlite3ResetAllSchemasOfConnection(db);
+ if( rc==SQLITE_NOMEM ){
+ goto no_mem;
+ }
+ goto abort_due_to_error;
}
break;
}
@@ -93281,7 +93281,7 @@ case OP_ParseSchema: {
case OP_LoadAnalysis: {
assert( pOp->p1>=0 && pOp->p1<db->nDb );
rc = sqlite3AnalysisLoad(db, pOp->p1);
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* !defined(SQLITE_OMIT_ANALYZE) */
@@ -93330,19 +93330,19 @@ case OP_DropTrigger: {
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/* Opcode: IntegrityCk P1 P2 P3 P4 P5
+/* Opcode: IntegrityCk P1 P2 P3 P4 P5
**
** Do an analysis of the currently open database. Store in
** register P1 the text of an error message describing any problems.
** If no problems are found, store a NULL in register P1.
**
-** The register P3 contains one less than the maximum number of allowed errors.
+** The register P3 contains one less than the maximum number of allowed errors.
** At most reg(P3) errors will be reported.
** In other words, the analysis stops as soon as reg(P1) errors are
** seen. Reg(P1) is updated with the number of errors remaining.
**
-** The root page numbers of all tables in the database are integers
-** stored in P4_INTARRAY argument.
+** The root page numbers of all tables in the database are integers
+** stored in P4_INTARRAY argument.
**
** If P5 is not zero, the check is done on the auxiliary database
** file, not the main database file.
@@ -93358,10 +93358,10 @@ case OP_IntegrityCk: {
assert( p->bIsReader );
nRoot = pOp->p2;
- aRoot = pOp->p4.ai;
+ aRoot = pOp->p4.ai;
assert( nRoot>0 );
assert( aRoot[0]==(Pgno)nRoot );
- assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
pnErr = &aMem[pOp->p3];
assert( (pnErr->flags & MEM_Int)!=0 );
assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 );
@@ -93369,14 +93369,14 @@ case OP_IntegrityCk: {
assert( pOp->p5<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p5) );
z = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot,
- (int)pnErr->u.i+1, &nErr);
+ (int)pnErr->u.i+1, &nErr);
sqlite3VdbeMemSetNull(pIn1);
if( nErr==0 ){
assert( z==0 );
}else if( z==0 ){
goto no_mem;
}else{
- pnErr->u.i -= nErr-1;
+ pnErr->u.i -= nErr-1;
sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
}
UPDATE_MAX_BLOBSIZE(pIn1);
@@ -93386,9 +93386,9 @@ case OP_IntegrityCk: {
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/* Opcode: RowSetAdd P1 P2 * * *
-** Synopsis: rowset(P1)=r[P2]
+** Synopsis: rowset(P1)=r[P2]
**
-** Insert the integer value held by register P2 into a RowSet object
+** Insert the integer value held by register P2 into a RowSet object
** held in register P1.
**
** An assertion fails if P2 is not an integer.
@@ -93406,11 +93406,11 @@ case OP_RowSetAdd: { /* in1, in2 */
}
/* Opcode: RowSetRead P1 P2 P3 * *
-** Synopsis: r[P3]=rowset(P1)
+** Synopsis: r[P3]=rowset(P1)
**
-** Extract the smallest value from the RowSet object in P1
-** and put that value into register P3.
-** Or, if RowSet object P1 is initially empty, leave P3
+** Extract the smallest value from the RowSet object in P1
+** and put that value into register P3.
+** Or, if RowSet object P1 is initially empty, leave P3
** unchanged and jump to instruction P2.
*/
case OP_RowSetRead: { /* jump, in1, out3 */
@@ -93442,14 +93442,14 @@ case OP_RowSetRead: { /* jump, in1, out3 */
** integer in P3 into the RowSet and continue on to the
** next opcode.
**
-** The RowSet object is optimized for the case where sets of integers
-** are inserted in distinct phases, which each set contains no duplicates.
-** Each set is identified by a unique P4 value. The first set
-** must have P4==0, the final set must have P4==-1, and for all other sets
-** must have P4>0.
+** The RowSet object is optimized for the case where sets of integers
+** are inserted in distinct phases, which each set contains no duplicates.
+** Each set is identified by a unique P4 value. The first set
+** must have P4==0, the final set must have P4==-1, and for all other sets
+** must have P4>0.
**
** This allows optimizations: (a) when P4==0 there is no need to test
-** the RowSet object for P3, as it is guaranteed not to contain it,
+** the RowSet object for P3, as it is guaranteed not to contain it,
** (b) when P4==-1 there is no need to insert the value, as it will
** never be tested for, and (c) when a value that is part of set X is
** inserted, there is no need to search to see if the same value was
@@ -93537,7 +93537,7 @@ case OP_Program: { /* jump */
if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
rc = SQLITE_ERROR;
sqlite3VdbeError(p, "too many levels of trigger recursion");
- goto abort_due_to_error;
+ goto abort_due_to_error;
}
/* Register pRt is used to store the memory required to save the state
@@ -93551,12 +93551,12 @@ case OP_Program: { /* jump */
** variable nMem (and later, VdbeFrame.nChildMem) to this value.
*/
nMem = pProgram->nMem + pProgram->nCsr;
- assert( nMem>0 );
- if( pProgram->nCsr==0 ) nMem++;
+ assert( nMem>0 );
+ if( pProgram->nCsr==0 ) nMem++;
nByte = ROUND8(sizeof(VdbeFrame))
+ nMem * sizeof(Mem)
- + pProgram->nCsr * sizeof(VdbeCursor*)
- + (pProgram->nOp + 7)/8;
+ + pProgram->nCsr * sizeof(VdbeCursor*)
+ + (pProgram->nOp + 7)/8;
pFrame = sqlite3DbMallocZero(db, nByte);
if( !pFrame ){
goto no_mem;
@@ -93594,27 +93594,27 @@ case OP_Program: { /* jump */
pFrame = (VdbeFrame*)pRt->z;
assert( pRt->xDel==sqlite3VdbeFrameMemDel );
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem
- || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) );
+ || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) );
assert( pProgram->nCsr==pFrame->nChildCsr );
assert( (int)(pOp - aOp)==pFrame->pc );
}
p->nFrame++;
pFrame->pParent = p->pFrame;
- pFrame->lastRowid = db->lastRowid;
+ pFrame->lastRowid = db->lastRowid;
pFrame->nChange = p->nChange;
pFrame->nDbChange = p->db->nChange;
- assert( pFrame->pAuxData==0 );
- pFrame->pAuxData = p->pAuxData;
- p->pAuxData = 0;
+ assert( pFrame->pAuxData==0 );
+ pFrame->pAuxData = p->pAuxData;
+ p->pAuxData = 0;
p->nChange = 0;
p->pFrame = pFrame;
- p->aMem = aMem = VdbeFrameMem(pFrame);
+ p->aMem = aMem = VdbeFrameMem(pFrame);
p->nMem = pFrame->nChildMem;
p->nCursor = (u16)pFrame->nChildCsr;
- p->apCsr = (VdbeCursor **)&aMem[p->nMem];
- pFrame->aOnce = (u8*)&p->apCsr[pProgram->nCsr];
- memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8);
+ p->apCsr = (VdbeCursor **)&aMem[p->nMem];
+ pFrame->aOnce = (u8*)&p->apCsr[pProgram->nCsr];
+ memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8);
p->aOp = aOp = pProgram->aOp;
p->nOp = pProgram->nOp;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
@@ -93734,12 +93734,12 @@ case OP_MemMax: { /* in2 */
}
#endif /* SQLITE_OMIT_AUTOINCREMENT */
-/* Opcode: IfPos P1 P2 P3 * *
-** Synopsis: if r[P1]>0 then r[P1]-=P3, goto P2
+/* Opcode: IfPos P1 P2 P3 * *
+** Synopsis: if r[P1]>0 then r[P1]-=P3, goto P2
**
** Register P1 must contain an integer.
-** If the value of register P1 is 1 or greater, subtract P3 from the
-** value in P1 and jump to P2.
+** If the value of register P1 is 1 or greater, subtract P3 from the
+** value in P1 and jump to P2.
**
** If the initial value of register P1 is less than 1, then the
** value is unchanged and control passes through to the next instruction.
@@ -93748,68 +93748,68 @@ case OP_IfPos: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken( pIn1->u.i>0, 2);
- if( pIn1->u.i>0 ){
- pIn1->u.i -= pOp->p3;
- goto jump_to_p2;
- }
+ if( pIn1->u.i>0 ){
+ pIn1->u.i -= pOp->p3;
+ goto jump_to_p2;
+ }
break;
}
-/* Opcode: OffsetLimit P1 P2 P3 * *
-** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)
-**
-** This opcode performs a commonly used computation associated with
-** LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3]
-** holds the offset counter. The opcode computes the combined value
-** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2]
-** value computed is the total number of rows that will need to be
-** visited in order to complete the query.
-**
-** If r[P3] is zero or negative, that means there is no OFFSET
-** and r[P2] is set to be the value of the LIMIT, r[P1].
-**
-** if r[P1] is zero or negative, that means there is no LIMIT
+/* Opcode: OffsetLimit P1 P2 P3 * *
+** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)
+**
+** This opcode performs a commonly used computation associated with
+** LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3]
+** holds the offset counter. The opcode computes the combined value
+** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2]
+** value computed is the total number of rows that will need to be
+** visited in order to complete the query.
+**
+** If r[P3] is zero or negative, that means there is no OFFSET
+** and r[P2] is set to be the value of the LIMIT, r[P1].
+**
+** if r[P1] is zero or negative, that means there is no LIMIT
** and r[P2] is set to -1.
-**
-** Otherwise, r[P2] is set to the sum of r[P1] and r[P3].
+**
+** Otherwise, r[P2] is set to the sum of r[P1] and r[P3].
*/
-case OP_OffsetLimit: { /* in1, out2, in3 */
- i64 x;
+case OP_OffsetLimit: { /* in1, out2, in3 */
+ i64 x;
pIn1 = &aMem[pOp->p1];
- pIn3 = &aMem[pOp->p3];
- pOut = out2Prerelease(p, pOp);
- assert( pIn1->flags & MEM_Int );
- assert( pIn3->flags & MEM_Int );
- x = pIn1->u.i;
- if( x<=0 || sqlite3AddInt64(&x, pIn3->u.i>0?pIn3->u.i:0) ){
- /* If the LIMIT is less than or equal to zero, loop forever. This
- ** is documented. But also, if the LIMIT+OFFSET exceeds 2^63 then
- ** also loop forever. This is undocumented. In fact, one could argue
- ** that the loop should terminate. But assuming 1 billion iterations
- ** per second (far exceeding the capabilities of any current hardware)
- ** it would take nearly 300 years to actually reach the limit. So
- ** looping forever is a reasonable approximation. */
- pOut->u.i = -1;
- }else{
- pOut->u.i = x;
- }
+ pIn3 = &aMem[pOp->p3];
+ pOut = out2Prerelease(p, pOp);
+ assert( pIn1->flags & MEM_Int );
+ assert( pIn3->flags & MEM_Int );
+ x = pIn1->u.i;
+ if( x<=0 || sqlite3AddInt64(&x, pIn3->u.i>0?pIn3->u.i:0) ){
+ /* If the LIMIT is less than or equal to zero, loop forever. This
+ ** is documented. But also, if the LIMIT+OFFSET exceeds 2^63 then
+ ** also loop forever. This is undocumented. In fact, one could argue
+ ** that the loop should terminate. But assuming 1 billion iterations
+ ** per second (far exceeding the capabilities of any current hardware)
+ ** it would take nearly 300 years to actually reach the limit. So
+ ** looping forever is a reasonable approximation. */
+ pOut->u.i = -1;
+ }else{
+ pOut->u.i = x;
+ }
break;
}
-/* Opcode: IfNotZero P1 P2 * * *
-** Synopsis: if r[P1]!=0 then r[P1]--, goto P2
+/* Opcode: IfNotZero P1 P2 * * *
+** Synopsis: if r[P1]!=0 then r[P1]--, goto P2
**
** Register P1 must contain an integer. If the content of register P1 is
-** initially greater than zero, then decrement the value in register P1.
+** initially greater than zero, then decrement the value in register P1.
** If it is non-zero (negative or positive) and then also jump to P2.
-** If register P1 is initially zero, leave it unchanged and fall through.
+** If register P1 is initially zero, leave it unchanged and fall through.
*/
case OP_IfNotZero: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken(pIn1->u.i<0, 2);
if( pIn1->u.i ){
- if( pIn1->u.i>0 ) pIn1->u.i--;
+ if( pIn1->u.i>0 ) pIn1->u.i--;
goto jump_to_p2;
}
break;
@@ -93818,13 +93818,13 @@ case OP_IfNotZero: { /* jump, in1 */
/* Opcode: DecrJumpZero P1 P2 * * *
** Synopsis: if (--r[P1])==0 goto P2
**
-** Register P1 must hold an integer. Decrement the value in P1
-** and jump to P2 if the new value is exactly zero.
+** Register P1 must hold an integer. Decrement the value in P1
+** and jump to P2 if the new value is exactly zero.
*/
case OP_DecrJumpZero: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
- if( pIn1->u.i>SMALLEST_INT64 ) pIn1->u.i--;
+ if( pIn1->u.i>SMALLEST_INT64 ) pIn1->u.i--;
VdbeBranchTaken(pIn1->u.i==0, 2);
if( pIn1->u.i==0 ) goto jump_to_p2;
break;
@@ -93877,8 +93877,8 @@ case OP_AggStep: {
assert( pOp->p4type==P4_FUNCDEF );
n = pOp->p5;
- assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
- assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+ assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) +
(sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*)));
@@ -93947,7 +93947,7 @@ case OP_AggStep1: {
(pCtx->pFunc->xInverse)(pCtx,pCtx->argc,pCtx->argv);
}else
#endif
- (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
+ (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
if( pCtx->isError ){
if( pCtx->isError>0 ){
@@ -93963,7 +93963,7 @@ case OP_AggStep1: {
sqlite3VdbeMemRelease(pCtx->pOut);
pCtx->pOut->flags = MEM_Null;
pCtx->isError = 0;
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
}
assert( pCtx->pOut->flags==MEM_Null );
assert( pCtx->skipFlag==0 );
@@ -93999,7 +93999,7 @@ case OP_AggStep1: {
case OP_AggValue:
case OP_AggFinal: {
Mem *pMem;
- assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
assert( pOp->p3==0 || pOp->opcode==OP_AggValue );
pMem = &aMem[pOp->p1];
assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
@@ -94016,7 +94016,7 @@ case OP_AggFinal: {
if( rc ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
- goto abort_due_to_error;
+ goto abort_due_to_error;
}
sqlite3VdbeChangeEncoding(pMem, encoding);
UPDATE_MAX_BLOBSIZE(pMem);
@@ -94052,8 +94052,8 @@ case OP_Checkpoint: {
|| pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
);
rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
- if( rc ){
- if( rc!=SQLITE_BUSY ) goto abort_due_to_error;
+ if( rc ){
+ if( rc!=SQLITE_BUSY ) goto abort_due_to_error;
rc = SQLITE_OK;
aRes[0] = 1;
}
@@ -94127,7 +94127,7 @@ case OP_JournalMode: { /* out2 */
"cannot change %s wal mode from within a transaction",
(eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
);
- goto abort_due_to_error;
+ goto abort_due_to_error;
}else{
if( eOld==PAGER_JOURNALMODE_WAL ){
@@ -94136,7 +94136,7 @@ case OP_JournalMode: { /* out2 */
** file. An EXCLUSIVE lock may still be held on the database file
** after a successful return.
*/
- rc = sqlite3PagerCloseWal(pPager, db);
+ rc = sqlite3PagerCloseWal(pPager, db);
if( rc==SQLITE_OK ){
sqlite3PagerSetJournalMode(pPager, eNew);
}
@@ -94157,7 +94157,7 @@ case OP_JournalMode: { /* out2 */
}
#endif /* ifndef SQLITE_OMIT_WAL */
- if( rc ) eNew = eOld;
+ if( rc ) eNew = eOld;
eNew = sqlite3PagerSetJournalMode(pPager, eNew);
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
@@ -94165,7 +94165,7 @@ case OP_JournalMode: { /* out2 */
pOut->n = sqlite3Strlen30(pOut->z);
pOut->enc = SQLITE_UTF8;
sqlite3VdbeChangeEncoding(pOut, encoding);
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
};
#endif /* SQLITE_OMIT_PRAGMA */
@@ -94173,8 +94173,8 @@ case OP_JournalMode: { /* out2 */
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/* Opcode: Vacuum P1 P2 * * *
**
-** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more
-** for an attached database. The "temp" database may not be vacuumed.
+** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more
+** for an attached database. The "temp" database may not be vacuumed.
**
** If P2 is not zero, then it is a register holding a string which is
** the file into which the result of vacuum should be written. When
@@ -94184,7 +94184,7 @@ case OP_Vacuum: {
assert( p->readOnly==0 );
rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1,
pOp->p2 ? &aMem[pOp->p2] : 0);
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
}
#endif
@@ -94205,8 +94205,8 @@ case OP_IncrVacuum: { /* jump */
pBt = db->aDb[pOp->p1].pBt;
rc = sqlite3BtreeIncrVacuum(pBt);
VdbeBranchTaken(rc==SQLITE_DONE,2);
- if( rc ){
- if( rc!=SQLITE_DONE ) goto abort_due_to_error;
+ if( rc ){
+ if( rc!=SQLITE_DONE ) goto abort_due_to_error;
rc = SQLITE_OK;
goto jump_to_p2;
}
@@ -94288,18 +94288,18 @@ case OP_CursorUnlock: {
*/
case OP_TableLock: {
u8 isWriteLock = (u8)pOp->p3;
- if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommit) ){
+ if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommit) ){
int p1 = pOp->p1;
assert( p1>=0 && p1<db->nDb );
assert( DbMaskTest(p->btreeMask, p1) );
assert( isWriteLock==0 || isWriteLock==1 );
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
- if( rc ){
- if( (rc&0xFF)==SQLITE_LOCKED ){
- const char *z = pOp->p4.z;
- sqlite3VdbeError(p, "database table is locked: %s", z);
- }
- goto abort_due_to_error;
+ if( rc ){
+ if( (rc&0xFF)==SQLITE_LOCKED ){
+ const char *z = pOp->p4.z;
+ sqlite3VdbeError(p, "database table is locked: %s", z);
+ }
+ goto abort_due_to_error;
}
}
break;
@@ -94321,7 +94321,7 @@ case OP_VBegin: {
pVTab = pOp->p4.pVtab;
rc = sqlite3VtabBegin(db, pVTab);
if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -94350,7 +94350,7 @@ case OP_VCreate: {
rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg);
}
sqlite3VdbeMemRelease(&sMem);
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -94366,7 +94366,7 @@ case OP_VDestroy: {
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
db->nVDestroy--;
assert( p->errorAction==OE_Abort && p->usesStmtJournal );
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -94380,35 +94380,35 @@ case OP_VDestroy: {
*/
case OP_VOpen: {
VdbeCursor *pCur;
- sqlite3_vtab_cursor *pVCur;
+ sqlite3_vtab_cursor *pVCur;
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
assert( p->bIsReader );
pCur = 0;
- pVCur = 0;
+ pVCur = 0;
pVtab = pOp->p4.pVtab->pVtab;
if( pVtab==0 || NEVER(pVtab->pModule==0) ){
rc = SQLITE_LOCKED;
- goto abort_due_to_error;
+ goto abort_due_to_error;
}
pModule = pVtab->pModule;
- rc = pModule->xOpen(pVtab, &pVCur);
+ rc = pModule->xOpen(pVtab, &pVCur);
sqlite3VtabImportErrmsg(p, pVtab);
- if( rc ) goto abort_due_to_error;
-
- /* Initialize sqlite3_vtab_cursor base class */
- pVCur->pVtab = pVtab;
-
- /* Initialize vdbe cursor object */
- pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
- if( pCur ){
- pCur->uc.pVCur = pVCur;
- pVtab->nRef++;
- }else{
- assert( db->mallocFailed );
- pModule->xClose(pVCur);
- goto no_mem;
+ if( rc ) goto abort_due_to_error;
+
+ /* Initialize sqlite3_vtab_cursor base class */
+ pVCur->pVtab = pVtab;
+
+ /* Initialize vdbe cursor object */
+ pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
+ if( pCur ){
+ pCur->uc.pVCur = pVCur;
+ pVtab->nRef++;
+ }else{
+ assert( db->mallocFailed );
+ pModule->xClose(pVCur);
+ goto no_mem;
}
break;
}
@@ -94440,7 +94440,7 @@ case OP_VFilter: { /* jump */
const sqlite3_module *pModule;
Mem *pQuery;
Mem *pArgc;
- sqlite3_vtab_cursor *pVCur;
+ sqlite3_vtab_cursor *pVCur;
sqlite3_vtab *pVtab;
VdbeCursor *pCur;
int res;
@@ -94453,9 +94453,9 @@ case OP_VFilter: { /* jump */
assert( memIsValid(pQuery) );
REGISTER_TRACE(pOp->p3, pQuery);
assert( pCur!=0 );
- assert( pCur->eCurType==CURTYPE_VTAB );
- pVCur = pCur->uc.pVCur;
- pVtab = pVCur->pVtab;
+ assert( pCur->eCurType==CURTYPE_VTAB );
+ pVCur = pCur->uc.pVCur;
+ pVtab = pVCur->pVtab;
pModule = pVtab->pModule;
/* Grab the index number and argc parameters */
@@ -94468,10 +94468,10 @@ case OP_VFilter: { /* jump */
for(i = 0; i<nArg; i++){
apArg[i] = &pArgc[i+1];
}
- rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
+ rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
sqlite3VtabImportErrmsg(p, pVtab);
- if( rc ) goto abort_due_to_error;
- res = pModule->xEof(pVCur);
+ if( rc ) goto abort_due_to_error;
+ res = pModule->xEof(pVCur);
pCur->nullRow = 0;
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
@@ -94480,14 +94480,14 @@ case OP_VFilter: { /* jump */
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VColumn P1 P2 P3 * P5
+/* Opcode: VColumn P1 P2 P3 * P5
** Synopsis: r[P3]=vcolumn(P2)
**
-** Store in register P3 the value of the P2-th column of
-** the current row of the virtual-table of cursor P1.
-**
-** If the VColumn opcode is being used to fetch the value of
-** an unchanging column during an UPDATE operation, then the P5
+** Store in register P3 the value of the P2-th column of
+** the current row of the virtual-table of cursor P1.
+**
+** If the VColumn opcode is being used to fetch the value of
+** an unchanging column during an UPDATE operation, then the P5
** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange()
** function to return true inside the xColumn method of the virtual
** table implementation. The P5 column might also contain other
@@ -94502,28 +94502,28 @@ case OP_VColumn: {
VdbeCursor *pCur = p->apCsr[pOp->p1];
assert( pCur!=0 );
- assert( pCur->eCurType==CURTYPE_VTAB );
- assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+ assert( pCur->eCurType==CURTYPE_VTAB );
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
pDest = &aMem[pOp->p3];
memAboutToChange(p, pDest);
if( pCur->nullRow ){
sqlite3VdbeMemSetNull(pDest);
break;
}
- pVtab = pCur->uc.pVCur->pVtab;
+ pVtab = pCur->uc.pVCur->pVtab;
pModule = pVtab->pModule;
assert( pModule->xColumn );
memset(&sContext, 0, sizeof(sContext));
sContext.pOut = pDest;
assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
if( pOp->p5 & OPFLAG_NOCHNG ){
- sqlite3VdbeMemSetNull(pDest);
- pDest->flags = MEM_Null|MEM_Zero;
- pDest->u.nZero = 0;
- }else{
- MemSetTypeFlag(pDest, MEM_Null);
- }
- rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2);
+ sqlite3VdbeMemSetNull(pDest);
+ pDest->flags = MEM_Null|MEM_Zero;
+ pDest->u.nZero = 0;
+ }else{
+ MemSetTypeFlag(pDest, MEM_Null);
+ }
+ rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2);
sqlite3VtabImportErrmsg(p, pVtab);
if( sContext.isError>0 ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(pDest));
@@ -94536,7 +94536,7 @@ case OP_VColumn: {
if( sqlite3VdbeMemTooBig(pDest) ){
goto too_big;
}
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -94556,11 +94556,11 @@ case OP_VNext: { /* jump */
pCur = p->apCsr[pOp->p1];
assert( pCur!=0 );
- assert( pCur->eCurType==CURTYPE_VTAB );
+ assert( pCur->eCurType==CURTYPE_VTAB );
if( pCur->nullRow ){
break;
}
- pVtab = pCur->uc.pVCur->pVtab;
+ pVtab = pCur->uc.pVCur->pVtab;
pModule = pVtab->pModule;
assert( pModule->xNext );
@@ -94570,10 +94570,10 @@ case OP_VNext: { /* jump */
** data is available) and the error code returned when xColumn or
** some other method is next invoked on the save virtual table cursor.
*/
- rc = pModule->xNext(pCur->uc.pVCur);
+ rc = pModule->xNext(pCur->uc.pVCur);
sqlite3VtabImportErrmsg(p, pVtab);
- if( rc ) goto abort_due_to_error;
- res = pModule->xEof(pCur->uc.pVCur);
+ if( rc ) goto abort_due_to_error;
+ res = pModule->xEof(pCur->uc.pVCur);
VdbeBranchTaken(!res,2);
if( !res ){
/* If there is data, jump to P2 */
@@ -94608,12 +94608,12 @@ case OP_VRename: {
testcase( pName->enc==SQLITE_UTF16BE );
testcase( pName->enc==SQLITE_UTF16LE );
rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
- if( rc ) goto abort_due_to_error;
- rc = pVtab->pModule->xRename(pVtab, pName->z);
+ if( rc ) goto abort_due_to_error;
+ rc = pVtab->pModule->xRename(pVtab, pName->z);
if( isLegacy==0 ) db->flags &= ~(u64)SQLITE_LegacyAlter;
- sqlite3VtabImportErrmsg(p, pVtab);
- p->expired = 0;
- if( rc ) goto abort_due_to_error;
+ sqlite3VtabImportErrmsg(p, pVtab);
+ p->expired = 0;
+ if( rc ) goto abort_due_to_error;
break;
}
#endif
@@ -94664,7 +94664,7 @@ case OP_VUpdate: {
pVtab = pOp->p4.pVtab->pVtab;
if( pVtab==0 || NEVER(pVtab->pModule==0) ){
rc = SQLITE_LOCKED;
- goto abort_due_to_error;
+ goto abort_due_to_error;
}
pModule = pVtab->pModule;
nArg = pOp->p2;
@@ -94685,7 +94685,7 @@ case OP_VUpdate: {
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK && pOp->p1 ){
assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
- db->lastRowid = rowid;
+ db->lastRowid = rowid;
}
if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
if( pOp->p5==OE_Ignore ){
@@ -94696,7 +94696,7 @@ case OP_VUpdate: {
}else{
p->nChange++;
}
- if( rc ) goto abort_due_to_error;
+ if( rc ) goto abort_due_to_error;
}
break;
}
@@ -94742,40 +94742,40 @@ case OP_MaxPgcnt: { /* out2 */
/* Opcode: Function P1 P2 P3 P4 *
** Synopsis: r[P3]=func(r[P2@NP])
-**
+**
** Invoke a user function (P4 is a pointer to an sqlite3_context object that
** contains a pointer to the function to be run) with arguments taken
** from register P2 and successors. The number of arguments is in
** the sqlite3_context object that P4 points to.
** 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
-** argument was constant then bit 0 of P1 is set. This is used to determine
-** whether meta data associated with a user function argument using the
-** sqlite3_set_auxdata() API may be safely retained until the next
-** invocation of this opcode.
-**
+** function was determined to be constant at compile time. If the first
+** argument was constant then bit 0 of P1 is set. This is used to determine
+** whether meta data associated with a user function argument using the
+** sqlite3_set_auxdata() API may be safely retained until the next
+** invocation of this opcode.
+**
** See also: AggStep, AggFinal, PureFunc
-*/
+*/
/* Opcode: PureFunc P1 P2 P3 P4 *
** Synopsis: r[P3]=func(r[P2@NP])
-**
-** Invoke a user function (P4 is a pointer to an sqlite3_context object that
+**
+** Invoke a user function (P4 is a pointer to an sqlite3_context object that
** contains a pointer to the function to be run) with arguments taken
** from register P2 and successors. The number of arguments is in
** the sqlite3_context object that P4 points to.
** The result of the function is stored
-** in register P3. Register P3 must not be one of the function inputs.
-**
+** 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
-** argument was constant then bit 0 of P1 is set. This is used to determine
-** whether meta data associated with a user function argument using the
-** sqlite3_set_auxdata() API may be safely retained until the next
-** invocation of this opcode.
-**
+** function was determined to be constant at compile time. If the first
+** argument was constant then bit 0 of P1 is set. This is used to determine
+** whether meta data associated with a user function argument using the
+** sqlite3_set_auxdata() API may be safely retained until the next
+** invocation of this opcode.
+**
** This opcode works exactly like OP_Function. The only difference is in
** its name. This opcode is used in places where the function must be
** purely non-deterministic. Some built-in date/time functions can be
@@ -94783,72 +94783,72 @@ case OP_MaxPgcnt: { /* out2 */
** When those function are used in a non-deterministic way, they will check
** to see if they were called using OP_PureFunc instead of OP_Function, and
** if they were, they throw an error.
-**
+**
** See also: AggStep, AggFinal, Function
-*/
+*/
case OP_PureFunc: /* group */
case OP_Function: { /* group */
- int i;
- sqlite3_context *pCtx;
-
- assert( pOp->p4type==P4_FUNCCTX );
- pCtx = pOp->p4.pCtx;
-
- /* If this function is inside of a trigger, the register array in aMem[]
- ** might change from one evaluation to the next. The next block of code
- ** checks to see if the register array has changed, and if so it
- ** reinitializes the relavant parts of the sqlite3_context object */
- pOut = &aMem[pOp->p3];
- if( pCtx->pOut != pOut ){
+ int i;
+ sqlite3_context *pCtx;
+
+ assert( pOp->p4type==P4_FUNCCTX );
+ pCtx = pOp->p4.pCtx;
+
+ /* If this function is inside of a trigger, the register array in aMem[]
+ ** might change from one evaluation to the next. The next block of code
+ ** checks to see if the register array has changed, and if so it
+ ** reinitializes the relavant parts of the sqlite3_context object */
+ pOut = &aMem[pOp->p3];
+ if( pCtx->pOut != pOut ){
pCtx->pVdbe = p;
- pCtx->pOut = pOut;
- for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
- }
+ pCtx->pOut = pOut;
+ for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
+ }
assert( pCtx->pVdbe==p );
-
- memAboutToChange(p, pOut);
-#ifdef SQLITE_DEBUG
- for(i=0; i<pCtx->argc; i++){
- assert( memIsValid(pCtx->argv[i]) );
- REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
- }
-#endif
- MemSetTypeFlag(pOut, MEM_Null);
+
+ memAboutToChange(p, pOut);
+#ifdef SQLITE_DEBUG
+ for(i=0; i<pCtx->argc; i++){
+ assert( memIsValid(pCtx->argv[i]) );
+ REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
+ }
+#endif
+ MemSetTypeFlag(pOut, MEM_Null);
assert( pCtx->isError==0 );
- (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
-
- /* If the function returned an error, throw an exception */
+ (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
+
+ /* If the function returned an error, throw an exception */
if( pCtx->isError ){
if( pCtx->isError>0 ){
- sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
- rc = pCtx->isError;
- }
- sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
+ rc = pCtx->isError;
+ }
+ sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
pCtx->isError = 0;
- if( rc ) goto abort_due_to_error;
- }
-
- /* Copy the result of the function into register P3 */
- if( pOut->flags & (MEM_Str|MEM_Blob) ){
- sqlite3VdbeChangeEncoding(pOut, encoding);
- if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
- }
-
- REGISTER_TRACE(pOp->p3, pOut);
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Trace P1 P2 * P4 *
-**
-** Write P4 on the statement trace output if statement tracing is
-** enabled.
-**
-** Operand P1 must be 0x7fffffff and P2 must positive.
-*/
-/* Opcode: Init P1 P2 P3 P4 *
-** Synopsis: Start at P2
-**
+ if( rc ) goto abort_due_to_error;
+ }
+
+ /* Copy the result of the function into register P3 */
+ if( pOut->flags & (MEM_Str|MEM_Blob) ){
+ sqlite3VdbeChangeEncoding(pOut, encoding);
+ if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
+ }
+
+ REGISTER_TRACE(pOp->p3, pOut);
+ UPDATE_MAX_BLOBSIZE(pOut);
+ break;
+}
+
+/* Opcode: Trace P1 P2 * P4 *
+**
+** Write P4 on the statement trace output if statement tracing is
+** enabled.
+**
+** Operand P1 must be 0x7fffffff and P2 must positive.
+*/
+/* Opcode: Init P1 P2 P3 P4 *
+** Synopsis: Start at P2
+**
** Programs contain a single instance of this opcode as the very first
** opcode.
**
@@ -94857,61 +94857,61 @@ case OP_Function: { /* group */
** Or if P4 is blank, use the string returned by sqlite3_sql().
**
** If P2 is not zero, jump to instruction P2.
-**
-** Increment the value of P1 so that OP_Once opcodes will jump the
-** first time they are evaluated for this run.
-**
-** If P3 is not zero, then it is an address to jump to if an SQLITE_CORRUPT
-** error is encountered.
-*/
-case OP_Trace:
+**
+** Increment the value of P1 so that OP_Once opcodes will jump the
+** first time they are evaluated for this run.
+**
+** If P3 is not zero, then it is an address to jump to if an SQLITE_CORRUPT
+** error is encountered.
+*/
+case OP_Trace:
case OP_Init: { /* jump */
int i;
#ifndef SQLITE_OMIT_TRACE
char *zTrace;
#endif
- /* If the P4 argument is not NULL, then it must be an SQL comment string.
- ** The "--" string is broken up to prevent false-positives with srcck1.c.
- **
- ** This assert() provides evidence for:
- ** EVIDENCE-OF: R-50676-09860 The callback can compute the same text that
- ** would have been returned by the legacy sqlite3_trace() interface by
- ** using the X argument when X begins with "--" and invoking
- ** sqlite3_expanded_sql(P) otherwise.
- */
- assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 );
-
- /* OP_Init is always instruction 0 */
- assert( pOp==p->aOp || pOp->opcode==OP_Trace );
-
+ /* If the P4 argument is not NULL, then it must be an SQL comment string.
+ ** The "--" string is broken up to prevent false-positives with srcck1.c.
+ **
+ ** This assert() provides evidence for:
+ ** EVIDENCE-OF: R-50676-09860 The callback can compute the same text that
+ ** would have been returned by the legacy sqlite3_trace() interface by
+ ** using the X argument when X begins with "--" and invoking
+ ** sqlite3_expanded_sql(P) otherwise.
+ */
+ assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 );
+
+ /* OP_Init is always instruction 0 */
+ assert( pOp==p->aOp || pOp->opcode==OP_Trace );
+
#ifndef SQLITE_OMIT_TRACE
- if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
+ if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
&& !p->doingRerun
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
-#ifndef SQLITE_OMIT_DEPRECATED
- if( db->mTrace & SQLITE_TRACE_LEGACY ){
- char *z = sqlite3VdbeExpandSql(p, zTrace);
+#ifndef SQLITE_OMIT_DEPRECATED
+ if( db->mTrace & SQLITE_TRACE_LEGACY ){
+ char *z = sqlite3VdbeExpandSql(p, zTrace);
db->trace.xLegacy(db->pTraceArg, z);
- sqlite3_free(z);
- }else
-#endif
- if( db->nVdbeExec>1 ){
- char *z = sqlite3MPrintf(db, "-- %s", zTrace);
+ sqlite3_free(z);
+ }else
+#endif
+ if( db->nVdbeExec>1 ){
+ char *z = sqlite3MPrintf(db, "-- %s", zTrace);
(void)db->trace.xV2(SQLITE_TRACE_STMT, db->pTraceArg, p, z);
- sqlite3DbFree(db, z);
- }else{
+ sqlite3DbFree(db, z);
+ }else{
(void)db->trace.xV2(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace);
- }
+ }
}
#ifdef SQLITE_USE_FCNTL_TRACE
zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
if( zTrace ){
- int j;
- for(j=0; j<db->nDb; j++){
- if( DbMaskTest(p->btreeMask, j)==0 ) continue;
- sqlite3_file_control(db, db->aDb[j].zDbSName, SQLITE_FCNTL_TRACE, zTrace);
+ int j;
+ for(j=0; j<db->nDb; j++){
+ if( DbMaskTest(p->btreeMask, j)==0 ) continue;
+ sqlite3_file_control(db, db->aDb[j].zDbSName, SQLITE_FCNTL_TRACE, zTrace);
}
}
#endif /* SQLITE_USE_FCNTL_TRACE */
@@ -94923,41 +94923,41 @@ case OP_Init: { /* jump */
}
#endif /* SQLITE_DEBUG */
#endif /* SQLITE_OMIT_TRACE */
- assert( pOp->p2>0 );
- if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){
- if( pOp->opcode==OP_Trace ) break;
- for(i=1; i<p->nOp; i++){
- if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0;
- }
- pOp->p1 = 0;
- }
- pOp->p1++;
- p->aCounter[SQLITE_STMTSTATUS_RUN]++;
- goto jump_to_p2;
-}
-
-#ifdef SQLITE_ENABLE_CURSOR_HINTS
-/* Opcode: CursorHint P1 * * P4 *
-**
-** Provide a hint to cursor P1 that it only needs to return rows that
-** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer
-** to values currently held in registers. TK_COLUMN terms in the P4
-** expression refer to columns in the b-tree to which cursor P1 is pointing.
-*/
-case OP_CursorHint: {
- VdbeCursor *pC;
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- assert( pOp->p4type==P4_EXPR );
- pC = p->apCsr[pOp->p1];
- if( pC ){
- assert( pC->eCurType==CURTYPE_BTREE );
- sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE,
- pOp->p4.pExpr, aMem);
- }
+ assert( pOp->p2>0 );
+ if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){
+ if( pOp->opcode==OP_Trace ) break;
+ for(i=1; i<p->nOp; i++){
+ if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0;
+ }
+ pOp->p1 = 0;
+ }
+ pOp->p1++;
+ p->aCounter[SQLITE_STMTSTATUS_RUN]++;
+ goto jump_to_p2;
+}
+
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+/* Opcode: CursorHint P1 * * P4 *
+**
+** Provide a hint to cursor P1 that it only needs to return rows that
+** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer
+** to values currently held in registers. TK_COLUMN terms in the P4
+** expression refer to columns in the b-tree to which cursor P1 is pointing.
+*/
+case OP_CursorHint: {
+ VdbeCursor *pC;
+
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ assert( pOp->p4type==P4_EXPR );
+ pC = p->apCsr[pOp->p1];
+ if( pC ){
+ assert( pC->eCurType==CURTYPE_BTREE );
+ sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE,
+ pOp->p4.pExpr, aMem);
+ }
break;
}
-#endif /* SQLITE_ENABLE_CURSOR_HINTS */
+#endif /* SQLITE_ENABLE_CURSOR_HINTS */
#ifdef SQLITE_DEBUG
/* Opcode: Abortable * * * * *
@@ -95067,12 +95067,12 @@ default: { /* This is really OP_Noop, OP_Explain */
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
- u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode];
+ u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode];
if( rc!=0 ) printf("rc=%d\n",rc);
- if( opProperty & (OPFLG_OUT2) ){
+ if( opProperty & (OPFLG_OUT2) ){
registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
}
- if( opProperty & OPFLG_OUT3 ){
+ if( opProperty & OPFLG_OUT3 ){
registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
}
if( opProperty==0xff ){
@@ -95089,7 +95089,7 @@ default: { /* This is really OP_Noop, OP_Explain */
/* If we reach this point, it means that execution is finished with
** an error of some kind.
*/
-abort_due_to_error:
+abort_due_to_error:
if( db->mallocFailed ){
rc = SQLITE_NOMEM_BKPT;
}else if( rc==SQLITE_IOERR_CORRUPTFS ){
@@ -95108,16 +95108,16 @@ abort_due_to_error:
printf("ABORT-due-to-error (rc=%d): %s\n", rc, zTrace);
}
#endif
- if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
- sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
- }
+ if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
+ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
+ }
p->rc = rc;
- sqlite3SystemError(db, rc);
+ sqlite3SystemError(db, rc);
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
(int)(pOp - aOp), p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p);
- if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
+ if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
db->flags |= SQLITE_CorruptRdOnly;
}
@@ -95144,7 +95144,7 @@ vdbe_return:
sqlite3VdbeLeave(p);
assert( rc!=SQLITE_OK || nExtraDelete==0
|| sqlite3_strlike("DELETE%",p->zSql,0)!=0
- );
+ );
return rc;
/* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
@@ -95153,15 +95153,15 @@ vdbe_return:
too_big:
sqlite3VdbeError(p, "string or blob too big");
rc = SQLITE_TOOBIG;
- goto abort_due_to_error;
+ goto abort_due_to_error;
/* Jump to here if a malloc() fails.
*/
no_mem:
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
sqlite3VdbeError(p, "out of memory");
- rc = SQLITE_NOMEM_BKPT;
- goto abort_due_to_error;
+ rc = SQLITE_NOMEM_BKPT;
+ goto abort_due_to_error;
/* Jump to here if the sqlite3_interrupt() API sets the interrupt
** flag.
@@ -95169,7 +95169,7 @@ no_mem:
abort_due_to_interrupt:
assert( AtomicLoad(&db->u1.isInterrupted) );
rc = SQLITE_INTERRUPT;
- goto abort_due_to_error;
+ goto abort_due_to_error;
}
@@ -95202,12 +95202,12 @@ typedef struct Incrblob Incrblob;
struct Incrblob {
int nByte; /* Size of open blob, in bytes */
int iOffset; /* Byte offset of blob in cursor data */
- u16 iCol; /* Table column this handle is open on */
+ u16 iCol; /* Table column this handle is open on */
BtCursor *pCsr; /* Cursor pointing at blob row */
sqlite3_stmt *pStmt; /* Statement holding cursor open */
sqlite3 *db; /* The associated database */
- char *zDb; /* Database name */
- Table *pTab; /* Table object */
+ char *zDb; /* Database name */
+ Table *pTab; /* Table object */
};
@@ -95234,30 +95234,30 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
Vdbe *v = (Vdbe *)p->pStmt;
/* Set the value of register r[1] in the SQL statement to integer iRow.
- ** This is done directly as a performance optimization
- */
- v->aMem[1].flags = MEM_Int;
- v->aMem[1].u.i = iRow;
-
- /* If the statement has been run before (and is paused at the OP_ResultRow)
- ** then back it up to the point where it does the OP_NotExists. This could
- ** have been down with an extra OP_Goto, but simply setting the program
- ** counter is faster. */
- if( v->pc>4 ){
- v->pc = 4;
- assert( v->aOp[v->pc].opcode==OP_NotExists );
- rc = sqlite3VdbeExec(v);
- }else{
- rc = sqlite3_step(p->pStmt);
- }
+ ** This is done directly as a performance optimization
+ */
+ v->aMem[1].flags = MEM_Int;
+ v->aMem[1].u.i = iRow;
+
+ /* If the statement has been run before (and is paused at the OP_ResultRow)
+ ** then back it up to the point where it does the OP_NotExists. This could
+ ** have been down with an extra OP_Goto, but simply setting the program
+ ** counter is faster. */
+ if( v->pc>4 ){
+ v->pc = 4;
+ assert( v->aOp[v->pc].opcode==OP_NotExists );
+ rc = sqlite3VdbeExec(v);
+ }else{
+ rc = sqlite3_step(p->pStmt);
+ }
if( rc==SQLITE_ROW ){
VdbeCursor *pC = v->apCsr[0];
u32 type;
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
- testcase( pC->nHdrParsed==p->iCol );
- testcase( pC->nHdrParsed==p->iCol+1 );
+ testcase( pC->nHdrParsed==p->iCol );
+ testcase( pC->nHdrParsed==p->iCol+1 );
if( type<12 ){
zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
type==0?"null": type==7?"real": "integer"
@@ -95268,7 +95268,7 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
}else{
p->iOffset = pC->aType[p->iCol + pC->nField];
p->nByte = sqlite3VdbeSerialTypeLen(type);
- p->pCsr = pC->uc.pCursor;
+ p->pCsr = pC->uc.pCursor;
sqlite3BtreeIncrblobCursor(p->pCsr);
}
}
@@ -95296,13 +95296,13 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
/*
** Open a blob handle.
*/
-SQLITE_API int sqlite3_blob_open(
+SQLITE_API int sqlite3_blob_open(
sqlite3* db, /* The database connection */
const char *zDb, /* The attached database containing the blob */
const char *zTable, /* The table containing the blob */
const char *zColumn, /* The column containing the blob */
sqlite_int64 iRow, /* The row containing the glob */
- int wrFlag, /* True -> read/write access, false -> read-only */
+ int wrFlag, /* True -> read/write access, false -> read-only */
sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */
){
int nAttempt = 0;
@@ -95311,7 +95311,7 @@ SQLITE_API int sqlite3_blob_open(
char *zErr = 0;
Table *pTab;
Incrblob *pBlob = 0;
- Parse sParse;
+ Parse sParse;
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppBlob==0 ){
@@ -95324,46 +95324,46 @@ SQLITE_API int sqlite3_blob_open(
return SQLITE_MISUSE_BKPT;
}
#endif
- wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */
+ wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */
sqlite3_mutex_enter(db->mutex);
pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
do {
- memset(&sParse, 0, sizeof(Parse));
- if( !pBlob ) goto blob_open_out;
- sParse.db = db;
+ memset(&sParse, 0, sizeof(Parse));
+ if( !pBlob ) goto blob_open_out;
+ sParse.db = db;
sqlite3DbFree(db, zErr);
zErr = 0;
sqlite3BtreeEnterAll(db);
- pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb);
+ pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb);
if( pTab && IsVirtual(pTab) ){
pTab = 0;
- sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable);
+ sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable);
}
if( pTab && !HasRowid(pTab) ){
pTab = 0;
- sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable);
+ sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable);
}
#ifndef SQLITE_OMIT_VIEW
if( pTab && IsView(pTab) ){
pTab = 0;
- sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable);
+ sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable);
}
#endif
if( !pTab ){
- if( sParse.zErrMsg ){
+ if( sParse.zErrMsg ){
sqlite3DbFree(db, zErr);
- zErr = sParse.zErrMsg;
- sParse.zErrMsg = 0;
+ zErr = sParse.zErrMsg;
+ sParse.zErrMsg = 0;
}
rc = SQLITE_ERROR;
sqlite3BtreeLeaveAll(db);
goto blob_open_out;
}
- pBlob->pTab = pTab;
- pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName;
+ pBlob->pTab = pTab;
+ pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName;
/* Now search pTab for the exact column. */
for(iCol=0; iCol<pTab->nCol; iCol++) {
@@ -95381,8 +95381,8 @@ SQLITE_API int sqlite3_blob_open(
/* If the value is being opened for writing, check that the
** column is not indexed, and that it is not part of a foreign key.
- */
- if( wrFlag ){
+ */
+ if( wrFlag ){
const char *zFault = 0;
Index *pIdx;
#ifndef SQLITE_OMIT_FOREIGN_KEY
@@ -95406,8 +95406,8 @@ SQLITE_API int sqlite3_blob_open(
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int j;
for(j=0; j<pIdx->nKeyCol; j++){
- /* FIXME: Be smarter about indexes that use expressions */
- if( pIdx->aiColumn[j]==iCol || pIdx->aiColumn[j]==XN_EXPR ){
+ /* FIXME: Be smarter about indexes that use expressions */
+ if( pIdx->aiColumn[j]==iCol || pIdx->aiColumn[j]==XN_EXPR ){
zFault = "indexed";
}
}
@@ -95421,84 +95421,84 @@ SQLITE_API int sqlite3_blob_open(
}
}
- pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(&sParse);
+ pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(&sParse);
assert( pBlob->pStmt || db->mallocFailed );
if( pBlob->pStmt ){
/* This VDBE program seeks a btree cursor to the identified
- ** db/table/row entry. The reason for using a vdbe program instead
- ** of writing code to use the b-tree layer directly is that the
- ** vdbe program will take advantage of the various transaction,
- ** locking and error handling infrastructure built into the vdbe.
- **
- ** After seeking the cursor, the vdbe executes an OP_ResultRow.
- ** Code external to the Vdbe then "borrows" the b-tree cursor and
+ ** db/table/row entry. The reason for using a vdbe program instead
+ ** of writing code to use the b-tree layer directly is that the
+ ** vdbe program will take advantage of the various transaction,
+ ** locking and error handling infrastructure built into the vdbe.
+ **
+ ** After seeking the cursor, the vdbe executes an OP_ResultRow.
+ ** Code external to the Vdbe then "borrows" the b-tree cursor and
** uses it to implement the blob_read(), blob_write() and
- ** blob_bytes() functions.
- **
- ** The sqlite3_blob_close() function finalizes the vdbe program,
+ ** blob_bytes() functions.
+ **
+ ** The sqlite3_blob_close() function finalizes the vdbe program,
** which closes the b-tree cursor and (possibly) commits the
- ** transaction.
- */
- static const int iLn = VDBE_OFFSET_LINENO(2);
- static const VdbeOpList openBlob[] = {
- {OP_TableLock, 0, 0, 0}, /* 0: Acquire a read or write lock */
- {OP_OpenRead, 0, 0, 0}, /* 1: Open a cursor */
- /* blobSeekToRow() will initialize r[1] to the desired rowid */
- {OP_NotExists, 0, 5, 1}, /* 2: Seek the cursor to rowid=r[1] */
- {OP_Column, 0, 0, 1}, /* 3 */
- {OP_ResultRow, 1, 0, 0}, /* 4 */
- {OP_Halt, 0, 0, 0}, /* 5 */
- };
+ ** transaction.
+ */
+ static const int iLn = VDBE_OFFSET_LINENO(2);
+ static const VdbeOpList openBlob[] = {
+ {OP_TableLock, 0, 0, 0}, /* 0: Acquire a read or write lock */
+ {OP_OpenRead, 0, 0, 0}, /* 1: Open a cursor */
+ /* blobSeekToRow() will initialize r[1] to the desired rowid */
+ {OP_NotExists, 0, 5, 1}, /* 2: Seek the cursor to rowid=r[1] */
+ {OP_Column, 0, 0, 1}, /* 3 */
+ {OP_ResultRow, 1, 0, 0}, /* 4 */
+ {OP_Halt, 0, 0, 0}, /* 5 */
+ };
Vdbe *v = (Vdbe *)pBlob->pStmt;
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- VdbeOp *aOp;
+ VdbeOp *aOp;
sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag,
pTab->pSchema->schema_cookie,
pTab->pSchema->iGeneration);
- sqlite3VdbeChangeP5(v, 1);
- assert( sqlite3VdbeCurrentAddr(v)==2 || db->mallocFailed );
- aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn);
+ sqlite3VdbeChangeP5(v, 1);
+ assert( sqlite3VdbeCurrentAddr(v)==2 || db->mallocFailed );
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn);
/* Make sure a mutex is held on the table to be accessed */
sqlite3VdbeUsesBtree(v, iDb);
- if( db->mallocFailed==0 ){
- assert( aOp!=0 );
- /* Configure the OP_TableLock instruction */
+ if( db->mallocFailed==0 ){
+ assert( aOp!=0 );
+ /* Configure the OP_TableLock instruction */
#ifdef SQLITE_OMIT_SHARED_CACHE
- aOp[0].opcode = OP_Noop;
+ aOp[0].opcode = OP_Noop;
#else
- aOp[0].p1 = iDb;
- aOp[0].p2 = pTab->tnum;
- aOp[0].p3 = wrFlag;
- sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);
- }
- if( db->mallocFailed==0 ){
+ aOp[0].p1 = iDb;
+ aOp[0].p2 = pTab->tnum;
+ aOp[0].p3 = wrFlag;
+ sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);
+ }
+ if( db->mallocFailed==0 ){
#endif
/* Remove either the OP_OpenWrite or OpenRead. Set the P2
- ** parameter of the other to pTab->tnum. */
- if( wrFlag ) aOp[1].opcode = OP_OpenWrite;
- aOp[1].p2 = pTab->tnum;
+ ** parameter of the other to pTab->tnum. */
+ if( wrFlag ) aOp[1].opcode = OP_OpenWrite;
+ aOp[1].p2 = pTab->tnum;
aOp[1].p3 = iDb;
- /* Configure the number of columns. Configure the cursor to
- ** think that the table has one more column than it really
- ** does. An OP_Column to retrieve this imaginary column will
- ** always return an SQL NULL. This is useful because it means
+ /* Configure the number of columns. Configure the cursor to
+ ** think that the table has one more column than it really
+ ** does. An OP_Column to retrieve this imaginary column will
+ ** always return an SQL NULL. This is useful because it means
** we can invoke OP_Column to fill in the vdbe cursors type
- ** and offset cache without causing any IO.
- */
- aOp[1].p4type = P4_INT32;
- aOp[1].p4.i = pTab->nCol+1;
- aOp[3].p2 = pTab->nCol;
-
- sParse.nVar = 0;
- sParse.nMem = 1;
- sParse.nTab = 1;
- sqlite3VdbeMakeReady(v, &sParse);
+ ** and offset cache without causing any IO.
+ */
+ aOp[1].p4type = P4_INT32;
+ aOp[1].p4.i = pTab->nCol+1;
+ aOp[3].p2 = pTab->nCol;
+
+ sParse.nVar = 0;
+ sParse.nMem = 1;
+ sParse.nTab = 1;
+ sqlite3VdbeMakeReady(v, &sParse);
}
}
@@ -95520,7 +95520,7 @@ blob_open_out:
}
sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
- sqlite3ParserReset(&sParse);
+ sqlite3ParserReset(&sParse);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
@@ -95530,7 +95530,7 @@ blob_open_out:
** Close a blob handle that was previously created using
** sqlite3_blob_open().
*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){
+SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
int rc;
sqlite3 *db;
@@ -95582,32 +95582,32 @@ static int blobReadWrite(
*/
assert( db == v->db );
sqlite3BtreeEnterCursor(p->pCsr);
-
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
- if( xCall==sqlite3BtreePutData && db->xPreUpdateCallback ){
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ if( xCall==sqlite3BtreePutData && db->xPreUpdateCallback ){
/* If a pre-update hook is registered and this is a write cursor,
** invoke it here.
**
- ** TODO: The preupdate-hook is passed SQLITE_DELETE, even though this
- ** operation should really be an SQLITE_UPDATE. This is probably
+ ** TODO: The preupdate-hook is passed SQLITE_DELETE, even though this
+ ** operation should really be an SQLITE_UPDATE. This is probably
** incorrect, but is convenient because at this point the new.* values
** are not easily obtainable. And for the sessions module, an
** SQLITE_UPDATE where the PK columns do not change is handled in the
- ** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually
- ** slightly more efficient). Since you cannot write to a PK column
- ** using the incremental-blob API, this works. For the sessions module
- ** anyhow.
- */
- sqlite3_int64 iKey;
- iKey = sqlite3BtreeIntegerKey(p->pCsr);
+ ** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually
+ ** slightly more efficient). Since you cannot write to a PK column
+ ** using the incremental-blob API, this works. For the sessions module
+ ** anyhow.
+ */
+ sqlite3_int64 iKey;
+ iKey = sqlite3BtreeIntegerKey(p->pCsr);
assert( v->apCsr[0]!=0 );
assert( v->apCsr[0]->eCurType==CURTYPE_BTREE );
- sqlite3VdbePreUpdateHook(
+ sqlite3VdbePreUpdateHook(
v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol
- );
- }
-#endif
-
+ );
+ }
+#endif
+
rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
sqlite3BtreeLeaveCursor(p->pCsr);
if( rc==SQLITE_ABORT ){
@@ -95626,14 +95626,14 @@ static int blobReadWrite(
/*
** Read data from a blob handle.
*/
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
- return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreePayloadChecked);
+SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
+ return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreePayloadChecked);
}
/*
** Write data to a blob handle.
*/
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
+SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
}
@@ -95643,7 +95643,7 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int
** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
** so no mutex is required for access.
*/
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
+SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
return (p && p->pStmt) ? p->nByte : 0;
}
@@ -95658,7 +95658,7 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
** subsequent calls to sqlite3_blob_xxx() functions (except blob_close())
** immediately return SQLITE_ABORT.
*/
-SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
+SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
int rc;
Incrblob *p = (Incrblob *)pBlob;
sqlite3 *db;
@@ -96235,7 +96235,7 @@ static int vdbePmaReadBlob(
sqlite3_int64 nNew = MAX(128, 2*(sqlite3_int64)p->nAlloc);
while( nByte>nNew ) nNew = nNew*2;
aNew = sqlite3Realloc(p->aAlloc, nNew);
- if( !aNew ) return SQLITE_NOMEM_BKPT;
+ if( !aNew ) return SQLITE_NOMEM_BKPT;
p->nAlloc = nNew;
p->aAlloc = aNew;
}
@@ -96347,7 +96347,7 @@ static int vdbePmaReaderSeek(
int iBuf = pReadr->iReadOff % pgsz;
if( pReadr->aBuffer==0 ){
pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz);
- if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM_BKPT;
+ if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM_BKPT;
pReadr->nBuffer = pgsz;
}
if( rc==SQLITE_OK && iBuf ){
@@ -96432,7 +96432,7 @@ static int vdbePmaReaderInit(
rc = vdbePmaReaderSeek(pTask, pReadr, pFile, iStart);
if( rc==SQLITE_OK ){
- u64 nByte = 0; /* Size of PMA in bytes */
+ u64 nByte = 0; /* Size of PMA in bytes */
rc = vdbePmaReadVarint(pReadr, &nByte);
pReadr->iEof = pReadr->iReadOff + nByte;
*pnByte += nByte;
@@ -96512,13 +96512,13 @@ static int vdbeSorterCompareText(
getVarint32NR(&p1[1], n1);
getVarint32NR(&p2[1], n2);
- res = memcmp(v1, v2, (MIN(n1, n2) - 13)/2);
+ res = memcmp(v1, v2, (MIN(n1, n2) - 13)/2);
if( res==0 ){
res = n1 - n2;
}
if( res==0 ){
- if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
+ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
@@ -96554,41 +96554,41 @@ static int vdbeSorterCompareInt(
assert( (s1>0 && s1<7) || s1==8 || s1==9 );
assert( (s2>0 && s2<7) || s2==8 || s2==9 );
- if( s1==s2 ){
- /* The two values have the same sign. Compare using memcmp(). */
- static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8, 0, 0, 0 };
- const u8 n = aLen[s1];
- int i;
- res = 0;
- for(i=0; i<n; i++){
- if( (res = v1[i] - v2[i])!=0 ){
- if( ((v1[0] ^ v2[0]) & 0x80)!=0 ){
- res = v1[0] & 0x80 ? -1 : +1;
- }
- break;
- }
- }
- }else if( s1>7 && s2>7 ){
+ if( s1==s2 ){
+ /* The two values have the same sign. Compare using memcmp(). */
+ static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8, 0, 0, 0 };
+ const u8 n = aLen[s1];
+ int i;
+ res = 0;
+ for(i=0; i<n; i++){
+ if( (res = v1[i] - v2[i])!=0 ){
+ if( ((v1[0] ^ v2[0]) & 0x80)!=0 ){
+ res = v1[0] & 0x80 ? -1 : +1;
+ }
+ break;
+ }
+ }
+ }else if( s1>7 && s2>7 ){
res = s1 - s2;
}else{
- if( s2>7 ){
- res = +1;
- }else if( s1>7 ){
- res = -1;
+ if( s2>7 ){
+ res = +1;
+ }else if( s1>7 ){
+ res = -1;
}else{
- res = s1 - s2;
- }
- assert( res!=0 );
+ res = s1 - s2;
+ }
+ assert( res!=0 );
- if( res>0 ){
- if( *v1 & 0x80 ) res = -1;
- }else{
- if( *v2 & 0x80 ) res = +1;
+ if( res>0 ){
+ if( *v1 & 0x80 ) res = -1;
+ }else{
+ if( *v2 & 0x80 ) res = +1;
}
}
if( res==0 ){
- if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
+ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
@@ -96604,7 +96604,7 @@ static int vdbeSorterCompareInt(
/*
** Initialize the temporary index cursor just opened as a sorter cursor.
**
-** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField)
+** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField)
** to determine the number of fields that should be compared from the
** records being sorted. However, if the value passed as argument nField
** is non-zero and the sorter is able to guarantee a stable sort, nField
@@ -96655,28 +96655,28 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
}
#endif
- assert( pCsr->pKeyInfo && pCsr->pBtx==0 );
- assert( pCsr->eCurType==CURTYPE_SORTER );
- szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*);
+ assert( pCsr->pKeyInfo && pCsr->pBtx==0 );
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*);
sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
- pCsr->uc.pSorter = pSorter;
+ pCsr->uc.pSorter = pSorter;
if( pSorter==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}else{
Btree *pBt = db->aDb[0].pBt;
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
pKeyInfo->db = 0;
if( nField && nWorker==0 ){
- pKeyInfo->nKeyField = nField;
+ pKeyInfo->nKeyField = nField;
}
sqlite3BtreeEnter(pBt);
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt);
sqlite3BtreeLeave(pBt);
pSorter->nTask = nWorker + 1;
- pSorter->iPrev = (u8)(nWorker - 1);
+ pSorter->iPrev = (u8)(nWorker - 1);
pSorter->bUseThreads = (pSorter->nTask>1);
pSorter->db = db;
for(i=0; i<pSorter->nTask; i++){
@@ -96685,28 +96685,28 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
}
if( !sqlite3TempInMemory(db) ){
- i64 mxCache; /* Cache size in bytes*/
+ i64 mxCache; /* Cache size in bytes*/
u32 szPma = sqlite3GlobalConfig.szPma;
pSorter->mnPmaSize = szPma * pgsz;
-
+
mxCache = db->aDb[0].pSchema->cache_size;
- if( mxCache<0 ){
- /* A negative cache-size value C indicates that the cache is abs(C)
- ** KiB in size. */
- mxCache = mxCache * -1024;
- }else{
- mxCache = mxCache * pgsz;
- }
- mxCache = MIN(mxCache, SQLITE_MAX_PMASZ);
- pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache);
-
- /* Avoid large memory allocations if the application has requested
- ** SQLITE_CONFIG_SMALL_MALLOC. */
- if( sqlite3GlobalConfig.bSmallMalloc==0 ){
+ if( mxCache<0 ){
+ /* A negative cache-size value C indicates that the cache is abs(C)
+ ** KiB in size. */
+ mxCache = mxCache * -1024;
+ }else{
+ mxCache = mxCache * pgsz;
+ }
+ mxCache = MIN(mxCache, SQLITE_MAX_PMASZ);
+ pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache);
+
+ /* Avoid large memory allocations if the application has requested
+ ** SQLITE_CONFIG_SMALL_MALLOC. */
+ if( sqlite3GlobalConfig.bSmallMalloc==0 ){
assert( pSorter->iMemory==0 );
pSorter->nMemory = pgsz;
pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
- if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT;
+ if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT;
}
}
@@ -96956,14 +96956,14 @@ SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){
** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
*/
SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
- VdbeSorter *pSorter;
- assert( pCsr->eCurType==CURTYPE_SORTER );
- pSorter = pCsr->uc.pSorter;
+ VdbeSorter *pSorter;
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.pSorter;
if( pSorter ){
sqlite3VdbeSorterReset(db, pSorter);
sqlite3_free(pSorter->list.aMemory);
sqlite3DbFree(db, pSorter);
- pCsr->uc.pSorter = 0;
+ pCsr->uc.pSorter = 0;
}
}
@@ -97025,9 +97025,9 @@ static int vdbeSorterOpenTempFile(
*/
static int vdbeSortAllocUnpacked(SortSubtask *pTask){
if( pTask->pUnpacked==0 ){
- pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo);
- if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT;
- pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nKeyField;
+ pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo);
+ if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT;
+ pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nKeyField;
pTask->pUnpacked->errCode = 0;
}
return SQLITE_OK;
@@ -97037,17 +97037,17 @@ static int vdbeSortAllocUnpacked(SortSubtask *pTask){
/*
** Merge the two sorted lists p1 and p2 into a single list.
*/
-static SorterRecord *vdbeSorterMerge(
+static SorterRecord *vdbeSorterMerge(
SortSubtask *pTask, /* Calling thread context */
SorterRecord *p1, /* First list to merge */
- SorterRecord *p2 /* Second list to merge */
+ SorterRecord *p2 /* Second list to merge */
){
SorterRecord *pFinal = 0;
SorterRecord **pp = &pFinal;
int bCached = 0;
- assert( p1!=0 && p2!=0 );
- for(;;){
+ assert( p1!=0 && p2!=0 );
+ for(;;){
int res;
res = pTask->xCompare(
pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal
@@ -97057,22 +97057,22 @@ static SorterRecord *vdbeSorterMerge(
*pp = p1;
pp = &p1->u.pNext;
p1 = p1->u.pNext;
- if( p1==0 ){
- *pp = p2;
- break;
- }
+ if( p1==0 ){
+ *pp = p2;
+ break;
+ }
}else{
*pp = p2;
pp = &p2->u.pNext;
p2 = p2->u.pNext;
bCached = 0;
- if( p2==0 ){
- *pp = p1;
- break;
- }
+ if( p2==0 ){
+ *pp = p1;
+ break;
+ }
}
}
- return pFinal;
+ return pFinal;
}
/*
@@ -97121,7 +97121,7 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
p->u.pNext = 0;
for(i=0; aSlot[i]; i++){
- p = vdbeSorterMerge(pTask, p, aSlot[i]);
+ p = vdbeSorterMerge(pTask, p, aSlot[i]);
aSlot[i] = 0;
}
aSlot[i] = p;
@@ -97130,8 +97130,8 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
p = 0;
for(i=0; i<ArraySize(aSlot); i++){
- if( aSlot[i]==0 ) continue;
- p = p ? vdbeSorterMerge(pTask, p, aSlot[i]) : aSlot[i];
+ if( aSlot[i]==0 ) continue;
+ p = p ? vdbeSorterMerge(pTask, p, aSlot[i]) : aSlot[i];
}
pList->pList = p;
@@ -97153,7 +97153,7 @@ static void vdbePmaWriterInit(
memset(p, 0, sizeof(PmaWriter));
p->aBuffer = (u8*)sqlite3Malloc(nBuf);
if( !p->aBuffer ){
- p->eFWErr = SQLITE_NOMEM_BKPT;
+ p->eFWErr = SQLITE_NOMEM_BKPT;
}else{
p->iBufEnd = p->iBufStart = (iStart % nBuf);
p->iWriteOff = iStart - p->iBufStart;
@@ -97444,7 +97444,7 @@ static int vdbeSorterFlushPMA(VdbeSorter *pSorter){
pSorter->nMemory = sqlite3MallocSize(aMem);
}else if( pSorter->list.aMemory ){
pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory);
- if( !pSorter->list.aMemory ) return SQLITE_NOMEM_BKPT;
+ if( !pSorter->list.aMemory ) return SQLITE_NOMEM_BKPT;
}
rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx);
@@ -97462,7 +97462,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
const VdbeCursor *pCsr, /* Sorter cursor */
Mem *pVal /* Memory cell containing record */
){
- VdbeSorter *pSorter;
+ VdbeSorter *pSorter;
int rc = SQLITE_OK; /* Return Code */
SorterRecord *pNew; /* New list element */
int bFlush; /* True to flush contents of memory to PMA */
@@ -97470,8 +97470,8 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
int nPMA; /* Bytes of PMA space required */
int t; /* serial type of first record field */
- assert( pCsr->eCurType==CURTYPE_SORTER );
- pSorter = pCsr->uc.pSorter;
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.pSorter;
getVarint32NR((const u8*)&pVal->z[1], t);
if( t>0 && t<10 && t!=7 ){
pSorter->typeMask &= SORTER_TYPE_INTEGER;
@@ -97537,7 +97537,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize;
if( nNew < nMin ) nNew = nMin;
aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
- if( !aNew ) return SQLITE_NOMEM_BKPT;
+ if( !aNew ) return SQLITE_NOMEM_BKPT;
if( iListOff>=0 ){
pSorter->list.pList = (SorterRecord*)&aNew[iListOff];
}
@@ -97547,13 +97547,13 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory];
pSorter->iMemory += ROUND8(nReq);
- if( pSorter->list.pList ){
- pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
- }
+ if( pSorter->list.pList ){
+ pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
+ }
}else{
pNew = (SorterRecord *)sqlite3Malloc(nReq);
if( pNew==0 ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
pNew->u.pNext = pSorter->list.pList;
}
@@ -97700,7 +97700,7 @@ static int vdbeIncrMergerNew(
pTask->file2.iEof += pIncr->mxSz;
}else{
vdbeMergeEngineFree(pMerger);
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
assert( *ppOut!=0 || rc!=SQLITE_OK );
return rc;
@@ -98011,10 +98011,10 @@ static int vdbeMergeEngineLevel0(
int rc = SQLITE_OK;
*ppOut = pNew = vdbeMergeEngineNew(nPMA);
- if( pNew==0 ) rc = SQLITE_NOMEM_BKPT;
+ if( pNew==0 ) rc = SQLITE_NOMEM_BKPT;
for(i=0; i<nPMA && rc==SQLITE_OK; i++){
- i64 nDummy = 0;
+ i64 nDummy = 0;
PmaReader *pReadr = &pNew->aReadr[i];
rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy);
iOff = pReadr->iEof;
@@ -98082,7 +98082,7 @@ static int vdbeSorterAddToTree(
if( pReadr->pIncr==0 ){
MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
if( pNew==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}else{
rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr);
}
@@ -98127,7 +98127,7 @@ static int vdbeSorterMergeTreeBuild(
assert( pSorter->bUseThreads || pSorter->nTask==1 );
if( pSorter->nTask>1 ){
pMain = vdbeMergeEngineNew(pSorter->nTask);
- if( pMain==0 ) rc = SQLITE_NOMEM_BKPT;
+ if( pMain==0 ) rc = SQLITE_NOMEM_BKPT;
}
#endif
@@ -98145,7 +98145,7 @@ static int vdbeSorterMergeTreeBuild(
int i;
int iSeq = 0;
pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
- if( pRoot==0 ) rc = SQLITE_NOMEM_BKPT;
+ if( pRoot==0 ) rc = SQLITE_NOMEM_BKPT;
for(i=0; i<pTask->nPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){
MergeEngine *pMerger = 0; /* New level-0 PMA merger */
int nReader; /* Number of level-0 PMAs to merge */
@@ -98216,7 +98216,7 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
if( rc==SQLITE_OK ){
pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
pSorter->pReader = pReadr;
- if( pReadr==0 ) rc = SQLITE_NOMEM_BKPT;
+ if( pReadr==0 ) rc = SQLITE_NOMEM_BKPT;
}
if( rc==SQLITE_OK ){
rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr);
@@ -98274,11 +98274,11 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
** in sorted order.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){
- VdbeSorter *pSorter;
+ VdbeSorter *pSorter;
int rc = SQLITE_OK; /* Return code */
- assert( pCsr->eCurType==CURTYPE_SORTER );
- pSorter = pCsr->uc.pSorter;
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.pSorter;
assert( pSorter );
/* If no data has been written to disk, then do not do so now. Instead,
@@ -98319,18 +98319,18 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){
}
/*
-** Advance to the next element in the sorter. Return value:
-**
-** SQLITE_OK success
-** SQLITE_DONE end of data
-** otherwise some kind of error.
+** Advance to the next element in the sorter. Return value:
+**
+** SQLITE_OK success
+** SQLITE_DONE end of data
+** otherwise some kind of error.
*/
-SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr){
- VdbeSorter *pSorter;
+SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr){
+ VdbeSorter *pSorter;
int rc; /* Return code */
- assert( pCsr->eCurType==CURTYPE_SORTER );
- pSorter = pCsr->uc.pSorter;
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.pSorter;
assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) );
if( pSorter->bUsePMA ){
assert( pSorter->pReader==0 || pSorter->pMerger==0 );
@@ -98339,22 +98339,22 @@ SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr){
#if SQLITE_MAX_WORKER_THREADS>0
if( pSorter->bUseThreads ){
rc = vdbePmaReaderNext(pSorter->pReader);
- if( rc==SQLITE_OK && pSorter->pReader->pFd==0 ) rc = SQLITE_DONE;
+ if( rc==SQLITE_OK && pSorter->pReader->pFd==0 ) rc = SQLITE_DONE;
}else
#endif
/*if( !pSorter->bUseThreads )*/ {
- int res = 0;
+ int res = 0;
assert( pSorter->pMerger!=0 );
assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) );
- rc = vdbeMergeEngineStep(pSorter->pMerger, &res);
- if( rc==SQLITE_OK && res ) rc = SQLITE_DONE;
+ rc = vdbeMergeEngineStep(pSorter->pMerger, &res);
+ if( rc==SQLITE_OK && res ) rc = SQLITE_DONE;
}
}else{
SorterRecord *pFree = pSorter->list.pList;
pSorter->list.pList = pFree->u.pNext;
pFree->u.pNext = 0;
if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree);
- rc = pSorter->list.pList ? SQLITE_OK : SQLITE_DONE;
+ rc = pSorter->list.pList ? SQLITE_OK : SQLITE_DONE;
}
return rc;
}
@@ -98391,14 +98391,14 @@ static void *vdbeSorterRowkey(
** Copy the current sorter key into the memory cell pOut.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
- VdbeSorter *pSorter;
+ VdbeSorter *pSorter;
void *pKey; int nKey; /* Sorter key to copy into pOut */
- assert( pCsr->eCurType==CURTYPE_SORTER );
- pSorter = pCsr->uc.pSorter;
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.pSorter;
pKey = vdbeSorterRowkey(pSorter, &nKey);
if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
pOut->n = nKey;
MemSetTypeFlag(pOut, MEM_Blob);
@@ -98429,19 +98429,19 @@ SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
int nKeyCol, /* Compare this many columns */
int *pRes /* OUT: Result of comparison */
){
- VdbeSorter *pSorter;
- UnpackedRecord *r2;
- KeyInfo *pKeyInfo;
+ VdbeSorter *pSorter;
+ UnpackedRecord *r2;
+ KeyInfo *pKeyInfo;
int i;
void *pKey; int nKey; /* Sorter key to compare pVal with */
- assert( pCsr->eCurType==CURTYPE_SORTER );
- pSorter = pCsr->uc.pSorter;
- r2 = pSorter->pUnpacked;
- pKeyInfo = pCsr->pKeyInfo;
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.pSorter;
+ r2 = pSorter->pUnpacked;
+ pKeyInfo = pCsr->pKeyInfo;
if( r2==0 ){
- r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
- if( r2==0 ) return SQLITE_NOMEM_BKPT;
+ r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
+ if( r2==0 ) return SQLITE_NOMEM_BKPT;
r2->nField = nKeyCol;
}
assert( r2->nField==nKeyCol );
@@ -98903,15 +98903,15 @@ SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ return SQLITE_OK; }
** This file contains code use to implement an in-memory rollback journal.
** The in-memory rollback journal is used to journal transactions for
** ":memory:" databases and when the journal_mode=MEMORY pragma is used.
-**
-** Update: The in-memory journal is also used to temporarily cache
-** smaller journals that are not critical for power-loss recovery.
-** For example, statement journals that are not too big will be held
-** entirely in memory, thus reducing the number of file I/O calls, and
-** more importantly, reducing temporary file creation events. If these
-** journals become too large for memory, they are spilled to disk. But
-** in the common case, they are usually small and no file I/O needs to
-** occur.
+**
+** Update: The in-memory journal is also used to temporarily cache
+** smaller journals that are not critical for power-loss recovery.
+** For example, statement journals that are not too big will be held
+** entirely in memory, thus reducing the number of file I/O calls, and
+** more importantly, reducing temporary file creation events. If these
+** journals become too large for memory, they are spilled to disk. But
+** in the common case, they are usually small and no file I/O needs to
+** occur.
*/
/* #include "sqliteInt.h" */
@@ -98922,27 +98922,27 @@ typedef struct FileChunk FileChunk;
/*
** The rollback journal is composed of a linked list of these structures.
-**
-** The zChunk array is always at least 8 bytes in size - usually much more.
-** Its actual size is stored in the MemJournal.nChunkSize variable.
+**
+** The zChunk array is always at least 8 bytes in size - usually much more.
+** Its actual size is stored in the MemJournal.nChunkSize variable.
*/
struct FileChunk {
FileChunk *pNext; /* Next chunk in the journal */
- u8 zChunk[8]; /* Content of this chunk */
+ u8 zChunk[8]; /* Content of this chunk */
};
/*
-** By default, allocate this many bytes of memory for each FileChunk object.
-*/
-#define MEMJOURNAL_DFLT_FILECHUNKSIZE 1024
-
-/*
-** For chunk size nChunkSize, return the number of bytes that should
-** be allocated for each FileChunk structure.
-*/
-#define fileChunkSize(nChunkSize) (sizeof(FileChunk) + ((nChunkSize)-8))
-
-/*
+** By default, allocate this many bytes of memory for each FileChunk object.
+*/
+#define MEMJOURNAL_DFLT_FILECHUNKSIZE 1024
+
+/*
+** For chunk size nChunkSize, return the number of bytes that should
+** be allocated for each FileChunk structure.
+*/
+#define fileChunkSize(nChunkSize) (sizeof(FileChunk) + ((nChunkSize)-8))
+
+/*
** An instance of this object serves as a cursor into the rollback journal.
** The cursor can be either for reading or writing.
*/
@@ -98952,21 +98952,21 @@ struct FilePoint {
};
/*
-** This structure is a subclass of sqlite3_file. Each open memory-journal
+** This structure is a subclass of sqlite3_file. Each open memory-journal
** is an instance of this class.
*/
struct MemJournal {
- const sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */
- int nChunkSize; /* In-memory chunk-size */
-
- int nSpill; /* Bytes of data before flushing */
+ const sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */
+ int nChunkSize; /* In-memory chunk-size */
+
+ int nSpill; /* Bytes of data before flushing */
FileChunk *pFirst; /* Head of in-memory chunk-list */
FilePoint endpoint; /* Pointer to the end of the file */
FilePoint readpoint; /* Pointer to the end of the last xRead() */
-
- int flags; /* xOpen flags */
- sqlite3_vfs *pVfs; /* The "real" underlying VFS */
- const char *zJournal; /* Name of the journal file */
+
+ int flags; /* xOpen flags */
+ sqlite3_vfs *pVfs; /* The "real" underlying VFS */
+ const char *zJournal; /* Name of the journal file */
};
/*
@@ -98985,90 +98985,90 @@ static int memjrnlRead(
int iChunkOffset;
FileChunk *pChunk;
- if( (iAmt+iOfst)>p->endpoint.iOffset ){
- return SQLITE_IOERR_SHORT_READ;
- }
- assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 );
+ if( (iAmt+iOfst)>p->endpoint.iOffset ){
+ return SQLITE_IOERR_SHORT_READ;
+ }
+ assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 );
if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
sqlite3_int64 iOff = 0;
for(pChunk=p->pFirst;
- ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst;
+ ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst;
pChunk=pChunk->pNext
){
- iOff += p->nChunkSize;
+ iOff += p->nChunkSize;
}
}else{
pChunk = p->readpoint.pChunk;
- assert( pChunk!=0 );
+ assert( pChunk!=0 );
}
- iChunkOffset = (int)(iOfst%p->nChunkSize);
+ iChunkOffset = (int)(iOfst%p->nChunkSize);
do {
- int iSpace = p->nChunkSize - iChunkOffset;
- int nCopy = MIN(nRead, (p->nChunkSize - iChunkOffset));
- memcpy(zOut, (u8*)pChunk->zChunk + iChunkOffset, nCopy);
+ int iSpace = p->nChunkSize - iChunkOffset;
+ int nCopy = MIN(nRead, (p->nChunkSize - iChunkOffset));
+ memcpy(zOut, (u8*)pChunk->zChunk + iChunkOffset, nCopy);
zOut += nCopy;
nRead -= iSpace;
iChunkOffset = 0;
} while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
- p->readpoint.iOffset = pChunk ? iOfst+iAmt : 0;
+ p->readpoint.iOffset = pChunk ? iOfst+iAmt : 0;
p->readpoint.pChunk = pChunk;
return SQLITE_OK;
}
/*
-** Free the list of FileChunk structures headed at MemJournal.pFirst.
-*/
+** Free the list of FileChunk structures headed at MemJournal.pFirst.
+*/
static void memjrnlFreeChunks(FileChunk *pFirst){
- FileChunk *pIter;
- FileChunk *pNext;
+ FileChunk *pIter;
+ FileChunk *pNext;
for(pIter=pFirst; pIter; pIter=pNext){
- pNext = pIter->pNext;
- sqlite3_free(pIter);
- }
-}
-
-/*
-** Flush the contents of memory to a real file on disk.
-*/
-static int memjrnlCreateFile(MemJournal *p){
- int rc;
- sqlite3_file *pReal = (sqlite3_file*)p;
- MemJournal copy = *p;
-
- memset(p, 0, sizeof(MemJournal));
- rc = sqlite3OsOpen(copy.pVfs, copy.zJournal, pReal, copy.flags, 0);
- if( rc==SQLITE_OK ){
- int nChunk = copy.nChunkSize;
- i64 iOff = 0;
- FileChunk *pIter;
- for(pIter=copy.pFirst; pIter; pIter=pIter->pNext){
- if( iOff + nChunk > copy.endpoint.iOffset ){
- nChunk = copy.endpoint.iOffset - iOff;
- }
- rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff);
- if( rc ) break;
- iOff += nChunk;
- }
- if( rc==SQLITE_OK ){
- /* No error has occurred. Free the in-memory buffers. */
+ pNext = pIter->pNext;
+ sqlite3_free(pIter);
+ }
+}
+
+/*
+** Flush the contents of memory to a real file on disk.
+*/
+static int memjrnlCreateFile(MemJournal *p){
+ int rc;
+ sqlite3_file *pReal = (sqlite3_file*)p;
+ MemJournal copy = *p;
+
+ memset(p, 0, sizeof(MemJournal));
+ rc = sqlite3OsOpen(copy.pVfs, copy.zJournal, pReal, copy.flags, 0);
+ if( rc==SQLITE_OK ){
+ int nChunk = copy.nChunkSize;
+ i64 iOff = 0;
+ FileChunk *pIter;
+ for(pIter=copy.pFirst; pIter; pIter=pIter->pNext){
+ if( iOff + nChunk > copy.endpoint.iOffset ){
+ nChunk = copy.endpoint.iOffset - iOff;
+ }
+ rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff);
+ if( rc ) break;
+ iOff += nChunk;
+ }
+ if( rc==SQLITE_OK ){
+ /* No error has occurred. Free the in-memory buffers. */
memjrnlFreeChunks(copy.pFirst);
- }
- }
- if( rc!=SQLITE_OK ){
- /* If an error occurred while creating or writing to the file, restore
- ** the original before returning. This way, SQLite uses the in-memory
- ** journal data to roll back changes made to the internal page-cache
- ** before this function was called. */
- sqlite3OsClose(pReal);
- *p = copy;
- }
- return rc;
-}
-
-
-/*
+ }
+ }
+ if( rc!=SQLITE_OK ){
+ /* If an error occurred while creating or writing to the file, restore
+ ** the original before returning. This way, SQLite uses the in-memory
+ ** journal data to roll back changes made to the internal page-cache
+ ** before this function was called. */
+ sqlite3OsClose(pReal);
+ *p = copy;
+ }
+ return rc;
+}
+
+
+/*
** Write data to the file.
*/
static int memjrnlWrite(
@@ -99081,60 +99081,60 @@ static int memjrnlWrite(
int nWrite = iAmt;
u8 *zWrite = (u8 *)zBuf;
- /* If the file should be created now, create it and write the new data
- ** into the file on disk. */
- if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){
- int rc = memjrnlCreateFile(p);
- if( rc==SQLITE_OK ){
- rc = sqlite3OsWrite(pJfd, zBuf, iAmt, iOfst);
- }
- return rc;
- }
-
- /* If the contents of this write should be stored in memory */
- else{
- /* An in-memory journal file should only ever be appended to. Random
- ** access writes are not required. The only exception to this is when
- ** the in-memory journal is being used by a connection using the
- ** atomic-write optimization. In this case the first 28 bytes of the
+ /* If the file should be created now, create it and write the new data
+ ** into the file on disk. */
+ if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){
+ int rc = memjrnlCreateFile(p);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3OsWrite(pJfd, zBuf, iAmt, iOfst);
+ }
+ return rc;
+ }
+
+ /* If the contents of this write should be stored in memory */
+ else{
+ /* An in-memory journal file should only ever be appended to. Random
+ ** access writes are not required. The only exception to this is when
+ ** the in-memory journal is being used by a connection using the
+ ** atomic-write optimization. In this case the first 28 bytes of the
** journal file may be written as part of committing the transaction. */
- assert( iOfst==p->endpoint.iOffset || iOfst==0 );
-#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
- || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
- if( iOfst==0 && p->pFirst ){
- assert( p->nChunkSize>iAmt );
- memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
- }else
-#else
- assert( iOfst>0 || p->pFirst==0 );
-#endif
- {
- while( nWrite>0 ){
- FileChunk *pChunk = p->endpoint.pChunk;
- int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
- int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
-
- if( iChunkOffset==0 ){
- /* New chunk is required to extend the file. */
- FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
- if( !pNew ){
- return SQLITE_IOERR_NOMEM_BKPT;
- }
- pNew->pNext = 0;
- if( pChunk ){
- assert( p->pFirst );
- pChunk->pNext = pNew;
- }else{
- assert( !p->pFirst );
- p->pFirst = pNew;
- }
- p->endpoint.pChunk = pNew;
- }
-
- memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace);
- zWrite += iSpace;
- nWrite -= iSpace;
- p->endpoint.iOffset += iSpace;
+ assert( iOfst==p->endpoint.iOffset || iOfst==0 );
+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+ if( iOfst==0 && p->pFirst ){
+ assert( p->nChunkSize>iAmt );
+ memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
+ }else
+#else
+ assert( iOfst>0 || p->pFirst==0 );
+#endif
+ {
+ while( nWrite>0 ){
+ FileChunk *pChunk = p->endpoint.pChunk;
+ int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
+ int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
+
+ if( iChunkOffset==0 ){
+ /* New chunk is required to extend the file. */
+ FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
+ if( !pNew ){
+ return SQLITE_IOERR_NOMEM_BKPT;
+ }
+ pNew->pNext = 0;
+ if( pChunk ){
+ assert( p->pFirst );
+ pChunk->pNext = pNew;
+ }else{
+ assert( !p->pFirst );
+ p->pFirst = pNew;
+ }
+ p->endpoint.pChunk = pNew;
+ }
+
+ memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace);
+ zWrite += iSpace;
+ nWrite -= iSpace;
+ p->endpoint.iOffset += iSpace;
}
}
}
@@ -99166,8 +99166,8 @@ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
p->endpoint.pChunk = pIter;
p->endpoint.iOffset = size;
- p->readpoint.pChunk = 0;
- p->readpoint.iOffset = 0;
+ p->readpoint.pChunk = 0;
+ p->readpoint.iOffset = 0;
}
return SQLITE_OK;
}
@@ -99176,7 +99176,7 @@ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
** Close the file.
*/
static int memjrnlClose(sqlite3_file *pJfd){
- MemJournal *p = (MemJournal *)pJfd;
+ MemJournal *p = (MemJournal *)pJfd;
memjrnlFreeChunks(p->pFirst);
return SQLITE_OK;
}
@@ -99187,8 +99187,8 @@ static int memjrnlClose(sqlite3_file *pJfd){
** If the real file has been created, call its xSync method. Otherwise,
** syncing an in-memory journal is a no-op.
*/
-static int memjrnlSync(sqlite3_file *pJfd, int flags){
- UNUSED_PARAMETER2(pJfd, flags);
+static int memjrnlSync(sqlite3_file *pJfd, int flags){
+ UNUSED_PARAMETER2(pJfd, flags);
return SQLITE_OK;
}
@@ -99228,101 +99228,101 @@ static const struct sqlite3_io_methods MemJournalMethods = {
/*
** Open a journal file.
-**
+**
** The behaviour of the journal file depends on the value of parameter
** nSpill. If nSpill is 0, then the journal file is always create and
-** accessed using the underlying VFS. If nSpill is less than zero, then
-** all content is always stored in main-memory. Finally, if nSpill is a
-** positive value, then the journal file is initially created in-memory
-** but may be flushed to disk later on. In this case the journal file is
-** flushed to disk either when it grows larger than nSpill bytes in size,
-** or when sqlite3JournalCreate() is called.
-*/
-SQLITE_PRIVATE int sqlite3JournalOpen(
- sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */
- const char *zName, /* Name of the journal file */
- sqlite3_file *pJfd, /* Preallocated, blank file handle */
- int flags, /* Opening flags */
- int nSpill /* Bytes buffered before opening the file */
-){
- MemJournal *p = (MemJournal*)pJfd;
-
- /* Zero the file-handle object. If nSpill was passed zero, initialize
- ** it using the sqlite3OsOpen() function of the underlying VFS. In this
- ** case none of the code in this module is executed as a result of calls
- ** made on the journal file-handle. */
- memset(p, 0, sizeof(MemJournal));
- if( nSpill==0 ){
- return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
- }
-
- if( nSpill>0 ){
- p->nChunkSize = nSpill;
- }else{
- p->nChunkSize = 8 + MEMJOURNAL_DFLT_FILECHUNKSIZE - sizeof(FileChunk);
- assert( MEMJOURNAL_DFLT_FILECHUNKSIZE==fileChunkSize(p->nChunkSize) );
- }
-
+** accessed using the underlying VFS. If nSpill is less than zero, then
+** all content is always stored in main-memory. Finally, if nSpill is a
+** positive value, then the journal file is initially created in-memory
+** but may be flushed to disk later on. In this case the journal file is
+** flushed to disk either when it grows larger than nSpill bytes in size,
+** or when sqlite3JournalCreate() is called.
+*/
+SQLITE_PRIVATE int sqlite3JournalOpen(
+ sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */
+ const char *zName, /* Name of the journal file */
+ sqlite3_file *pJfd, /* Preallocated, blank file handle */
+ int flags, /* Opening flags */
+ int nSpill /* Bytes buffered before opening the file */
+){
+ MemJournal *p = (MemJournal*)pJfd;
+
+ /* Zero the file-handle object. If nSpill was passed zero, initialize
+ ** it using the sqlite3OsOpen() function of the underlying VFS. In this
+ ** case none of the code in this module is executed as a result of calls
+ ** made on the journal file-handle. */
+ memset(p, 0, sizeof(MemJournal));
+ if( nSpill==0 ){
+ return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
+ }
+
+ if( nSpill>0 ){
+ p->nChunkSize = nSpill;
+ }else{
+ p->nChunkSize = 8 + MEMJOURNAL_DFLT_FILECHUNKSIZE - sizeof(FileChunk);
+ assert( MEMJOURNAL_DFLT_FILECHUNKSIZE==fileChunkSize(p->nChunkSize) );
+ }
+
pJfd->pMethods = (const sqlite3_io_methods*)&MemJournalMethods;
- p->nSpill = nSpill;
- p->flags = flags;
- p->zJournal = zName;
- p->pVfs = pVfs;
- return SQLITE_OK;
-}
-
-/*
-** Open an in-memory journal file.
-*/
+ p->nSpill = nSpill;
+ p->flags = flags;
+ p->zJournal = zName;
+ p->pVfs = pVfs;
+ return SQLITE_OK;
+}
+
+/*
+** Open an in-memory journal file.
+*/
SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){
- sqlite3JournalOpen(0, 0, pJfd, 0, -1);
+ sqlite3JournalOpen(0, 0, pJfd, 0, -1);
}
-#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
- || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
/*
** If the argument p points to a MemJournal structure that is not an
-** in-memory-only journal file (i.e. is one that was opened with a +ve
+** in-memory-only journal file (i.e. is one that was opened with a +ve
** nSpill parameter or as SQLITE_OPEN_MAIN_JOURNAL), and the underlying
-** file has not yet been created, create it now.
+** file has not yet been created, create it now.
*/
-SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *pJfd){
- int rc = SQLITE_OK;
- MemJournal *p = (MemJournal*)pJfd;
+SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *pJfd){
+ int rc = SQLITE_OK;
+ MemJournal *p = (MemJournal*)pJfd;
if( pJfd->pMethods==&MemJournalMethods && (
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
- p->nSpill>0
-#else
- /* While this appears to not be possible without ATOMIC_WRITE, the
- ** paths are complex, so it seems prudent to leave the test in as
- ** a NEVER(), in case our analysis is subtly flawed. */
- NEVER(p->nSpill>0)
-#endif
-#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
- || (p->flags & SQLITE_OPEN_MAIN_JOURNAL)
-#endif
- )){
- rc = memjrnlCreateFile(p);
- }
- return rc;
-}
-#endif
-
-/*
-** The file-handle passed as the only argument is open on a journal file.
-** Return true if this "journal file" is currently stored in heap memory,
-** or false otherwise.
-*/
-SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p){
- return p->pMethods==&MemJournalMethods;
-}
-
-/*
-** Return the number of bytes required to store a JournalFile that uses vfs
-** pVfs to create the underlying on-disk files.
-*/
-SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
- return MAX(pVfs->szOsFile, (int)sizeof(MemJournal));
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+ p->nSpill>0
+#else
+ /* While this appears to not be possible without ATOMIC_WRITE, the
+ ** paths are complex, so it seems prudent to leave the test in as
+ ** a NEVER(), in case our analysis is subtly flawed. */
+ NEVER(p->nSpill>0)
+#endif
+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+ || (p->flags & SQLITE_OPEN_MAIN_JOURNAL)
+#endif
+ )){
+ rc = memjrnlCreateFile(p);
+ }
+ return rc;
+}
+#endif
+
+/*
+** The file-handle passed as the only argument is open on a journal file.
+** Return true if this "journal file" is currently stored in heap memory,
+** or false otherwise.
+*/
+SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p){
+ return p->pMethods==&MemJournalMethods;
+}
+
+/*
+** Return the number of bytes required to store a JournalFile that uses vfs
+** pVfs to create the underlying on-disk files.
+*/
+SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
+ return MAX(pVfs->szOsFile, (int)sizeof(MemJournal));
}
/************** End of memjournal.c ******************************************/
@@ -99381,32 +99381,32 @@ static int walkWindowList(Walker *pWalker, Window *pList, int bOneOnly){
**
** WRC_Continue Continue descending down the tree.
**
-** WRC_Prune Do not descend into child nodes, but allow
+** WRC_Prune Do not descend into child nodes, but allow
** the walk to continue with sibling nodes.
**
** WRC_Abort Do no more callbacks. Unwind the stack and
-** return from the top-level walk call.
+** return from the top-level walk call.
**
** The return value from this routine is WRC_Abort to abandon the tree walk
** and WRC_Continue to continue.
*/
-static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
+static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
int rc;
testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
testcase( ExprHasProperty(pExpr, EP_Reduced) );
- while(1){
- rc = pWalker->xExprCallback(pWalker, pExpr);
- if( rc ) return rc & WRC_Abort;
- if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
+ while(1){
+ rc = pWalker->xExprCallback(pWalker, pExpr);
+ if( rc ) return rc & WRC_Abort;
+ if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
assert( pExpr->x.pList==0 || pExpr->pRight==0 );
- if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
- if( pExpr->pRight ){
+ if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
+ if( pExpr->pRight ){
assert( !ExprHasProperty(pExpr, EP_WinFunc) );
- pExpr = pExpr->pRight;
- continue;
+ pExpr = pExpr->pRight;
+ continue;
}else if( ExprUseXSelect(pExpr) ){
assert( !ExprHasProperty(pExpr, EP_WinFunc) );
- if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
+ if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
}else{
if( pExpr->x.pList ){
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
@@ -99418,13 +99418,13 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
#endif
}
}
- break;
+ break;
}
- return WRC_Continue;
+ return WRC_Continue;
+}
+SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
+ return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue;
}
-SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
- return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue;
-}
/*
** Call sqlite3WalkExpr() for every expression in list p or until
@@ -99518,9 +99518,9 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
**
** If it is not NULL, the xSelectCallback() callback is invoked before
** the walk of the expressions and FROM clause. The xSelectCallback2()
-** method is invoked following the walk of the expressions and FROM clause,
-** but only if both xSelectCallback and xSelectCallback2 are both non-NULL
-** and if the expressions and FROM clause both return WRC_Continue;
+** method is invoked following the walk of the expressions and FROM clause,
+** but only if both xSelectCallback and xSelectCallback2 are both non-NULL
+** and if the expressions and FROM clause both return WRC_Continue;
**
** Return WRC_Continue under normal conditions. Return WRC_Abort if
** there is an abort request.
@@ -99530,11 +99530,11 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
*/
SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
int rc;
- if( p==0 ) return WRC_Continue;
- if( pWalker->xSelectCallback==0 ) return WRC_Continue;
- do{
- rc = pWalker->xSelectCallback(pWalker, p);
- if( rc ) return rc & WRC_Abort;
+ if( p==0 ) return WRC_Continue;
+ if( pWalker->xSelectCallback==0 ) return WRC_Continue;
+ do{
+ rc = pWalker->xSelectCallback(pWalker, p);
+ if( rc ) return rc & WRC_Abort;
if( sqlite3WalkSelectExpr(pWalker, p)
|| sqlite3WalkSelectFrom(pWalker, p)
){
@@ -99544,8 +99544,8 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
pWalker->xSelectCallback2(pWalker, p);
}
p = p->pPrior;
- }while( p!=0 );
- return WRC_Continue;
+ }while( p!=0 );
+ return WRC_Continue;
}
/* Increase the walkerDepth when entering a subquery, and
@@ -99868,8 +99868,8 @@ static int lookupName(
zDb = 0;
}else{
for(i=0; i<db->nDb; i++){
- assert( db->aDb[i].zDbSName );
- if( sqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){
+ assert( db->aDb[i].zDbSName );
+ if( sqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){
pSchema = db->aDb[i].pSchema;
break;
}
@@ -99884,8 +99884,8 @@ static int lookupName(
}
/* Start at the inner-most context and move outward until a match is found */
- assert( pNC && cnt==0 );
- do{
+ assert( pNC && cnt==0 );
+ do{
ExprList *pEList;
SrcList *pSrcList = pNC->pSrcList;
@@ -99933,7 +99933,7 @@ static int lookupName(
** USING clause, then skip this match.
*/
if( cnt==1 ){
- if( pItem->fg.jointype & JT_NATURAL ) continue;
+ if( pItem->fg.jointype & JT_NATURAL ) continue;
if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
}
cnt++;
@@ -99953,8 +99953,8 @@ static int lookupName(
assert( ExprUseYTab(pExpr) );
pExpr->y.pTab = pMatch->pTab;
/* RIGHT JOIN not (yet) supported */
- assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
- if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
+ assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
+ if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
ExprSetProperty(pExpr, EP_CanBeNull);
}
pSchema = pExpr->y.pTab->pSchema;
@@ -100069,15 +100069,15 @@ static int lookupName(
/*
** Perhaps the name is a reference to the ROWID
*/
- if( cnt==0
- && cntTab==1
- && pMatch
+ if( cnt==0
+ && cntTab==1
+ && pMatch
&& (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
- && sqlite3IsRowid(zCol)
+ && sqlite3IsRowid(zCol)
&& ALWAYS(VisibleRowid(pMatch->pTab))
- ){
+ ){
cnt = 1;
- pExpr->iColumn = -1;
+ pExpr->iColumn = -1;
pExpr->affExpr = SQLITE_AFF_INTEGER;
}
@@ -100094,9 +100094,9 @@ static int lookupName(
** resolved by the time the WHERE clause is resolved.
**
** The ability to use an output result-set column in the WHERE, GROUP BY,
- ** or HAVING clauses, or as part of a larger expression in the ORDER BY
+ ** or HAVING clauses, or as part of a larger expression in the ORDER BY
** clause is not standard SQL. This is a (goofy) SQLite extension, that
- ** is supported for backwards compatibility only. Hence, we issue a warning
+ ** is supported for backwards compatibility only. Hence, we issue a warning
** on sqlite3_log() whenever the capability is used.
*/
if( cnt==0
@@ -100125,10 +100125,10 @@ static int lookupName(
sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs);
return WRC_Abort;
}
- if( sqlite3ExprVectorSize(pOrig)!=1 ){
- sqlite3ErrorMsg(pParse, "row value misused");
- return WRC_Abort;
- }
+ if( sqlite3ExprVectorSize(pOrig)!=1 ){
+ sqlite3ErrorMsg(pParse, "row value misused");
+ return WRC_Abort;
+ }
resolveAlias(pParse, pEList, j, pExpr, nSubquery);
cnt = 1;
pMatch = 0;
@@ -100144,12 +100144,12 @@ static int lookupName(
/* Advance to the next name context. The loop will exit when either
** we have a match (cnt>0) or when we run out of name contexts.
*/
- if( cnt ) break;
- pNC = pNC->pNext;
- nSubquery++;
- }while( pNC );
+ if( cnt ) break;
+ pNC = pNC->pNext;
+ nSubquery++;
+ }while( pNC );
+
-
/*
** If X and Y are NULL (in other words if only the column name Z is
** supplied) and the value of Z is enclosed in double-quotes, then
@@ -100238,7 +100238,7 @@ static int lookupName(
pExpr->pRight = 0;
}
pExpr->op = eNewExprOp;
- ExprSetProperty(pExpr, EP_Leaf);
+ ExprSetProperty(pExpr, EP_Leaf);
lookupname_end:
if( cnt==1 ){
assert( pNC!=0 );
@@ -100296,8 +100296,8 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr
}
/*
-** Report an error that an expression is not valid for some set of
-** pNC->ncFlags values determined by validMask.
+** Report an error that an expression is not valid for some set of
+** pNC->ncFlags values determined by validMask.
**
** static void notValid(
** Parse *pParse, // Leave error message here
@@ -100321,7 +100321,7 @@ static void notValidImpl(
if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
#ifndef SQLITE_OMIT_CHECK
else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
-#endif
+#endif
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns";
#endif
@@ -100387,7 +100387,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
SrcList *pSrcList = pNC->pSrcList;
SrcItem *pItem;
assert( pSrcList && pSrcList->nSrc>=1 );
- pItem = pSrcList->a;
+ pItem = pSrcList->a;
pExpr->op = TK_COLUMN;
assert( ExprUseYTab(pExpr) );
pExpr->y.pTab = pItem->pTab;
@@ -100440,42 +100440,42 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
return WRC_Prune;
}
- /* A column name: ID
- ** Or table name and column name: ID.ID
+ /* A column name: ID
+ ** Or table name and column name: ID.ID
** Or a database, table and column: ID.ID.ID
- **
- ** The TK_ID and TK_OUT cases are combined so that there will only
+ **
+ ** The TK_ID and TK_OUT cases are combined so that there will only
** be one call to lookupName(). Then the compiler will in-line
- ** lookupName() for a size reduction and performance increase.
+ ** lookupName() for a size reduction and performance increase.
*/
- case TK_ID:
+ case TK_ID:
case TK_DOT: {
const char *zColumn;
const char *zTable;
const char *zDb;
Expr *pRight;
- if( pExpr->op==TK_ID ){
+ if( pExpr->op==TK_ID ){
zDb = 0;
- zTable = 0;
+ zTable = 0;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- zColumn = pExpr->u.zToken;
+ zColumn = pExpr->u.zToken;
}else{
Expr *pLeft = pExpr->pLeft;
testcase( pNC->ncFlags & NC_IdxExpr );
testcase( pNC->ncFlags & NC_GenCol );
sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator",
NC_IdxExpr|NC_GenCol, 0);
- pRight = pExpr->pRight;
- if( pRight->op==TK_ID ){
- zDb = 0;
- }else{
- assert( pRight->op==TK_DOT );
+ pRight = pExpr->pRight;
+ if( pRight->op==TK_ID ){
+ zDb = 0;
+ }else{
+ assert( pRight->op==TK_DOT );
assert( !ExprHasProperty(pRight, EP_IntValue) );
zDb = pLeft->u.zToken;
pLeft = pRight->pLeft;
pRight = pRight->pRight;
- }
+ }
assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) );
zTable = pLeft->u.zToken;
zColumn = pRight->u.zToken;
@@ -100507,16 +100507,16 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
- pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
+ pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
if( pDef==0 ){
- pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
+ pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
if( pDef==0 ){
no_such_func = 1;
}else{
wrong_num_args = 1;
}
}else{
- is_agg = pDef->xFinalize!=0;
+ is_agg = pDef->xFinalize!=0;
if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
ExprSetProperty(pExpr, EP_Unlikely);
if( n==2 ){
@@ -100541,30 +100541,30 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
}
#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0);
- if( auth!=SQLITE_OK ){
- if( auth==SQLITE_DENY ){
- sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
- pDef->zName);
+ {
+ int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0);
+ if( auth!=SQLITE_OK ){
+ if( auth==SQLITE_DENY ){
+ sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
+ pDef->zName);
pNC->nNcErr++;
- }
- pExpr->op = TK_NULL;
- return WRC_Prune;
+ }
+ pExpr->op = TK_NULL;
+ return WRC_Prune;
}
}
#endif
- if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
- /* For the purposes of the EP_ConstFunc flag, date and time
- ** functions and other functions that change slowly are considered
+ if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
+ /* For the purposes of the EP_ConstFunc flag, date and time
+ ** functions and other functions that change slowly are considered
** constant because they are constant for the duration of one query.
** This allows them to be factored out of inner loops. */
ExprSetProperty(pExpr,EP_ConstFunc);
}
- if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
+ if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
/* Clearly non-deterministic functions like random(), but also
** date/time functions that use 'now', and other functions like
- ** sqlite_version() that might change over time cannot be used
+ ** sqlite_version() that might change over time cannot be used
** in an index or generated column. Curiously, they can be used
** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
** all this. */
@@ -100574,7 +100574,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
pExpr->op2 = pNC->ncFlags & NC_SelfRef;
if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
- }
+ }
if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
&& pParse->nested==0
&& (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0
@@ -100627,9 +100627,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
#endif
else if( no_such_func && pParse->db->init.busy==0
-#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
+#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
&& pParse->explain==0
-#endif
+#endif
){
sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
pNC->nNcErr++;
@@ -100734,7 +100734,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
ExprSetProperty(pExpr, EP_VarSelect);
- pNC->ncFlags |= NC_VarSelect;
+ pNC->ncFlags |= NC_VarSelect;
}
}
break;
@@ -100765,41 +100765,41 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
/* no break */ deliberate_fall_through
}
- case TK_BETWEEN:
- case TK_EQ:
- case TK_NE:
- case TK_LT:
- case TK_LE:
- case TK_GT:
+ case TK_BETWEEN:
+ case TK_EQ:
+ case TK_NE:
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
case TK_GE: {
- int nLeft, nRight;
- if( pParse->db->mallocFailed ) break;
- assert( pExpr->pLeft!=0 );
- nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
- if( pExpr->op==TK_BETWEEN ){
+ int nLeft, nRight;
+ if( pParse->db->mallocFailed ) break;
+ assert( pExpr->pLeft!=0 );
+ nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
+ if( pExpr->op==TK_BETWEEN ){
assert( ExprUseXList(pExpr) );
- nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr);
- if( nRight==nLeft ){
- nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr);
- }
- }else{
- assert( pExpr->pRight!=0 );
- nRight = sqlite3ExprVectorSize(pExpr->pRight);
- }
- if( nLeft!=nRight ){
- testcase( pExpr->op==TK_EQ );
- testcase( pExpr->op==TK_NE );
- testcase( pExpr->op==TK_LT );
- testcase( pExpr->op==TK_LE );
- testcase( pExpr->op==TK_GT );
- testcase( pExpr->op==TK_GE );
- testcase( pExpr->op==TK_IS );
- testcase( pExpr->op==TK_ISNOT );
- testcase( pExpr->op==TK_BETWEEN );
- sqlite3ErrorMsg(pParse, "row value misused");
- }
- break;
- }
+ nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr);
+ if( nRight==nLeft ){
+ nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr);
+ }
+ }else{
+ assert( pExpr->pRight!=0 );
+ nRight = sqlite3ExprVectorSize(pExpr->pRight);
+ }
+ if( nLeft!=nRight ){
+ testcase( pExpr->op==TK_EQ );
+ testcase( pExpr->op==TK_NE );
+ testcase( pExpr->op==TK_LT );
+ testcase( pExpr->op==TK_LE );
+ testcase( pExpr->op==TK_GT );
+ testcase( pExpr->op==TK_GE );
+ testcase( pExpr->op==TK_IS );
+ testcase( pExpr->op==TK_ISNOT );
+ testcase( pExpr->op==TK_BETWEEN );
+ sqlite3ErrorMsg(pParse, "row value misused");
+ }
+ break;
+ }
}
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
}
@@ -100893,7 +100893,7 @@ static int resolveOrderByTermToExprList(
** result-set entry.
*/
for(i=0; i<pEList->nExpr; i++){
- if( sqlite3ExprCompare(0, pEList->a[i].pExpr, pE, -1)<2 ){
+ if( sqlite3ExprCompare(0, pEList->a[i].pExpr, pE, -1)<2 ){
return i+1;
}
}
@@ -101170,7 +101170,7 @@ static int resolveOrderGroupBy(
return 1;
}
for(j=0; j<pSelect->pEList->nExpr; j++){
- if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
+ if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
/* Since this expresion is being changed into a reference
** to an identical expression in the result set, remove all Window
** objects belonging to the expression from the Select.pWin list. */
@@ -101234,7 +101234,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
sNC.pWinSelect = p;
- if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){
+ if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){
return WRC_Abort;
}
@@ -101286,7 +101286,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
sNC.pNext = pOuterNC;
/* Resolve names in the result set. */
- if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
+ if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
sNC.ncFlags &= ~NC_AllowWin;
/* If there are no aggregate functions in the result-set, and no GROUP BY
@@ -101322,16 +101322,16 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
- /* Resolve names in table-valued-function arguments */
- for(i=0; i<p->pSrc->nSrc; i++){
+ /* Resolve names in table-valued-function arguments */
+ for(i=0; i<p->pSrc->nSrc; i++){
SrcItem *pItem = &p->pSrc->a[i];
- if( pItem->fg.isTabFunc
+ if( pItem->fg.isTabFunc
&& sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg)
- ){
- return WRC_Abort;
- }
- }
-
+ ){
+ return WRC_Abort;
+ }
+ }
+
#ifndef SQLITE_OMIT_WINDOWFUNC
if( IN_RENAME_OBJECT ){
Window *pWin;
@@ -101479,23 +101479,23 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
int savedHasAgg;
Walker w;
- if( pExpr==0 ) return SQLITE_OK;
+ if( pExpr==0 ) return SQLITE_OK;
savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
- w.pParse = pNC->pParse;
+ w.pParse = pNC->pParse;
w.xExprCallback = resolveExprStep;
w.xSelectCallback = (pNC->ncFlags & NC_NoSelect) ? 0 : resolveSelectStep;
- w.xSelectCallback2 = 0;
+ w.xSelectCallback2 = 0;
w.u.pNC = pNC;
-#if SQLITE_MAX_EXPR_DEPTH>0
- w.pParse->nHeight += pExpr->nHeight;
- if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
- return SQLITE_ERROR;
- }
-#endif
+#if SQLITE_MAX_EXPR_DEPTH>0
+ w.pParse->nHeight += pExpr->nHeight;
+ if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
+ return SQLITE_ERROR;
+ }
+#endif
sqlite3WalkExpr(&w, pExpr);
#if SQLITE_MAX_EXPR_DEPTH>0
- w.pParse->nHeight -= pExpr->nHeight;
+ w.pParse->nHeight -= pExpr->nHeight;
#endif
assert( EP_Agg==NC_HasAgg );
assert( EP_Win==NC_HasWin );
@@ -101506,16 +101506,16 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
return pNC->nNcErr>0 || w.pParse->nErr>0;
}
-/*
-** Resolve all names for all expression in an expression list. This is
-** just like sqlite3ResolveExprNames() except that it works for an expression
-** list rather than a single expression.
-*/
+/*
+** Resolve all names for all expression in an expression list. This is
+** just like sqlite3ResolveExprNames() except that it works for an expression
+** list rather than a single expression.
+*/
SQLITE_PRIVATE int sqlite3ResolveExprListNames(
- NameContext *pNC, /* Namespace to resolve expressions in. */
- ExprList *pList /* The expression list to be analyzed. */
-){
- int i;
+ NameContext *pNC, /* Namespace to resolve expressions in. */
+ ExprList *pList /* The expression list to be analyzed. */
+){
+ int i;
int savedHasAgg = 0;
Walker w;
if( pList==0 ) return WRC_Continue;
@@ -101533,7 +101533,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames(
w.pParse->nHeight += pExpr->nHeight;
if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
return WRC_Abort;
- }
+ }
#endif
sqlite3WalkExpr(&w, pExpr);
#if SQLITE_MAX_EXPR_DEPTH>0
@@ -101550,10 +101550,10 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames(
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
}
if( w.pParse->nErr>0 ) return WRC_Abort;
- }
+ }
pNC->ncFlags |= savedHasAgg;
- return WRC_Continue;
-}
+ return WRC_Continue;
+}
/*
** Resolve all names in all expressions of a SELECT and in all
@@ -101577,7 +101577,7 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
assert( p!=0 );
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
- w.xSelectCallback2 = 0;
+ w.xSelectCallback2 = 0;
w.pParse = pParse;
w.u.pNC = pOuterNC;
sqlite3WalkSelect(&w, p);
@@ -101654,19 +101654,19 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference(
*/
/* #include "sqliteInt.h" */
-/* Forward declarations */
-static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int);
-static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree);
-
+/* Forward declarations */
+static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int);
+static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree);
+
/*
-** Return the affinity character for a single column of a table.
-*/
+** Return the affinity character for a single column of a table.
+*/
SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
if( iCol<0 || NEVER(iCol>=pTab->nCol) ) return SQLITE_AFF_INTEGER;
return pTab->aCol[iCol].affinity;
-}
-
-/*
+}
+
+/*
** Return the 'affinity' of the expression pExpr if any.
**
** If pExpr is a column, a reference to a column via an 'AS' alias,
@@ -101712,14 +101712,14 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){
return sqlite3AffinityType(pExpr->u.zToken, 0);
}
#endif
- if( op==TK_SELECT_COLUMN ){
+ if( op==TK_SELECT_COLUMN ){
assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) );
assert( pExpr->iColumn < pExpr->iTable );
assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
- return sqlite3ExprAffinity(
- pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
- );
- }
+ return sqlite3ExprAffinity(
+ pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
+ );
+ }
if( op==TK_VECTOR ){
assert( ExprUseXList(pExpr) );
return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
@@ -101758,7 +101758,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(
){
Token s;
assert( zC!=0 );
- sqlite3TokenInit(&s, (char*)zC);
+ sqlite3TokenInit(&s, (char*)zC);
return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
}
@@ -101786,7 +101786,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
}else{
- assert( pExpr->op==TK_COLLATE );
+ assert( pExpr->op==TK_COLLATE );
pExpr = pExpr->pLeft;
}
}
@@ -101797,11 +101797,11 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
** Return the collation sequence for the expression pExpr. If
** there is no defined collating sequence, return NULL.
**
-** See also: sqlite3ExprNNCollSeq()
-**
-** The sqlite3ExprNNCollSeq() works the same exact that it returns the
-** default collation if pExpr has no defined collation.
-**
+** See also: sqlite3ExprNNCollSeq()
+**
+** The sqlite3ExprNNCollSeq() works the same exact that it returns the
+** default collation if pExpr has no defined collation.
+**
** The collating sequence might be determined by a COLLATE operator
** or by the presence of a column with a defined collating sequence.
** COLLATE operators take first precedence. Left operands take
@@ -101871,32 +101871,32 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
}
/*
-** Return the collation sequence for the expression pExpr. If
-** there is no defined collating sequence, return a pointer to the
-** defautl collation sequence.
-**
-** See also: sqlite3ExprCollSeq()
-**
-** The sqlite3ExprCollSeq() routine works the same except that it
-** returns NULL if there is no defined collation.
-*/
+** Return the collation sequence for the expression pExpr. If
+** there is no defined collating sequence, return a pointer to the
+** defautl collation sequence.
+**
+** See also: sqlite3ExprCollSeq()
+**
+** The sqlite3ExprCollSeq() routine works the same except that it
+** returns NULL if there is no defined collation.
+*/
SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){
- CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr);
- if( p==0 ) p = pParse->db->pDfltColl;
- assert( p!=0 );
- return p;
-}
-
-/*
-** Return TRUE if the two expressions have equivalent collating sequences.
-*/
+ CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr);
+ if( p==0 ) p = pParse->db->pDfltColl;
+ assert( p!=0 );
+ return p;
+}
+
+/*
+** Return TRUE if the two expressions have equivalent collating sequences.
+*/
SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){
- CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
- CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
- return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
-}
-
-/*
+ CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
+ CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
+ return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
+}
+
+/*
** pExpr is an operand of a comparison operator. aff2 is the
** type affinity of the other operand. This routine returns the
** type affinity that should be used for the comparison operator.
@@ -101934,7 +101934,7 @@ static char comparisonAffinity(const Expr *pExpr){
aff = sqlite3CompareAffinity(pExpr->pRight, aff);
}else if( ExprUseXSelect(pExpr) ){
aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
- }else if( aff==0 ){
+ }else if( aff==0 ){
aff = SQLITE_AFF_BLOB;
}
return aff;
@@ -102049,122 +102049,122 @@ static int codeCompare(
return addr;
}
-/*
-** Return true if expression pExpr is a vector, or false otherwise.
-**
-** A vector is defined as any expression that results in two or more
-** columns of result. Every TK_VECTOR node is an vector because the
-** parser will not generate a TK_VECTOR with fewer than two entries.
-** But a TK_SELECT might be either a vector or a scalar. It is only
-** considered a vector if it has two or more result columns.
-*/
+/*
+** Return true if expression pExpr is a vector, or false otherwise.
+**
+** A vector is defined as any expression that results in two or more
+** columns of result. Every TK_VECTOR node is an vector because the
+** parser will not generate a TK_VECTOR with fewer than two entries.
+** But a TK_SELECT might be either a vector or a scalar. It is only
+** considered a vector if it has two or more result columns.
+*/
SQLITE_PRIVATE int sqlite3ExprIsVector(const Expr *pExpr){
- return sqlite3ExprVectorSize(pExpr)>1;
-}
-
-/*
+ return sqlite3ExprVectorSize(pExpr)>1;
+}
+
+/*
** If the expression passed as the only argument is of type TK_VECTOR
-** return the number of expressions in the vector. Or, if the expression
-** is a sub-select, return the number of columns in the sub-select. For
-** any other type of expression, return 1.
-*/
+** return the number of expressions in the vector. Or, if the expression
+** is a sub-select, return the number of columns in the sub-select. For
+** any other type of expression, return 1.
+*/
SQLITE_PRIVATE int sqlite3ExprVectorSize(const Expr *pExpr){
- u8 op = pExpr->op;
- if( op==TK_REGISTER ) op = pExpr->op2;
- if( op==TK_VECTOR ){
+ u8 op = pExpr->op;
+ if( op==TK_REGISTER ) op = pExpr->op2;
+ if( op==TK_VECTOR ){
assert( ExprUseXList(pExpr) );
- return pExpr->x.pList->nExpr;
- }else if( op==TK_SELECT ){
+ return pExpr->x.pList->nExpr;
+ }else if( op==TK_SELECT ){
assert( ExprUseXSelect(pExpr) );
- return pExpr->x.pSelect->pEList->nExpr;
- }else{
- return 1;
- }
-}
-
-/*
-** Return a pointer to a subexpression of pVector that is the i-th
-** column of the vector (numbered starting with 0). The caller must
-** ensure that i is within range.
-**
-** If pVector is really a scalar (and "scalar" here includes subqueries
-** that return a single column!) then return pVector unmodified.
-**
-** pVector retains ownership of the returned subexpression.
-**
-** If the vector is a (SELECT ...) then the expression returned is
-** just the expression for the i-th term of the result set, and may
-** not be ready for evaluation because the table cursor has not yet
-** been positioned.
-*/
-SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
+ return pExpr->x.pSelect->pEList->nExpr;
+ }else{
+ return 1;
+ }
+}
+
+/*
+** Return a pointer to a subexpression of pVector that is the i-th
+** column of the vector (numbered starting with 0). The caller must
+** ensure that i is within range.
+**
+** If pVector is really a scalar (and "scalar" here includes subqueries
+** that return a single column!) then return pVector unmodified.
+**
+** pVector retains ownership of the returned subexpression.
+**
+** If the vector is a (SELECT ...) then the expression returned is
+** just the expression for the i-th term of the result set, and may
+** not be ready for evaluation because the table cursor has not yet
+** been positioned.
+*/
+SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
assert( i<sqlite3ExprVectorSize(pVector) || pVector->op==TK_ERROR );
- if( sqlite3ExprIsVector(pVector) ){
- assert( pVector->op2==0 || pVector->op==TK_REGISTER );
- if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){
+ if( sqlite3ExprIsVector(pVector) ){
+ assert( pVector->op2==0 || pVector->op==TK_REGISTER );
+ if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){
assert( ExprUseXSelect(pVector) );
- return pVector->x.pSelect->pEList->a[i].pExpr;
- }else{
+ return pVector->x.pSelect->pEList->a[i].pExpr;
+ }else{
assert( ExprUseXList(pVector) );
- return pVector->x.pList->a[i].pExpr;
- }
- }
- return pVector;
-}
-
-/*
-** Compute and return a new Expr object which when passed to
-** sqlite3ExprCode() will generate all necessary code to compute
-** the iField-th column of the vector expression pVector.
-**
+ return pVector->x.pList->a[i].pExpr;
+ }
+ }
+ return pVector;
+}
+
+/*
+** Compute and return a new Expr object which when passed to
+** sqlite3ExprCode() will generate all necessary code to compute
+** the iField-th column of the vector expression pVector.
+**
** It is ok for pVector to be a scalar (as long as iField==0).
-** In that case, this routine works like sqlite3ExprDup().
-**
-** The caller owns the returned Expr object and is responsible for
-** ensuring that the returned value eventually gets freed.
-**
-** The caller retains ownership of pVector. If pVector is a TK_SELECT,
-** then the returned object will reference pVector and so pVector must remain
-** valid for the life of the returned object. If pVector is a TK_VECTOR
-** or a scalar expression, then it can be deleted as soon as this routine
-** returns.
-**
-** A trick to cause a TK_SELECT pVector to be deleted together with
-** the returned Expr object is to attach the pVector to the pRight field
-** of the returned TK_SELECT_COLUMN Expr object.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(
- Parse *pParse, /* Parsing context */
- Expr *pVector, /* The vector. List of expressions or a sub-SELECT */
+** In that case, this routine works like sqlite3ExprDup().
+**
+** The caller owns the returned Expr object and is responsible for
+** ensuring that the returned value eventually gets freed.
+**
+** The caller retains ownership of pVector. If pVector is a TK_SELECT,
+** then the returned object will reference pVector and so pVector must remain
+** valid for the life of the returned object. If pVector is a TK_VECTOR
+** or a scalar expression, then it can be deleted as soon as this routine
+** returns.
+**
+** A trick to cause a TK_SELECT pVector to be deleted together with
+** the returned Expr object is to attach the pVector to the pRight field
+** of the returned TK_SELECT_COLUMN Expr object.
+*/
+SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(
+ Parse *pParse, /* Parsing context */
+ Expr *pVector, /* The vector. List of expressions or a sub-SELECT */
int iField, /* Which column of the vector to return */
int nField /* Total number of columns in the vector */
-){
- Expr *pRet;
- if( pVector->op==TK_SELECT ){
+){
+ Expr *pRet;
+ if( pVector->op==TK_SELECT ){
assert( ExprUseXSelect(pVector) );
- /* The TK_SELECT_COLUMN Expr node:
- **
- ** pLeft: pVector containing TK_SELECT. Not deleted.
- ** pRight: not used. But recursively deleted.
- ** iColumn: Index of a column in pVector
- ** iTable: 0 or the number of columns on the LHS of an assignment
- ** pLeft->iTable: First in an array of register holding result, or 0
- ** if the result is not yet computed.
- **
- ** sqlite3ExprDelete() specifically skips the recursive delete of
- ** pLeft on TK_SELECT_COLUMN nodes. But pRight is followed, so pVector
- ** can be attached to pRight to cause this node to take ownership of
- ** pVector. Typically there will be multiple TK_SELECT_COLUMN nodes
- ** with the same pLeft pointer to the pVector, but only one of them
- ** will own the pVector.
- */
- pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0);
- if( pRet ){
+ /* The TK_SELECT_COLUMN Expr node:
+ **
+ ** pLeft: pVector containing TK_SELECT. Not deleted.
+ ** pRight: not used. But recursively deleted.
+ ** iColumn: Index of a column in pVector
+ ** iTable: 0 or the number of columns on the LHS of an assignment
+ ** pLeft->iTable: First in an array of register holding result, or 0
+ ** if the result is not yet computed.
+ **
+ ** sqlite3ExprDelete() specifically skips the recursive delete of
+ ** pLeft on TK_SELECT_COLUMN nodes. But pRight is followed, so pVector
+ ** can be attached to pRight to cause this node to take ownership of
+ ** pVector. Typically there will be multiple TK_SELECT_COLUMN nodes
+ ** with the same pLeft pointer to the pVector, but only one of them
+ ** will own the pVector.
+ */
+ pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0);
+ if( pRet ){
pRet->iTable = nField;
- pRet->iColumn = iField;
- pRet->pLeft = pVector;
- }
- }else{
+ pRet->iColumn = iField;
+ pRet->pLeft = pVector;
+ }
+ }else{
if( pVector->op==TK_VECTOR ){
Expr **ppVector;
assert( ExprUseXList(pVector) );
@@ -102176,146 +102176,146 @@ SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(
return pVector;
}
}
- pRet = sqlite3ExprDup(pParse->db, pVector, 0);
- }
- return pRet;
-}
-
-/*
-** If expression pExpr is of type TK_SELECT, generate code to evaluate
+ pRet = sqlite3ExprDup(pParse->db, pVector, 0);
+ }
+ return pRet;
+}
+
+/*
+** If expression pExpr is of type TK_SELECT, generate code to evaluate
** it. Return the register in which the result is stored (or, if the
-** sub-select returns more than one column, the first in an array
-** of registers in which the result is stored).
-**
-** If pExpr is not a TK_SELECT expression, return 0.
-*/
-static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
- int reg = 0;
-#ifndef SQLITE_OMIT_SUBQUERY
- if( pExpr->op==TK_SELECT ){
+** sub-select returns more than one column, the first in an array
+** of registers in which the result is stored).
+**
+** If pExpr is not a TK_SELECT expression, return 0.
+*/
+static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
+ int reg = 0;
+#ifndef SQLITE_OMIT_SUBQUERY
+ if( pExpr->op==TK_SELECT ){
reg = sqlite3CodeSubselect(pParse, pExpr);
- }
-#endif
- return reg;
-}
-
-/*
-** Argument pVector points to a vector expression - either a TK_VECTOR
-** or TK_SELECT that returns more than one column. This function returns
-** the register number of a register that contains the value of
-** element iField of the vector.
-**
+ }
+#endif
+ return reg;
+}
+
+/*
+** Argument pVector points to a vector expression - either a TK_VECTOR
+** or TK_SELECT that returns more than one column. This function returns
+** the register number of a register that contains the value of
+** element iField of the vector.
+**
** If pVector is a TK_SELECT expression, then code for it must have
-** already been generated using the exprCodeSubselect() routine. In this
-** case parameter regSelect should be the first in an array of registers
+** already been generated using the exprCodeSubselect() routine. In this
+** case parameter regSelect should be the first in an array of registers
** containing the results of the sub-select.
-**
-** If pVector is of type TK_VECTOR, then code for the requested field
-** is generated. In this case (*pRegFree) may be set to the number of
-** a temporary register to be freed by the caller before returning.
-**
-** Before returning, output parameter (*ppExpr) is set to point to the
-** Expr object corresponding to element iElem of the vector.
-*/
-static int exprVectorRegister(
- Parse *pParse, /* Parse context */
- Expr *pVector, /* Vector to extract element from */
- int iField, /* Field to extract from pVector */
- int regSelect, /* First in array of registers */
- Expr **ppExpr, /* OUT: Expression element */
- int *pRegFree /* OUT: Temp register to free */
-){
- u8 op = pVector->op;
+**
+** If pVector is of type TK_VECTOR, then code for the requested field
+** is generated. In this case (*pRegFree) may be set to the number of
+** a temporary register to be freed by the caller before returning.
+**
+** Before returning, output parameter (*ppExpr) is set to point to the
+** Expr object corresponding to element iElem of the vector.
+*/
+static int exprVectorRegister(
+ Parse *pParse, /* Parse context */
+ Expr *pVector, /* Vector to extract element from */
+ int iField, /* Field to extract from pVector */
+ int regSelect, /* First in array of registers */
+ Expr **ppExpr, /* OUT: Expression element */
+ int *pRegFree /* OUT: Temp register to free */
+){
+ u8 op = pVector->op;
assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT || op==TK_ERROR );
- if( op==TK_REGISTER ){
- *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField);
- return pVector->iTable+iField;
- }
- if( op==TK_SELECT ){
+ if( op==TK_REGISTER ){
+ *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField);
+ return pVector->iTable+iField;
+ }
+ if( op==TK_SELECT ){
assert( ExprUseXSelect(pVector) );
- *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
- return regSelect+iField;
- }
+ *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
+ return regSelect+iField;
+ }
if( op==TK_VECTOR ){
assert( ExprUseXList(pVector) );
*ppExpr = pVector->x.pList->a[iField].pExpr;
return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
}
return 0;
-}
-
-/*
-** Expression pExpr is a comparison between two vector values. Compute
-** the result of the comparison (1, 0, or NULL) and write that
-** result into register dest.
-**
-** The caller must satisfy the following preconditions:
-**
-** if pExpr->op==TK_IS: op==TK_EQ and p5==SQLITE_NULLEQ
-** if pExpr->op==TK_ISNOT: op==TK_NE and p5==SQLITE_NULLEQ
-** otherwise: op==pExpr->op and p5==0
-*/
-static void codeVectorCompare(
- Parse *pParse, /* Code generator context */
- Expr *pExpr, /* The comparison operation */
- int dest, /* Write results into this register */
- u8 op, /* Comparison operator */
- u8 p5 /* SQLITE_NULLEQ or zero */
-){
- Vdbe *v = pParse->pVdbe;
- Expr *pLeft = pExpr->pLeft;
- Expr *pRight = pExpr->pRight;
- int nLeft = sqlite3ExprVectorSize(pLeft);
- int i;
- int regLeft = 0;
- int regRight = 0;
- u8 opx = op;
+}
+
+/*
+** Expression pExpr is a comparison between two vector values. Compute
+** the result of the comparison (1, 0, or NULL) and write that
+** result into register dest.
+**
+** The caller must satisfy the following preconditions:
+**
+** if pExpr->op==TK_IS: op==TK_EQ and p5==SQLITE_NULLEQ
+** if pExpr->op==TK_ISNOT: op==TK_NE and p5==SQLITE_NULLEQ
+** otherwise: op==pExpr->op and p5==0
+*/
+static void codeVectorCompare(
+ Parse *pParse, /* Code generator context */
+ Expr *pExpr, /* The comparison operation */
+ int dest, /* Write results into this register */
+ u8 op, /* Comparison operator */
+ u8 p5 /* SQLITE_NULLEQ or zero */
+){
+ Vdbe *v = pParse->pVdbe;
+ Expr *pLeft = pExpr->pLeft;
+ Expr *pRight = pExpr->pRight;
+ int nLeft = sqlite3ExprVectorSize(pLeft);
+ int i;
+ int regLeft = 0;
+ int regRight = 0;
+ u8 opx = op;
int addrCmp = 0;
int addrDone = sqlite3VdbeMakeLabel(pParse);
int isCommuted = ExprHasProperty(pExpr,EP_Commuted);
-
+
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
if( pParse->nErr ) return;
- if( nLeft!=sqlite3ExprVectorSize(pRight) ){
- sqlite3ErrorMsg(pParse, "row value misused");
- return;
- }
+ if( nLeft!=sqlite3ExprVectorSize(pRight) ){
+ sqlite3ErrorMsg(pParse, "row value misused");
+ return;
+ }
assert( pExpr->op==TK_EQ || pExpr->op==TK_NE
|| pExpr->op==TK_IS || pExpr->op==TK_ISNOT
|| pExpr->op==TK_LT || pExpr->op==TK_GT
|| pExpr->op==TK_LE || pExpr->op==TK_GE
- );
- assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ)
- || (pExpr->op==TK_ISNOT && op==TK_NE) );
- assert( p5==0 || pExpr->op!=op );
- assert( p5==SQLITE_NULLEQ || pExpr->op==op );
-
+ );
+ assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ)
+ || (pExpr->op==TK_ISNOT && op==TK_NE) );
+ assert( p5==0 || pExpr->op!=op );
+ assert( p5==SQLITE_NULLEQ || pExpr->op==op );
+
if( op==TK_LE ) opx = TK_LT;
if( op==TK_GE ) opx = TK_GT;
if( op==TK_NE ) opx = TK_EQ;
-
- regLeft = exprCodeSubselect(pParse, pLeft);
- regRight = exprCodeSubselect(pParse, pRight);
-
+
+ regLeft = exprCodeSubselect(pParse, pLeft);
+ regRight = exprCodeSubselect(pParse, pRight);
+
sqlite3VdbeAddOp2(v, OP_Integer, 1, dest);
- for(i=0; 1 /*Loop exits by "break"*/; i++){
- int regFree1 = 0, regFree2 = 0;
+ for(i=0; 1 /*Loop exits by "break"*/; i++){
+ int regFree1 = 0, regFree2 = 0;
Expr *pL = 0, *pR = 0;
- int r1, r2;
- assert( i>=0 && i<nLeft );
+ int r1, r2;
+ assert( i>=0 && i<nLeft );
if( addrCmp ) sqlite3VdbeJumpHere(v, addrCmp);
- r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, &regFree1);
- r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, &regFree2);
+ r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, &regFree1);
+ r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, &regFree2);
addrCmp = sqlite3VdbeCurrentAddr(v);
codeCompare(pParse, pL, pR, opx, r1, r2, addrDone, p5, isCommuted);
- testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
- testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
- testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
- testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
- testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
- testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
- sqlite3ReleaseTempReg(pParse, regFree1);
- sqlite3ReleaseTempReg(pParse, regFree2);
+ testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
+ testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
+ testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
+ testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+ testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+ testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
+ sqlite3ReleaseTempReg(pParse, regFree1);
+ sqlite3ReleaseTempReg(pParse, regFree2);
if( (opx==TK_LT || opx==TK_GT) && i<nLeft-1 ){
addrCmp = sqlite3VdbeAddOp0(v, OP_ElseEq);
testcase(opx==TK_LT); VdbeCoverageIf(v,opx==TK_LT);
@@ -102326,24 +102326,24 @@ static void codeVectorCompare(
}else{
sqlite3VdbeAddOp3(v, OP_ZeroOrNull, r1, dest, r2);
}
- if( i==nLeft-1 ){
- break;
- }
- if( opx==TK_EQ ){
+ if( i==nLeft-1 ){
+ break;
+ }
+ if( opx==TK_EQ ){
sqlite3VdbeAddOp2(v, OP_NotNull, dest, addrDone); VdbeCoverage(v);
- }else{
- assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE );
+ }else{
+ assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE );
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrDone);
- if( i==nLeft-2 ) opx = op;
- }
- }
+ if( i==nLeft-2 ) opx = op;
+ }
+ }
sqlite3VdbeJumpHere(v, addrCmp);
- sqlite3VdbeResolveLabel(v, addrDone);
+ sqlite3VdbeResolveLabel(v, addrDone);
if( op==TK_NE ){
sqlite3VdbeAddOp2(v, OP_Not, dest, dest);
}
-}
-
+}
+
#if SQLITE_MAX_EXPR_DEPTH>0
/*
** Check that argument nHeight is less than or equal to the maximum
@@ -102388,7 +102388,7 @@ static void heightOfExprList(const ExprList *p, int *pnHeight){
}
static void heightOfSelect(const Select *pSelect, int *pnHeight){
const Select *p;
- for(p=pSelect; p; p=p->pPrior){
+ for(p=pSelect; p; p=p->pPrior){
heightOfExpr(p->pWhere, pnHeight);
heightOfExpr(p->pHaving, pnHeight);
heightOfExpr(p->pLimit, pnHeight);
@@ -102467,7 +102467,7 @@ SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
** is responsible for making sure the node eventually gets freed.
**
** If dequote is true, then the token (if it exists) is dequoted.
-** If dequote is false, no dequoting is performed. The deQuote
+** If dequote is false, no dequoting is performed. The deQuote
** parameter is ignored if pToken is NULL or if the token does not
** appear to be quoted. If the quotes were of the form "..." (double-quotes)
** then the EP_DblQuoted flag is set on the expression node.
@@ -102479,7 +102479,7 @@ SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
** is allocated to hold the integer text and the dequote flag is ignored.
*/
SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
- sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */
+ sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */
int op, /* Expression opcode */
const Token *pToken, /* Token argument. Might be NULL */
int dequote /* True to dequote */
@@ -102488,7 +102488,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
int nExtra = 0;
int iValue = 0;
- assert( db!=0 );
+ assert( db!=0 );
if( pToken ){
if( op!=TK_INTEGER || pToken->z==0
|| sqlite3GetInt32(pToken->z, &iValue)==0 ){
@@ -102496,9 +102496,9 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
assert( iValue>=0 );
}
}
- pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra);
+ pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra);
if( pNew ){
- memset(pNew, 0, sizeof(Expr));
+ memset(pNew, 0, sizeof(Expr));
pNew->op = (u8)op;
pNew->iAgg = -1;
if( pToken ){
@@ -102510,7 +102510,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
assert( pToken->z!=0 || pToken->n==0 );
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
pNew->u.zToken[pToken->n] = 0;
- if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
+ if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
sqlite3DequoteExpr(pNew);
}
}
@@ -102533,7 +102533,7 @@ SQLITE_PRIVATE Expr *sqlite3Expr(
){
Token x;
x.z = zToken;
- x.n = sqlite3Strlen30(zToken);
+ x.n = sqlite3Strlen30(zToken);
return sqlite3ExprAlloc(db, op, &x, 0);
}
@@ -102577,7 +102577,7 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
Parse *pParse, /* Parsing context */
int op, /* Expression opcode */
Expr *pLeft, /* Left operand */
- Expr *pRight /* Right operand */
+ Expr *pRight /* Right operand */
){
Expr *p;
p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
@@ -102595,20 +102595,20 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
}
/*
-** Add pSelect to the Expr.x.pSelect field. Or, if pExpr is NULL (due
-** do a memory allocation failure) then delete the pSelect object.
-*/
-SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
- if( pExpr ){
- pExpr->x.pSelect = pSelect;
- ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery);
- sqlite3ExprSetHeightAndFlags(pParse, pExpr);
- }else{
- assert( pParse->db->mallocFailed );
- sqlite3SelectDelete(pParse->db, pSelect);
- }
-}
-
+** Add pSelect to the Expr.x.pSelect field. Or, if pExpr is NULL (due
+** do a memory allocation failure) then delete the pSelect object.
+*/
+SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
+ if( pExpr ){
+ pExpr->x.pSelect = pSelect;
+ ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery);
+ sqlite3ExprSetHeightAndFlags(pParse, pExpr);
+ }else{
+ assert( pParse->db->mallocFailed );
+ sqlite3SelectDelete(pParse->db, pSelect);
+ }
+}
+
/*
** Expression list pEList is a list of vector values. This function
** converts the contents of pEList to a VALUES(...) Select statement
@@ -102659,7 +102659,7 @@ SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprLis
pRet = pSel;
}
}
-
+
if( pRet && pRet->pPrior ){
pRet->selFlags |= SF_MultiValue;
}
@@ -102667,7 +102667,7 @@ SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprLis
return pRet;
}
-/*
+/*
** Join two expressions using an AND operator. If either expression is
** NULL, then just return the other expression.
**
@@ -102717,7 +102717,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(
sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
}
pNew->x.pList = pList;
- ExprSetProperty(pNew, EP_HasFunc);
+ ExprSetProperty(pNew, EP_HasFunc);
assert( ExprUseXList(pNew) );
sqlite3ExprSetHeightAndFlags(pParse, pNew);
if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
@@ -102766,7 +102766,7 @@ SQLITE_PRIVATE void sqlite3ExprFunctionUsable(
** variable number.
**
** Wildcards of the form "?nnn" are assigned the number "nnn". We make
-** sure "nnn" is not too big to avoid a denial of service attack when
+** sure "nnn" is not too big to avoid a denial of service attack when
** the SQL statement comes from an external source.
**
** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
@@ -102774,34 +102774,34 @@ SQLITE_PRIVATE void sqlite3ExprFunctionUsable(
** instance of the wildcard, the next sequential variable number is
** assigned.
*/
-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
+SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
sqlite3 *db = pParse->db;
const char *z;
- ynVar x;
+ ynVar x;
if( pExpr==0 ) return;
assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
z = pExpr->u.zToken;
assert( z!=0 );
assert( z[0]!=0 );
- assert( n==(u32)sqlite3Strlen30(z) );
+ assert( n==(u32)sqlite3Strlen30(z) );
if( z[1]==0 ){
/* Wildcard of the form "?". Assign the next variable number */
assert( z[0]=='?' );
- x = (ynVar)(++pParse->nVar);
+ x = (ynVar)(++pParse->nVar);
}else{
- int doAdd = 0;
+ int doAdd = 0;
if( z[0]=='?' ){
/* Wildcard of the form "?nnn". Convert "nnn" to an integer and
** use it as the variable number */
i64 i;
- int bOk;
- if( n==2 ){ /*OPTIMIZATION-IF-TRUE*/
- i = z[1]-'0'; /* The common case of ?N for a single digit N */
- bOk = 1;
- }else{
- bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
- }
+ int bOk;
+ if( n==2 ){ /*OPTIMIZATION-IF-TRUE*/
+ i = z[1]-'0'; /* The common case of ?N for a single digit N */
+ bOk = 1;
+ }else{
+ bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
+ }
testcase( i==0 );
testcase( i==1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
@@ -102809,32 +102809,32 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n
if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
- return;
+ return;
}
- x = (ynVar)i;
- if( x>pParse->nVar ){
- pParse->nVar = (int)x;
- doAdd = 1;
- }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){
- doAdd = 1;
+ x = (ynVar)i;
+ if( x>pParse->nVar ){
+ pParse->nVar = (int)x;
+ doAdd = 1;
+ }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){
+ doAdd = 1;
}
}else{
/* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable
** number as the prior appearance of the same name, or if the name
** has never appeared before, reuse the same variable number
*/
- x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n);
- if( x==0 ){
- x = (ynVar)(++pParse->nVar);
- doAdd = 1;
+ x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n);
+ if( x==0 ){
+ x = (ynVar)(++pParse->nVar);
+ doAdd = 1;
}
}
- if( doAdd ){
- pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x);
+ if( doAdd ){
+ pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x);
}
- }
- pExpr->iColumn = x;
- if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
+ }
+ pExpr->iColumn = x;
+ if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
sqlite3ErrorMsg(pParse, "too many SQL variables");
}
}
@@ -102842,27 +102842,27 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n
/*
** Recursively delete an expression tree.
*/
-static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
- assert( p!=0 );
+static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
+ assert( p!=0 );
assert( !ExprUseUValue(p) || p->u.iValue>=0 );
assert( !ExprUseYWin(p) || !ExprUseYSub(p) );
assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed );
assert( p->op!=TK_FUNCTION || !ExprUseYSub(p) );
-#ifdef SQLITE_DEBUG
- if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
- assert( p->pLeft==0 );
- assert( p->pRight==0 );
+#ifdef SQLITE_DEBUG
+ if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
+ assert( p->pLeft==0 );
+ assert( p->pRight==0 );
assert( !ExprUseXSelect(p) || p->x.pSelect==0 );
assert( !ExprUseXList(p) || p->x.pList==0 );
- }
-#endif
- if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
+ }
+#endif
+ if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
/* The Expr.x union is never used at the same time as Expr.pRight */
assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 );
- if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
- if( p->pRight ){
+ if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
+ if( p->pRight ){
assert( !ExprHasProperty(p, EP_WinFunc) );
- sqlite3ExprDeleteNN(db, p->pRight);
+ sqlite3ExprDeleteNN(db, p->pRight);
}else if( ExprUseXSelect(p) ){
assert( !ExprHasProperty(p, EP_WinFunc) );
sqlite3SelectDelete(db, p->x.pSelect);
@@ -102880,12 +102880,12 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
sqlite3DbFree(db, p->u.zToken);
}
if( !ExprHasProperty(p, EP_Static) ){
- sqlite3DbFreeNN(db, p);
+ sqlite3DbFreeNN(db, p);
}
}
-SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
- if( p ) sqlite3ExprDeleteNN(db, p);
-}
+SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
+ if( p ) sqlite3ExprDeleteNN(db, p);
+}
/*
@@ -103032,103 +103032,103 @@ static int dupedExprSize(const Expr *p, int flags){
** portion of the buffer copied into by this function.
*/
static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){
- Expr *pNew; /* Value to return */
- u8 *zAlloc; /* Memory space from which to build Expr object */
- u32 staticFlag; /* EP_Static if space not obtained from malloc */
-
- assert( db!=0 );
- assert( p );
- assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE );
- assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE );
-
- /* Figure out where to write the new Expr structure. */
- if( pzBuffer ){
- zAlloc = *pzBuffer;
- staticFlag = EP_Static;
+ Expr *pNew; /* Value to return */
+ u8 *zAlloc; /* Memory space from which to build Expr object */
+ u32 staticFlag; /* EP_Static if space not obtained from malloc */
+
+ assert( db!=0 );
+ assert( p );
+ assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE );
+ assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE );
+
+ /* Figure out where to write the new Expr structure. */
+ if( pzBuffer ){
+ zAlloc = *pzBuffer;
+ staticFlag = EP_Static;
assert( zAlloc!=0 );
- }else{
- zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags));
- staticFlag = 0;
- }
- pNew = (Expr *)zAlloc;
-
- if( pNew ){
- /* Set nNewSize to the size allocated for the structure pointed to
- ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
- ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
- ** by the copy of the p->u.zToken string (if any).
- */
- const unsigned nStructSize = dupedExprStructSize(p, dupFlags);
- const int nNewSize = nStructSize & 0xfff;
- int nToken;
- if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
- nToken = sqlite3Strlen30(p->u.zToken) + 1;
- }else{
- nToken = 0;
- }
- if( dupFlags ){
- assert( ExprHasProperty(p, EP_Reduced)==0 );
- memcpy(zAlloc, p, nNewSize);
- }else{
- u32 nSize = (u32)exprStructSize(p);
- memcpy(zAlloc, p, nSize);
+ }else{
+ zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags));
+ staticFlag = 0;
+ }
+ pNew = (Expr *)zAlloc;
+
+ if( pNew ){
+ /* Set nNewSize to the size allocated for the structure pointed to
+ ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
+ ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
+ ** by the copy of the p->u.zToken string (if any).
+ */
+ const unsigned nStructSize = dupedExprStructSize(p, dupFlags);
+ const int nNewSize = nStructSize & 0xfff;
+ int nToken;
+ if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+ nToken = sqlite3Strlen30(p->u.zToken) + 1;
+ }else{
+ nToken = 0;
+ }
+ if( dupFlags ){
+ assert( ExprHasProperty(p, EP_Reduced)==0 );
+ memcpy(zAlloc, p, nNewSize);
+ }else{
+ u32 nSize = (u32)exprStructSize(p);
+ memcpy(zAlloc, p, nSize);
if( nSize<EXPR_FULLSIZE ){
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
}
- }
+ }
- /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
- pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
- pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
- pNew->flags |= staticFlag;
+ /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
+ pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
+ pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
+ pNew->flags |= staticFlag;
ExprClearVVAProperties(pNew);
if( dupFlags ){
ExprSetVVAProperty(pNew, EP_Immutable);
}
- /* Copy the p->u.zToken string, if any. */
- if( nToken ){
- char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
- memcpy(zToken, p->u.zToken, nToken);
- }
-
- if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
- /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
+ /* Copy the p->u.zToken string, if any. */
+ if( nToken ){
+ char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
+ memcpy(zToken, p->u.zToken, nToken);
+ }
+
+ if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
+ /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprUseXSelect(p) ){
- pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
- }else{
- pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
+ pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
+ }else{
+ pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
}
- }
+ }
- /* Fill in pNew->pLeft and pNew->pRight. */
+ /* Fill in pNew->pLeft and pNew->pRight. */
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){
- zAlloc += dupedExprNodeSize(p, dupFlags);
- if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
- pNew->pLeft = p->pLeft ?
- exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
- pNew->pRight = p->pRight ?
- exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
- }
+ zAlloc += dupedExprNodeSize(p, dupFlags);
+ if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
+ pNew->pLeft = p->pLeft ?
+ exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
+ pNew->pRight = p->pRight ?
+ exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
+ }
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(p, EP_WinFunc) ){
pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin);
assert( ExprHasProperty(pNew, EP_WinFunc) );
}
#endif /* SQLITE_OMIT_WINDOWFUNC */
- if( pzBuffer ){
- *pzBuffer = zAlloc;
- }
- }else{
- if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
- if( pNew->op==TK_SELECT_COLUMN ){
- pNew->pLeft = p->pLeft;
+ if( pzBuffer ){
+ *pzBuffer = zAlloc;
+ }
+ }else{
+ if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
+ if( pNew->op==TK_SELECT_COLUMN ){
+ pNew->pLeft = p->pLeft;
assert( p->pRight==0 || p->pRight==p->pLeft
|| ExprHasProperty(p->pLeft, EP_Subquery) );
}else{
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
}
- pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
+ pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
}
}
@@ -103213,8 +103213,8 @@ static void gatherSelectWindows(Select *p){
** part of the in-memory representation of the database schema.
*/
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, const Expr *p, int flags){
- assert( flags==0 || flags==EXPRDUP_REDUCE );
- return p ? exprDup(db, p, flags, 0) : 0;
+ assert( flags==0 || flags==EXPRDUP_REDUCE );
+ return p ? exprDup(db, p, flags, 0) : 0;
}
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int flags){
ExprList *pNew;
@@ -103223,35 +103223,35 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int
int i;
Expr *pPriorSelectColOld = 0;
Expr *pPriorSelectColNew = 0;
- assert( db!=0 );
+ assert( db!=0 );
if( p==0 ) return 0;
- pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p));
+ pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p));
if( pNew==0 ) return 0;
- pNew->nExpr = p->nExpr;
+ pNew->nExpr = p->nExpr;
pNew->nAlloc = p->nAlloc;
- pItem = pNew->a;
+ pItem = pNew->a;
pOldItem = p->a;
for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
Expr *pOldExpr = pOldItem->pExpr;
- Expr *pNewExpr;
+ Expr *pNewExpr;
pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags);
if( pOldExpr
- && pOldExpr->op==TK_SELECT_COLUMN
+ && pOldExpr->op==TK_SELECT_COLUMN
&& (pNewExpr = pItem->pExpr)!=0
- ){
+ ){
if( pNewExpr->pRight ){
pPriorSelectColOld = pOldExpr->pRight;
pPriorSelectColNew = pNewExpr->pRight;
pNewExpr->pLeft = pNewExpr->pRight;
- }else{
+ }else{
if( pOldExpr->pLeft!=pPriorSelectColOld ){
pPriorSelectColOld = pOldExpr->pLeft;
pPriorSelectColNew = sqlite3ExprDup(db, pPriorSelectColOld, flags);
pNewExpr->pRight = pPriorSelectColNew;
}
pNewExpr->pLeft = pPriorSelectColNew;
- }
- }
+ }
+ }
pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
pItem->sortFlags = pOldItem->sortFlags;
pItem->eEName = pOldItem->eEName;
@@ -103275,10 +103275,10 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla
SrcList *pNew;
int i;
int nByte;
- assert( db!=0 );
+ assert( db!=0 );
if( p==0 ) return 0;
nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
- pNew = sqlite3DbMallocRawNN(db, nByte );
+ pNew = sqlite3DbMallocRawNN(db, nByte );
if( pNew==0 ) return 0;
pNew->nSrc = pNew->nAlloc = p->nSrc;
for(i=0; i<p->nSrc; i++){
@@ -103289,24 +103289,24 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla
pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
- pNewItem->fg = pOldItem->fg;
+ pNewItem->fg = pOldItem->fg;
pNewItem->iCursor = pOldItem->iCursor;
pNewItem->addrFillSub = pOldItem->addrFillSub;
pNewItem->regReturn = pOldItem->regReturn;
- if( pNewItem->fg.isIndexedBy ){
- pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
- }
+ if( pNewItem->fg.isIndexedBy ){
+ pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
+ }
pNewItem->u2 = pOldItem->u2;
if( pNewItem->fg.isCte ){
pNewItem->u2.pCteUse->nUse++;
}
- if( pNewItem->fg.isTabFunc ){
+ if( pNewItem->fg.isTabFunc ){
pNewItem->u1.pFuncArg =
- sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
- }
+ sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
+ }
pTab = pNewItem->pTab = pOldItem->pTab;
if( pTab ){
- pTab->nTabRef++;
+ pTab->nTabRef++;
}
pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags);
@@ -103318,14 +103318,14 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
IdList *pNew;
int i;
- assert( db!=0 );
+ assert( db!=0 );
if( p==0 ) return 0;
- pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
+ pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
if( pNew==0 ) return 0;
pNew->nId = p->nId;
- pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) );
+ pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) );
if( pNew->a==0 ){
- sqlite3DbFreeNN(db, pNew);
+ sqlite3DbFreeNN(db, pNew);
return 0;
}
/* Note that because the size of the allocation for p->a[] is not
@@ -103340,31 +103340,31 @@ SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
return pNew;
}
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
- Select *pRet = 0;
- Select *pNext = 0;
- Select **pp = &pRet;
+ Select *pRet = 0;
+ Select *pNext = 0;
+ Select **pp = &pRet;
const Select *p;
-
- assert( db!=0 );
- for(p=pDup; p; p=p->pPrior){
- Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) );
- if( pNew==0 ) break;
- pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
- pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
- pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
- pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
- pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
- pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
- pNew->op = p->op;
- pNew->pNext = pNext;
- pNew->pPrior = 0;
- pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
- pNew->iLimit = 0;
- pNew->iOffset = 0;
- pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
- pNew->addrOpenEphm[0] = -1;
- pNew->addrOpenEphm[1] = -1;
- pNew->nSelectRow = p->nSelectRow;
+
+ assert( db!=0 );
+ for(p=pDup; p; p=p->pPrior){
+ Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) );
+ if( pNew==0 ) break;
+ pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
+ pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
+ pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
+ pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
+ pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
+ pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
+ pNew->op = p->op;
+ pNew->pNext = pNext;
+ pNew->pPrior = 0;
+ pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
+ pNew->iLimit = 0;
+ pNew->iOffset = 0;
+ pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
+ pNew->addrOpenEphm[0] = -1;
+ pNew->addrOpenEphm[1] = -1;
+ pNew->nSelectRow = p->nSelectRow;
pNew->pWith = sqlite3WithDup(db, p->pWith);
#ifndef SQLITE_OMIT_WINDOWFUNC
pNew->pWin = 0;
@@ -103380,12 +103380,12 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int fla
sqlite3SelectDelete(db, pNew);
break;
}
- *pp = pNew;
- pp = &pNew->pPrior;
- pNext = pNew;
- }
-
- return pRet;
+ *pp = pNew;
+ pp = &pNew->pPrior;
+ pNext = pNew;
+ }
+
+ return pRet;
}
#else
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){
@@ -103399,13 +103399,13 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags)
** Add a new element to the end of an expression list. If pList is
** initially NULL, then create a new expression list.
**
-** The pList argument must be either NULL or a pointer to an ExprList
-** obtained from a prior call to sqlite3ExprListAppend(). This routine
-** may not be used with an ExprList obtained from sqlite3ExprListDup().
-** Reason: This routine assumes that the number of slots in pList->a[]
-** is a power of two. That is true for sqlite3ExprListAppend() returns
-** but is not necessarily true from the return value of sqlite3ExprListDup().
-**
+** The pList argument must be either NULL or a pointer to an ExprList
+** obtained from a prior call to sqlite3ExprListAppend(). This routine
+** may not be used with an ExprList obtained from sqlite3ExprListDup().
+** Reason: This routine assumes that the number of slots in pList->a[]
+** is a power of two. That is true for sqlite3ExprListAppend() returns
+** but is not necessarily true from the return value of sqlite3ExprListDup().
+**
** If a memory allocation error occurs, the entire list is freed and
** NULL is returned. If non-NULL is returned, then it is guaranteed
** that the new entry was successfully appended.
@@ -103457,96 +103457,96 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
ExprList *pList, /* List to which to append. Might be NULL */
Expr *pExpr /* Expression to be appended. Might be NULL */
){
- struct ExprList_item *pItem;
+ struct ExprList_item *pItem;
if( pList==0 ){
return sqlite3ExprListAppendNew(pParse->db,pExpr);
}
if( pList->nAlloc<pList->nExpr+1 ){
return sqlite3ExprListAppendGrow(pParse->db,pList,pExpr);
}
- pItem = &pList->a[pList->nExpr++];
+ pItem = &pList->a[pList->nExpr++];
*pItem = zeroItem;
- pItem->pExpr = pExpr;
+ pItem->pExpr = pExpr;
return pList;
}
/*
-** pColumns and pExpr form a vector assignment which is part of the SET
-** clause of an UPDATE statement. Like this:
-**
-** (a,b,c) = (expr1,expr2,expr3)
-** Or: (a,b,c) = (SELECT x,y,z FROM ....)
-**
-** For each term of the vector assignment, append new entries to the
-** expression list pList. In the case of a subquery on the RHS, append
-** TK_SELECT_COLUMN expressions.
-*/
-SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* List to which to append. Might be NULL */
- IdList *pColumns, /* List of names of LHS of the assignment */
- Expr *pExpr /* Vector expression to be appended. Might be NULL */
-){
- sqlite3 *db = pParse->db;
- int n;
- int i;
- int iFirst = pList ? pList->nExpr : 0;
- /* pColumns can only be NULL due to an OOM but an OOM will cause an
- ** exit prior to this routine being invoked */
- if( NEVER(pColumns==0) ) goto vector_append_error;
- if( pExpr==0 ) goto vector_append_error;
-
+** pColumns and pExpr form a vector assignment which is part of the SET
+** clause of an UPDATE statement. Like this:
+**
+** (a,b,c) = (expr1,expr2,expr3)
+** Or: (a,b,c) = (SELECT x,y,z FROM ....)
+**
+** For each term of the vector assignment, append new entries to the
+** expression list pList. In the case of a subquery on the RHS, append
+** TK_SELECT_COLUMN expressions.
+*/
+SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* List to which to append. Might be NULL */
+ IdList *pColumns, /* List of names of LHS of the assignment */
+ Expr *pExpr /* Vector expression to be appended. Might be NULL */
+){
+ sqlite3 *db = pParse->db;
+ int n;
+ int i;
+ int iFirst = pList ? pList->nExpr : 0;
+ /* pColumns can only be NULL due to an OOM but an OOM will cause an
+ ** exit prior to this routine being invoked */
+ if( NEVER(pColumns==0) ) goto vector_append_error;
+ if( pExpr==0 ) goto vector_append_error;
+
/* If the RHS is a vector, then we can immediately check to see that
** the size of the RHS and LHS match. But if the RHS is a SELECT,
- ** wildcards ("*") in the result set of the SELECT must be expanded before
- ** we can do the size check, so defer the size check until code generation.
- */
- if( pExpr->op!=TK_SELECT && pColumns->nId!=(n=sqlite3ExprVectorSize(pExpr)) ){
- sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
- pColumns->nId, n);
- goto vector_append_error;
- }
-
- for(i=0; i<pColumns->nId; i++){
+ ** wildcards ("*") in the result set of the SELECT must be expanded before
+ ** we can do the size check, so defer the size check until code generation.
+ */
+ if( pExpr->op!=TK_SELECT && pColumns->nId!=(n=sqlite3ExprVectorSize(pExpr)) ){
+ sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
+ pColumns->nId, n);
+ goto vector_append_error;
+ }
+
+ for(i=0; i<pColumns->nId; i++){
Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i, pColumns->nId);
assert( pSubExpr!=0 || db->mallocFailed );
if( pSubExpr==0 ) continue;
- pList = sqlite3ExprListAppend(pParse, pList, pSubExpr);
- if( pList ){
- assert( pList->nExpr==iFirst+i+1 );
+ pList = sqlite3ExprListAppend(pParse, pList, pSubExpr);
+ if( pList ){
+ assert( pList->nExpr==iFirst+i+1 );
pList->a[pList->nExpr-1].zEName = pColumns->a[i].zName;
- pColumns->a[i].zName = 0;
- }
- }
-
- if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){
- Expr *pFirst = pList->a[iFirst].pExpr;
- assert( pFirst!=0 );
- assert( pFirst->op==TK_SELECT_COLUMN );
-
- /* Store the SELECT statement in pRight so it will be deleted when
- ** sqlite3ExprListDelete() is called */
- pFirst->pRight = pExpr;
- pExpr = 0;
-
- /* Remember the size of the LHS in iTable so that we can check that
- ** the RHS and LHS sizes match during code generation. */
- pFirst->iTable = pColumns->nId;
- }
-
-vector_append_error:
+ pColumns->a[i].zName = 0;
+ }
+ }
+
+ if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){
+ Expr *pFirst = pList->a[iFirst].pExpr;
+ assert( pFirst!=0 );
+ assert( pFirst->op==TK_SELECT_COLUMN );
+
+ /* Store the SELECT statement in pRight so it will be deleted when
+ ** sqlite3ExprListDelete() is called */
+ pFirst->pRight = pExpr;
+ pExpr = 0;
+
+ /* Remember the size of the LHS in iTable so that we can check that
+ ** the RHS and LHS sizes match during code generation. */
+ pFirst->iTable = pColumns->nId;
+ }
+
+vector_append_error:
sqlite3ExprUnmapAndDelete(pParse, pExpr);
- sqlite3IdListDelete(db, pColumns);
- return pList;
-}
-
-/*
-** Set the sort order for the last element on the given ExprList.
-*/
+ sqlite3IdListDelete(db, pColumns);
+ return pList;
+}
+
+/*
+** Set the sort order for the last element on the given ExprList.
+*/
SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){
struct ExprList_item *pItem;
- if( p==0 ) return;
- assert( p->nExpr>0 );
+ if( p==0 ) return;
+ assert( p->nExpr>0 );
assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC==0 && SQLITE_SO_DESC>0 );
assert( iSortOrder==SQLITE_SO_UNDEFINED
@@ -103562,7 +103562,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int
assert( pItem->bNulls==0 );
if( iSortOrder==SQLITE_SO_UNDEFINED ){
iSortOrder = SQLITE_SO_ASC;
- }
+ }
pItem->sortFlags = (u8)iSortOrder;
if( eNulls!=SQLITE_SO_UNDEFINED ){
@@ -103571,9 +103571,9 @@ SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int
pItem->sortFlags |= KEYINFO_ORDER_BIGNULL;
}
}
-}
-
-/*
+}
+
+/*
** Set the ExprList.a[].zEName element of the most recently added item
** on the expression list.
**
@@ -103619,8 +103619,8 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(
SQLITE_PRIVATE void sqlite3ExprListSetSpan(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to add the span. */
- const char *zStart, /* Start of the span */
- const char *zEnd /* End of the span */
+ const char *zStart, /* Start of the span */
+ const char *zEnd /* End of the span */
){
sqlite3 *db = pParse->db;
assert( pList!=0 || db->mallocFailed!=0 );
@@ -103654,20 +103654,20 @@ SQLITE_PRIVATE void sqlite3ExprListCheckLength(
/*
** Delete an entire expression list.
*/
-static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
- int i = pList->nExpr;
- struct ExprList_item *pItem = pList->a;
- assert( pList->nExpr>0 );
- do{
+static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
+ int i = pList->nExpr;
+ struct ExprList_item *pItem = pList->a;
+ assert( pList->nExpr>0 );
+ do{
sqlite3ExprDelete(db, pItem->pExpr);
sqlite3DbFree(db, pItem->zEName);
- pItem++;
- }while( --i>0 );
- sqlite3DbFreeNN(db, pList);
+ pItem++;
+ }while( --i>0 );
+ sqlite3DbFreeNN(db, pList);
+}
+SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
+ if( pList ) exprListDeleteNN(db, pList);
}
-SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
- if( pList ) exprListDeleteNN(db, pList);
-}
/*
** Return the bitwise-OR of all Expr.flags fields in the given
@@ -103676,29 +103676,29 @@ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){
int i;
u32 m = 0;
- assert( pList!=0 );
- for(i=0; i<pList->nExpr; i++){
- Expr *pExpr = pList->a[i].pExpr;
- assert( pExpr!=0 );
- m |= pExpr->flags;
+ assert( pList!=0 );
+ for(i=0; i<pList->nExpr; i++){
+ Expr *pExpr = pList->a[i].pExpr;
+ assert( pExpr!=0 );
+ m |= pExpr->flags;
}
return m;
}
/*
-** This is a SELECT-node callback for the expression walker that
-** always "fails". By "fail" in this case, we mean set
-** pWalker->eCode to zero and abort.
-**
-** This callback is used by multiple expression walkers.
-*/
-SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- pWalker->eCode = 0;
- return WRC_Abort;
-}
-
-/*
+** This is a SELECT-node callback for the expression walker that
+** always "fails". By "fail" in this case, we mean set
+** pWalker->eCode to zero and abort.
+**
+** This callback is used by multiple expression walkers.
+*/
+SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
+ UNUSED_PARAMETER(NotUsed);
+ pWalker->eCode = 0;
+ return WRC_Abort;
+}
+
+/*
** Check the input string to see if it is "true" or "false" (in any case).
**
** If the string is.... Return
@@ -103843,14 +103843,14 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
return WRC_Continue;
}
/* no break */ deliberate_fall_through
- case TK_IF_NULL_ROW:
+ case TK_IF_NULL_ROW:
case TK_REGISTER:
case TK_DOT:
testcase( pExpr->op==TK_REGISTER );
- testcase( pExpr->op==TK_IF_NULL_ROW );
+ testcase( pExpr->op==TK_IF_NULL_ROW );
testcase( pExpr->op==TK_DOT );
- pWalker->eCode = 0;
- return WRC_Abort;
+ pWalker->eCode = 0;
+ return WRC_Abort;
case TK_VARIABLE:
if( pWalker->eCode==5 ){
/* Silently convert bound parameters that appear inside of CREATE
@@ -103874,10 +103874,10 @@ static int exprIsConst(Expr *p, int initFlag, int iCur){
Walker w;
w.eCode = initFlag;
w.xExprCallback = exprNodeIsConstant;
- w.xSelectCallback = sqlite3SelectWalkFail;
-#ifdef SQLITE_DEBUG
- w.xSelectCallback2 = sqlite3SelectWalkAssert2;
-#endif
+ w.xSelectCallback = sqlite3SelectWalkFail;
+#ifdef SQLITE_DEBUG
+ w.xSelectCallback2 = sqlite3SelectWalkAssert2;
+#endif
w.u.iCur = iCur;
sqlite3WalkExpr(&w, p);
return w.eCode;
@@ -103922,66 +103922,66 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
return exprIsConst(p, 3, iCur);
}
-
-/*
-** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy().
-*/
-static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
- ExprList *pGroupBy = pWalker->u.pGroupBy;
- int i;
-
- /* Check if pExpr is identical to any GROUP BY term. If so, consider
- ** it constant. */
- for(i=0; i<pGroupBy->nExpr; i++){
- Expr *p = pGroupBy->a[i].pExpr;
- if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){
- CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p);
+
+/*
+** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy().
+*/
+static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
+ ExprList *pGroupBy = pWalker->u.pGroupBy;
+ int i;
+
+ /* Check if pExpr is identical to any GROUP BY term. If so, consider
+ ** it constant. */
+ for(i=0; i<pGroupBy->nExpr; i++){
+ Expr *p = pGroupBy->a[i].pExpr;
+ if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){
+ CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p);
if( sqlite3IsBinary(pColl) ){
- return WRC_Prune;
- }
- }
- }
-
- /* Check if pExpr is a sub-select. If so, consider it variable. */
+ return WRC_Prune;
+ }
+ }
+ }
+
+ /* Check if pExpr is a sub-select. If so, consider it variable. */
if( ExprUseXSelect(pExpr) ){
- pWalker->eCode = 0;
- return WRC_Abort;
- }
-
- return exprNodeIsConstant(pWalker, pExpr);
-}
-
-/*
-** Walk the expression tree passed as the first argument. Return non-zero
+ pWalker->eCode = 0;
+ return WRC_Abort;
+ }
+
+ return exprNodeIsConstant(pWalker, pExpr);
+}
+
+/*
+** Walk the expression tree passed as the first argument. Return non-zero
** if the expression consists entirely of constants or copies of terms
-** in pGroupBy that sort with the BINARY collation sequence.
-**
-** This routine is used to determine if a term of the HAVING clause can
-** be promoted into the WHERE clause. In order for such a promotion to work,
-** the value of the HAVING clause term must be the same for all members of
-** a "group". The requirement that the GROUP BY term must be BINARY
-** assumes that no other collating sequence will have a finer-grained
-** grouping than binary. In other words (A=B COLLATE binary) implies
-** A=B in every other collating sequence. The requirement that the
-** GROUP BY be BINARY is stricter than necessary. It would also work
-** to promote HAVING clauses that use the same alternative collating
-** sequence as the GROUP BY term, but that is much harder to check,
-** alternative collating sequences are uncommon, and this is only an
-** optimization, so we take the easy way out and simply require the
-** GROUP BY to use the BINARY collating sequence.
-*/
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){
- Walker w;
- w.eCode = 1;
- w.xExprCallback = exprNodeIsConstantOrGroupBy;
- w.xSelectCallback = 0;
- w.u.pGroupBy = pGroupBy;
- w.pParse = pParse;
- sqlite3WalkExpr(&w, p);
- return w.eCode;
-}
-
-/*
+** in pGroupBy that sort with the BINARY collation sequence.
+**
+** This routine is used to determine if a term of the HAVING clause can
+** be promoted into the WHERE clause. In order for such a promotion to work,
+** the value of the HAVING clause term must be the same for all members of
+** a "group". The requirement that the GROUP BY term must be BINARY
+** assumes that no other collating sequence will have a finer-grained
+** grouping than binary. In other words (A=B COLLATE binary) implies
+** A=B in every other collating sequence. The requirement that the
+** GROUP BY be BINARY is stricter than necessary. It would also work
+** to promote HAVING clauses that use the same alternative collating
+** sequence as the GROUP BY term, but that is much harder to check,
+** alternative collating sequences are uncommon, and this is only an
+** optimization, so we take the easy way out and simply require the
+** GROUP BY to use the BINARY collating sequence.
+*/
+SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){
+ Walker w;
+ w.eCode = 1;
+ w.xExprCallback = exprNodeIsConstantOrGroupBy;
+ w.xSelectCallback = 0;
+ w.u.pGroupBy = pGroupBy;
+ w.pParse = pParse;
+ sqlite3WalkExpr(&w, p);
+ return w.eCode;
+}
+
+/*
** Walk an expression tree for the DEFAULT field of a column definition
** in a CREATE TABLE statement. Return non-zero if the expression is
** acceptable for use as a DEFAULT. That is to say, return non-zero if
@@ -104007,25 +104007,25 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
return exprIsConst(p, 4+isInit, 0);
}
-#ifdef SQLITE_ENABLE_CURSOR_HINTS
-/*
-** Walk an expression tree. Return 1 if the expression contains a
-** subquery of some kind. Return 0 if there are no subqueries.
-*/
-SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){
- Walker w;
- w.eCode = 1;
- w.xExprCallback = sqlite3ExprWalkNoop;
- w.xSelectCallback = sqlite3SelectWalkFail;
-#ifdef SQLITE_DEBUG
- w.xSelectCallback2 = sqlite3SelectWalkAssert2;
-#endif
- sqlite3WalkExpr(&w, p);
- return w.eCode==0;
-}
-#endif
-
-/*
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+/*
+** Walk an expression tree. Return 1 if the expression contains a
+** subquery of some kind. Return 0 if there are no subqueries.
+*/
+SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){
+ Walker w;
+ w.eCode = 1;
+ w.xExprCallback = sqlite3ExprWalkNoop;
+ w.xSelectCallback = sqlite3SelectWalkFail;
+#ifdef SQLITE_DEBUG
+ w.xSelectCallback2 = sqlite3SelectWalkAssert2;
+#endif
+ sqlite3WalkExpr(&w, p);
+ return w.eCode==0;
+}
+#endif
+
+/*
** If the expression p codes a constant integer that is small enough
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue. If the expression is not an integer or if it is too big
@@ -104159,21 +104159,21 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){
/*
** pX is the RHS of an IN operator. If pX is a SELECT statement
-** that can be simplified to a direct table access, then return
-** a pointer to the SELECT statement. If pX is not a SELECT statement,
-** or if the SELECT statement needs to be manifested into a transient
-** table, then return NULL.
+** that can be simplified to a direct table access, then return
+** a pointer to the SELECT statement. If pX is not a SELECT statement,
+** or if the SELECT statement needs to be manifested into a transient
+** table, then return NULL.
*/
#ifndef SQLITE_OMIT_SUBQUERY
static Select *isCandidateForInOpt(const Expr *pX){
- Select *p;
+ Select *p;
SrcList *pSrc;
ExprList *pEList;
Table *pTab;
- int i;
+ int i;
if( !ExprUseXSelect(pX) ) return 0; /* Not a subquery */
- if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */
- p = pX->x.pSelect;
+ if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */
+ p = pX->x.pSelect;
if( p->pPrior ) return 0; /* Not a compound SELECT */
if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
@@ -104188,22 +104188,22 @@ static Select *isCandidateForInOpt(const Expr *pX){
if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */
if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */
pTab = pSrc->a[0].pTab;
- assert( pTab!=0 );
+ assert( pTab!=0 );
assert( !IsView(pTab) ); /* FROM clause is not a view */
if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
pEList = p->pEList;
- assert( pEList!=0 );
- /* All SELECT results must be columns. */
- for(i=0; i<pEList->nExpr; i++){
- Expr *pRes = pEList->a[i].pExpr;
- if( pRes->op!=TK_COLUMN ) return 0;
- assert( pRes->iTable==pSrc->a[0].iCursor ); /* Not a correlated subquery */
- }
- return p;
+ assert( pEList!=0 );
+ /* All SELECT results must be columns. */
+ for(i=0; i<pEList->nExpr; i++){
+ Expr *pRes = pEList->a[i].pExpr;
+ if( pRes->op!=TK_COLUMN ) return 0;
+ assert( pRes->iTable==pSrc->a[0].iCursor ); /* Not a correlated subquery */
+ }
+ return p;
}
#endif /* SQLITE_OMIT_SUBQUERY */
-#ifndef SQLITE_OMIT_SUBQUERY
+#ifndef SQLITE_OMIT_SUBQUERY
/*
** Generate code that checks the left-most column of index table iCur to see if
** it contains any NULL entries. Cause the register at regHasNull to be set
@@ -104211,15 +104211,15 @@ static Select *isCandidateForInOpt(const Expr *pX){
** to be set to NULL if iCur contains one or more NULL values.
*/
static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){
- int addr1;
+ int addr1;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull);
- addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
+ addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull);
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
VdbeComment((v, "first_entry_in(%d)", iCur));
- sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeJumpHere(v, addr1);
}
-#endif
+#endif
#ifndef SQLITE_OMIT_SUBQUERY
@@ -104264,29 +104264,29 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
** An existing b-tree might be used if the RHS expression pX is a simple
** subquery such as:
**
-** SELECT <column1>, <column2>... FROM <table>
+** SELECT <column1>, <column2>... FROM <table>
**
** If the RHS of the IN operator is a list or a more complex subquery, then
** an ephemeral table might need to be generated from the RHS and then
** pX->iTable made to point to the ephemeral table instead of an
** existing table.
**
-** The inFlags parameter must contain, at a minimum, one of the bits
-** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains
-** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast
-** membership test. When the IN_INDEX_LOOP bit is set, the IN index will
-** be used to loop over all values of the RHS of the IN operator.
+** The inFlags parameter must contain, at a minimum, one of the bits
+** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains
+** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast
+** membership test. When the IN_INDEX_LOOP bit is set, the IN index will
+** be used to loop over all values of the RHS of the IN operator.
**
** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate
** through the set members) then the b-tree must not contain duplicates.
-** An epheremal table will be created unless the selected columns are guaranteed
-** to be unique - either because it is an INTEGER PRIMARY KEY or due to
-** a UNIQUE constraint or index.
+** An epheremal table will be created unless the selected columns are guaranteed
+** to be unique - either because it is an INTEGER PRIMARY KEY or due to
+** a UNIQUE constraint or index.
**
** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used
** for fast set membership tests) then an epheremal table must
** be used unless <columns> is a single INTEGER PRIMARY KEY column or an
-** index can be found with the specified <columns> as its left-most.
+** index can be found with the specified <columns> as its left-most.
**
** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and
** if the RHS of the IN operator is a list (not a subquery) then this
@@ -104307,27 +104307,27 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
** the value in that register will be NULL if the b-tree contains one or more
** NULL values, and it will be some non-NULL value if the b-tree contains no
** NULL values.
-**
-** If the aiMap parameter is not NULL, it must point to an array containing
-** one element for each column returned by the SELECT statement on the RHS
-** of the IN(...) operator. The i'th entry of the array is populated with the
-** offset of the index column that matches the i'th column returned by the
-** SELECT. For example, if the expression and selected index are:
-**
-** (?,?,?) IN (SELECT a, b, c FROM t1)
-** CREATE INDEX i1 ON t1(b, c, a);
-**
-** then aiMap[] is populated with {2, 0, 1}.
+**
+** If the aiMap parameter is not NULL, it must point to an array containing
+** one element for each column returned by the SELECT statement on the RHS
+** of the IN(...) operator. The i'th entry of the array is populated with the
+** offset of the index column that matches the i'th column returned by the
+** SELECT. For example, if the expression and selected index are:
+**
+** (?,?,?) IN (SELECT a, b, c FROM t1)
+** CREATE INDEX i1 ON t1(b, c, a);
+**
+** then aiMap[] is populated with {2, 0, 1}.
*/
#ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE int sqlite3FindInIndex(
- Parse *pParse, /* Parsing context */
+SQLITE_PRIVATE int sqlite3FindInIndex(
+ Parse *pParse, /* Parsing context */
Expr *pX, /* The IN expression */
- u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
- int *prRhsHasNull, /* Register holding NULL status. See notes */
+ u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
+ int *prRhsHasNull, /* Register holding NULL status. See notes */
int *aiMap, /* Mapping from Index fields to RHS fields */
int *piTab /* OUT: index to use */
-){
+){
Select *p; /* SELECT to the right of IN operator */
int eType = 0; /* Type of RHS table. IN_INDEX_* */
int iTab = pParse->nTab++; /* Cursor of the RHS table */
@@ -104338,46 +104338,46 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0;
/* If the RHS of this IN(...) operator is a SELECT, and if it matters
- ** whether or not the SELECT result contains NULL values, check whether
+ ** whether or not the SELECT result contains NULL values, check whether
** or not NULL is actually possible (it may not be, for example, due
- ** to NOT NULL constraints in the schema). If no NULL values are possible,
- ** set prRhsHasNull to 0 before continuing. */
+ ** to NOT NULL constraints in the schema). If no NULL values are possible,
+ ** set prRhsHasNull to 0 before continuing. */
if( prRhsHasNull && ExprUseXSelect(pX) ){
- int i;
- ExprList *pEList = pX->x.pSelect->pEList;
- for(i=0; i<pEList->nExpr; i++){
- if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break;
- }
- if( i==pEList->nExpr ){
- prRhsHasNull = 0;
- }
- }
-
+ int i;
+ ExprList *pEList = pX->x.pSelect->pEList;
+ for(i=0; i<pEList->nExpr; i++){
+ if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break;
+ }
+ if( i==pEList->nExpr ){
+ prRhsHasNull = 0;
+ }
+ }
+
/* Check to see if an existing table or index can be used to
** satisfy the query. This is preferable to generating a new
- ** ephemeral table. */
- if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){
+ ** ephemeral table. */
+ if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){
sqlite3 *db = pParse->db; /* Database connection */
Table *pTab; /* Table <table>. */
int iDb; /* Database idx for pTab */
- ExprList *pEList = p->pEList;
- int nExpr = pEList->nExpr;
+ ExprList *pEList = p->pEList;
+ int nExpr = pEList->nExpr;
assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
pTab = p->pSrc->a[0].pTab;
-
+
/* Code an OP_Transaction and OP_TableLock for <table>. */
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb>=0 && iDb<SQLITE_MAX_DB );
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
- assert(v); /* sqlite3GetVdbe() has always been previously called */
- if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){
- /* The "x IN (SELECT rowid FROM table)" case */
- int iAddr = sqlite3VdbeAddOp0(v, OP_Once);
+ assert(v); /* sqlite3GetVdbe() has always been previously called */
+ if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){
+ /* The "x IN (SELECT rowid FROM table)" case */
+ int iAddr = sqlite3VdbeAddOp0(v, OP_Once);
VdbeCoverage(v);
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
@@ -104387,113 +104387,113 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
sqlite3VdbeJumpHere(v, iAddr);
}else{
Index *pIdx; /* Iterator variable */
- int affinity_ok = 1;
- int i;
+ int affinity_ok = 1;
+ int i;
/* Check that the affinity that will be used to perform each
- ** comparison is the same as the affinity of each column in table
- ** on the RHS of the IN operator. If it not, it is not possible to
- ** use any index of the RHS table. */
- for(i=0; i<nExpr && affinity_ok; i++){
- Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
- int iCol = pEList->a[i].pExpr->iColumn;
- char idxaff = sqlite3TableColumnAffinity(pTab,iCol); /* RHS table */
- char cmpaff = sqlite3CompareAffinity(pLhs, idxaff);
- testcase( cmpaff==SQLITE_AFF_BLOB );
- testcase( cmpaff==SQLITE_AFF_TEXT );
- switch( cmpaff ){
- case SQLITE_AFF_BLOB:
- break;
- case SQLITE_AFF_TEXT:
- /* sqlite3CompareAffinity() only returns TEXT if one side or the
- ** other has no affinity and the other side is TEXT. Hence,
- ** the only way for cmpaff to be TEXT is for idxaff to be TEXT
- ** and for the term on the LHS of the IN to have no affinity. */
- assert( idxaff==SQLITE_AFF_TEXT );
- break;
- default:
- affinity_ok = sqlite3IsNumericAffinity(idxaff);
- }
- }
-
- if( affinity_ok ){
- /* Search for an existing index that will work for this IN operator */
- for(pIdx=pTab->pIndex; pIdx && eType==0; pIdx=pIdx->pNext){
- Bitmask colUsed; /* Columns of the index used */
- Bitmask mCol; /* Mask for the current column */
- if( pIdx->nColumn<nExpr ) continue;
+ ** comparison is the same as the affinity of each column in table
+ ** on the RHS of the IN operator. If it not, it is not possible to
+ ** use any index of the RHS table. */
+ for(i=0; i<nExpr && affinity_ok; i++){
+ Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
+ int iCol = pEList->a[i].pExpr->iColumn;
+ char idxaff = sqlite3TableColumnAffinity(pTab,iCol); /* RHS table */
+ char cmpaff = sqlite3CompareAffinity(pLhs, idxaff);
+ testcase( cmpaff==SQLITE_AFF_BLOB );
+ testcase( cmpaff==SQLITE_AFF_TEXT );
+ switch( cmpaff ){
+ case SQLITE_AFF_BLOB:
+ break;
+ case SQLITE_AFF_TEXT:
+ /* sqlite3CompareAffinity() only returns TEXT if one side or the
+ ** other has no affinity and the other side is TEXT. Hence,
+ ** the only way for cmpaff to be TEXT is for idxaff to be TEXT
+ ** and for the term on the LHS of the IN to have no affinity. */
+ assert( idxaff==SQLITE_AFF_TEXT );
+ break;
+ default:
+ affinity_ok = sqlite3IsNumericAffinity(idxaff);
+ }
+ }
+
+ if( affinity_ok ){
+ /* Search for an existing index that will work for this IN operator */
+ for(pIdx=pTab->pIndex; pIdx && eType==0; pIdx=pIdx->pNext){
+ Bitmask colUsed; /* Columns of the index used */
+ Bitmask mCol; /* Mask for the current column */
+ if( pIdx->nColumn<nExpr ) continue;
if( pIdx->pPartIdxWhere!=0 ) continue;
- /* Maximum nColumn is BMS-2, not BMS-1, so that we can compute
- ** BITMASK(nExpr) without overflowing */
- testcase( pIdx->nColumn==BMS-2 );
- testcase( pIdx->nColumn==BMS-1 );
- if( pIdx->nColumn>=BMS-1 ) continue;
- if( mustBeUnique ){
- if( pIdx->nKeyCol>nExpr
- ||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx))
- ){
- continue; /* This index is not unique over the IN RHS columns */
- }
- }
-
- colUsed = 0; /* Columns of index used so far */
- for(i=0; i<nExpr; i++){
- Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
- Expr *pRhs = pEList->a[i].pExpr;
- CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
- int j;
+ /* Maximum nColumn is BMS-2, not BMS-1, so that we can compute
+ ** BITMASK(nExpr) without overflowing */
+ testcase( pIdx->nColumn==BMS-2 );
+ testcase( pIdx->nColumn==BMS-1 );
+ if( pIdx->nColumn>=BMS-1 ) continue;
+ if( mustBeUnique ){
+ if( pIdx->nKeyCol>nExpr
+ ||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx))
+ ){
+ continue; /* This index is not unique over the IN RHS columns */
+ }
+ }
+
+ colUsed = 0; /* Columns of index used so far */
+ for(i=0; i<nExpr; i++){
+ Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
+ Expr *pRhs = pEList->a[i].pExpr;
+ CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
+ int j;
assert( pReq!=0 || pRhs->iColumn==XN_ROWID
|| pParse->nErr || db->mallocFailed );
- for(j=0; j<nExpr; j++){
- if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
- assert( pIdx->azColl[j] );
- if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
- continue;
- }
- break;
- }
- if( j==nExpr ) break;
- mCol = MASKBIT(j);
- if( mCol & colUsed ) break; /* Each column used only once */
- colUsed |= mCol;
- if( aiMap ) aiMap[i] = j;
- }
-
- assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) );
- if( colUsed==(MASKBIT(nExpr)-1) ){
- /* If we reach this point, that means the index pIdx is usable */
- int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ for(j=0; j<nExpr; j++){
+ if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
+ assert( pIdx->azColl[j] );
+ if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
+ continue;
+ }
+ break;
+ }
+ if( j==nExpr ) break;
+ mCol = MASKBIT(j);
+ if( mCol & colUsed ) break; /* Each column used only once */
+ colUsed |= mCol;
+ if( aiMap ) aiMap[i] = j;
+ }
+
+ assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) );
+ if( colUsed==(MASKBIT(nExpr)-1) ){
+ /* If we reach this point, that means the index pIdx is usable */
+ int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
ExplainQueryPlan((pParse, 0,
"USING INDEX %s FOR IN-OPERATOR",pIdx->zName));
- sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
- sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
- VdbeComment((v, "%s", pIdx->zName));
- assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
- eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
-
- if( prRhsHasNull ){
-#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
- i64 mask = (1<<nExpr)-1;
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+ VdbeComment((v, "%s", pIdx->zName));
+ assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
+ eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
+
+ if( prRhsHasNull ){
+#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
+ i64 mask = (1<<nExpr)-1;
sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed,
- iTab, 0, 0, (u8*)&mask, P4_INT64);
-#endif
- *prRhsHasNull = ++pParse->nMem;
- if( nExpr==1 ){
- sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull);
- }
- }
- sqlite3VdbeJumpHere(v, iAddr);
- }
- } /* End loop over indexes */
- } /* End if( affinity_ok ) */
- } /* End if not an rowid index */
- } /* End attempt to optimize using an index */
-
+ iTab, 0, 0, (u8*)&mask, P4_INT64);
+#endif
+ *prRhsHasNull = ++pParse->nMem;
+ if( nExpr==1 ){
+ sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull);
+ }
+ }
+ sqlite3VdbeJumpHere(v, iAddr);
+ }
+ } /* End loop over indexes */
+ } /* End if( affinity_ok ) */
+ } /* End if not an rowid index */
+ } /* End attempt to optimize using an index */
+
/* If no preexisting index is available for the IN clause
** and IN_INDEX_NOOP is an allowed reply
** and the RHS of the IN operator is a list, not a subquery
- ** and the RHS is not constant or has two or fewer terms,
+ ** and the RHS is not constant or has two or fewer terms,
** then it is not worth creating an ephemeral table to evaluate
** the IN operator so return IN_INDEX_NOOP.
*/
@@ -104524,90 +104524,90 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
}
pParse->nQueryLoop = savedNQueryLoop;
}
-
- if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
- int i, n;
- n = sqlite3ExprVectorSize(pX->pLeft);
- for(i=0; i<n; i++) aiMap[i] = i;
- }
+
+ if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
+ int i, n;
+ n = sqlite3ExprVectorSize(pX->pLeft);
+ for(i=0; i<n; i++) aiMap[i] = i;
+ }
*piTab = iTab;
return eType;
}
#endif
-#ifndef SQLITE_OMIT_SUBQUERY
+#ifndef SQLITE_OMIT_SUBQUERY
/*
** Argument pExpr is an (?, ?...) IN(...) expression. This
** function allocates and returns a nul-terminated string containing
-** the affinities to be used for each column of the comparison.
-**
-** It is the responsibility of the caller to ensure that the returned
-** string is eventually freed using sqlite3DbFree().
-*/
+** the affinities to be used for each column of the comparison.
+**
+** It is the responsibility of the caller to ensure that the returned
+** string is eventually freed using sqlite3DbFree().
+*/
static char *exprINAffinity(Parse *pParse, const Expr *pExpr){
- Expr *pLeft = pExpr->pLeft;
- int nVal = sqlite3ExprVectorSize(pLeft);
+ Expr *pLeft = pExpr->pLeft;
+ int nVal = sqlite3ExprVectorSize(pLeft);
Select *pSelect = ExprUseXSelect(pExpr) ? pExpr->x.pSelect : 0;
- char *zRet;
-
- assert( pExpr->op==TK_IN );
- zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
- if( zRet ){
- int i;
- for(i=0; i<nVal; i++){
- Expr *pA = sqlite3VectorFieldSubexpr(pLeft, i);
- char a = sqlite3ExprAffinity(pA);
- if( pSelect ){
- zRet[i] = sqlite3CompareAffinity(pSelect->pEList->a[i].pExpr, a);
- }else{
- zRet[i] = a;
- }
- }
- zRet[nVal] = '\0';
- }
- return zRet;
-}
-#endif
-
-#ifndef SQLITE_OMIT_SUBQUERY
-/*
+ char *zRet;
+
+ assert( pExpr->op==TK_IN );
+ zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
+ if( zRet ){
+ int i;
+ for(i=0; i<nVal; i++){
+ Expr *pA = sqlite3VectorFieldSubexpr(pLeft, i);
+ char a = sqlite3ExprAffinity(pA);
+ if( pSelect ){
+ zRet[i] = sqlite3CompareAffinity(pSelect->pEList->a[i].pExpr, a);
+ }else{
+ zRet[i] = a;
+ }
+ }
+ zRet[nVal] = '\0';
+ }
+ return zRet;
+}
+#endif
+
+#ifndef SQLITE_OMIT_SUBQUERY
+/*
** Load the Parse object passed as the first argument with an error
-** message of the form:
-**
-** "sub-select returns N columns - expected M"
+** message of the form:
+**
+** "sub-select returns N columns - expected M"
*/
-SQLITE_PRIVATE void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){
+SQLITE_PRIVATE void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){
if( pParse->nErr==0 ){
const char *zFmt = "sub-select returns %d columns - expected %d";
sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
}
-}
-#endif
-
-/*
-** Expression pExpr is a vector that has been used in a context where
+}
+#endif
+
+/*
+** Expression pExpr is a vector that has been used in a context where
** it is not permitted. If pExpr is a sub-select vector, this routine
-** loads the Parse object with a message of the form:
-**
-** "sub-select returns N columns - expected 1"
-**
-** Or, if it is a regular scalar vector:
-**
-** "row value misused"
-*/
-SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
-#ifndef SQLITE_OMIT_SUBQUERY
+** loads the Parse object with a message of the form:
+**
+** "sub-select returns N columns - expected 1"
+**
+** Or, if it is a regular scalar vector:
+**
+** "row value misused"
+*/
+SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
+#ifndef SQLITE_OMIT_SUBQUERY
if( ExprUseXSelect(pExpr) ){
- sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1);
- }else
-#endif
- {
- sqlite3ErrorMsg(pParse, "row value misused");
- }
-}
-
+ sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1);
+ }else
+#endif
+ {
+ sqlite3ErrorMsg(pParse, "row value misused");
+ }
+}
+
#ifndef SQLITE_OMIT_SUBQUERY
-/*
+/*
** Generate code that will construct an ephemeral table containing all terms
** in the RHS of an IN operator. The IN operator can be in either of two
** forms:
@@ -104645,7 +104645,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
assert( v!=0 );
/* The evaluation of the IN must be repeated every time it
- ** is encountered if any of the following is true:
+ ** is encountered if any of the following is true:
**
** * The right-hand side is a correlated subquery
** * The right-hand side is an expression list containing variables
@@ -104946,48 +104946,48 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
** Expr pIn is an IN(...) expression. This function checks that the
** sub-select on the RHS of the IN() operator has the same number of
** columns as the vector on the LHS. Or, if the RHS of the IN() is not
-** a sub-query, that the LHS is a vector of size 1.
-*/
-SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
- int nVector = sqlite3ExprVectorSize(pIn->pLeft);
+** a sub-query, that the LHS is a vector of size 1.
+*/
+SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
+ int nVector = sqlite3ExprVectorSize(pIn->pLeft);
if( ExprUseXSelect(pIn) && !pParse->db->mallocFailed ){
- if( nVector!=pIn->x.pSelect->pEList->nExpr ){
- sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector);
- return 1;
- }
- }else if( nVector!=1 ){
- sqlite3VectorErrorMsg(pParse, pIn->pLeft);
- return 1;
- }
- return 0;
-}
-#endif
-
-#ifndef SQLITE_OMIT_SUBQUERY
-/*
+ if( nVector!=pIn->x.pSelect->pEList->nExpr ){
+ sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector);
+ return 1;
+ }
+ }else if( nVector!=1 ){
+ sqlite3VectorErrorMsg(pParse, pIn->pLeft);
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+#ifndef SQLITE_OMIT_SUBQUERY
+/*
** Generate code for an IN expression.
**
** x IN (SELECT ...)
** x IN (value, value, ...)
**
** The left-hand side (LHS) is a scalar or vector expression. The
-** right-hand side (RHS) is an array of zero or more scalar values, or a
-** subquery. If the RHS is a subquery, the number of result columns must
-** match the number of columns in the vector on the LHS. If the RHS is
+** right-hand side (RHS) is an array of zero or more scalar values, or a
+** subquery. If the RHS is a subquery, the number of result columns must
+** match the number of columns in the vector on the LHS. If the RHS is
** a list of values, the LHS must be a scalar.
**
-** The IN operator is true if the LHS value is contained within the RHS.
+** The IN operator is true if the LHS value is contained within the RHS.
** The result is false if the LHS is definitely not in the RHS. The
** result is NULL if the presence of the LHS in the RHS cannot be
-** determined due to NULLs.
-**
+** determined due to NULLs.
+**
** This routine generates code that jumps to destIfFalse if the LHS is not
** contained within the RHS. If due to NULLs we cannot determine if the LHS
** is contained in the RHS then jump to destIfNull. If the LHS is contained
** within the RHS then fall through.
-**
-** See the separate in-operator.md documentation file in the canonical
-** SQLite source tree for additional information.
+**
+** See the separate in-operator.md documentation file in the canonical
+** SQLite source tree for additional information.
*/
static void sqlite3ExprCodeIN(
Parse *pParse, /* Parsing and code generating context */
@@ -104997,37 +104997,37 @@ static void sqlite3ExprCodeIN(
){
int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */
int eType; /* Type of the RHS */
- int rLhs; /* Register(s) holding the LHS values */
- int rLhsOrig; /* LHS values prior to reordering by aiMap[] */
+ int rLhs; /* Register(s) holding the LHS values */
+ int rLhsOrig; /* LHS values prior to reordering by aiMap[] */
Vdbe *v; /* Statement under construction */
- int *aiMap = 0; /* Map from vector field to index column */
- char *zAff = 0; /* Affinity string for comparisons */
- int nVector; /* Size of vectors for this IN operator */
- int iDummy; /* Dummy parameter to exprCodeVector() */
- Expr *pLeft; /* The LHS of the IN operator */
- int i; /* loop counter */
- int destStep2; /* Where to jump when NULLs seen in step 2 */
- int destStep6 = 0; /* Start of code for Step 6 */
- int addrTruthOp; /* Address of opcode that determines the IN is true */
- int destNotNull; /* Jump here if a comparison is not true in step 6 */
+ int *aiMap = 0; /* Map from vector field to index column */
+ char *zAff = 0; /* Affinity string for comparisons */
+ int nVector; /* Size of vectors for this IN operator */
+ int iDummy; /* Dummy parameter to exprCodeVector() */
+ Expr *pLeft; /* The LHS of the IN operator */
+ int i; /* loop counter */
+ int destStep2; /* Where to jump when NULLs seen in step 2 */
+ int destStep6 = 0; /* Start of code for Step 6 */
+ int addrTruthOp; /* Address of opcode that determines the IN is true */
+ int destNotNull; /* Jump here if a comparison is not true in step 6 */
int addrTop; /* Top of the step-6 loop */
int iTab = 0; /* Index to use */
u8 okConstFactor = pParse->okConstFactor;
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
- pLeft = pExpr->pLeft;
- if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
- zAff = exprINAffinity(pParse, pExpr);
- nVector = sqlite3ExprVectorSize(pExpr->pLeft);
- aiMap = (int*)sqlite3DbMallocZero(
- pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1
- );
- if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
-
- /* Attempt to compute the RHS. After this step, if anything other than
+ pLeft = pExpr->pLeft;
+ if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
+ zAff = exprINAffinity(pParse, pExpr);
+ nVector = sqlite3ExprVectorSize(pExpr->pLeft);
+ aiMap = (int*)sqlite3DbMallocZero(
+ pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1
+ );
+ if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
+
+ /* Attempt to compute the RHS. After this step, if anything other than
** IN_INDEX_NOOP is returned, the table opened with cursor iTab
- ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned,
- ** the RHS has not yet been coded. */
+ ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned,
+ ** the RHS has not yet been coded. */
v = pParse->pVdbe;
assert( v!=0 ); /* OOM detected prior to this routine */
VdbeNoopComment((v, "begin IN expr"));
@@ -105036,52 +105036,52 @@ static void sqlite3ExprCodeIN(
destIfFalse==destIfNull ? 0 : &rRhsHasNull,
aiMap, &iTab);
- assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH
+ assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH
|| eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC
- );
-#ifdef SQLITE_DEBUG
- /* Confirm that aiMap[] contains nVector integer values between 0 and
- ** nVector-1. */
- for(i=0; i<nVector; i++){
- int j, cnt;
- for(cnt=j=0; j<nVector; j++) if( aiMap[j]==i ) cnt++;
- assert( cnt==1 );
- }
-#endif
+ );
+#ifdef SQLITE_DEBUG
+ /* Confirm that aiMap[] contains nVector integer values between 0 and
+ ** nVector-1. */
+ for(i=0; i<nVector; i++){
+ int j, cnt;
+ for(cnt=j=0; j<nVector; j++) if( aiMap[j]==i ) cnt++;
+ assert( cnt==1 );
+ }
+#endif
/* Code the LHS, the <expr> from "<expr> IN (...)". If the LHS is a
** vector, then it is stored in an array of nVector registers starting
- ** at r1.
- **
- ** sqlite3FindInIndex() might have reordered the fields of the LHS vector
- ** so that the fields are in the same order as an existing index. The
- ** aiMap[] array contains a mapping from the original LHS field order to
- ** the field order that matches the RHS index.
+ ** at r1.
+ **
+ ** sqlite3FindInIndex() might have reordered the fields of the LHS vector
+ ** so that the fields are in the same order as an existing index. The
+ ** aiMap[] array contains a mapping from the original LHS field order to
+ ** the field order that matches the RHS index.
**
** Avoid factoring the LHS of the IN(...) expression out of the loop,
** even if it is constant, as OP_Affinity may be used on the register
** by code generated below. */
assert( pParse->okConstFactor==okConstFactor );
pParse->okConstFactor = 0;
- rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
+ rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
pParse->okConstFactor = okConstFactor;
- for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
- if( i==nVector ){
- /* LHS fields are not reordered */
- rLhs = rLhsOrig;
- }else{
- /* Need to reorder the LHS fields according to aiMap */
- rLhs = sqlite3GetTempRange(pParse, nVector);
- for(i=0; i<nVector; i++){
- sqlite3VdbeAddOp3(v, OP_Copy, rLhsOrig+i, rLhs+aiMap[i], 0);
- }
- }
+ for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
+ if( i==nVector ){
+ /* LHS fields are not reordered */
+ rLhs = rLhsOrig;
+ }else{
+ /* Need to reorder the LHS fields according to aiMap */
+ rLhs = sqlite3GetTempRange(pParse, nVector);
+ for(i=0; i<nVector; i++){
+ sqlite3VdbeAddOp3(v, OP_Copy, rLhsOrig+i, rLhs+aiMap[i], 0);
+ }
+ }
/* If sqlite3FindInIndex() did not find or create an index that is
** suitable for evaluating the IN operator, then evaluate using a
** sequence of comparisons.
- **
- ** This is step (1) in the in-operator.md optimized algorithm.
+ **
+ ** This is step (1) in the in-operator.md optimized algorithm.
*/
if( eType==IN_INDEX_NOOP ){
ExprList *pList;
@@ -105095,7 +105095,7 @@ static void sqlite3ExprCodeIN(
pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
if( destIfNull!=destIfFalse ){
regCkNull = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
+ sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
}
for(ii=0; ii<pList->nExpr; ii++){
r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, &regToFree);
@@ -105111,7 +105111,7 @@ static void sqlite3ExprCodeIN(
VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_Eq);
VdbeCoverageIf(v, ii<pList->nExpr-1 && op==OP_NotNull);
VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_NotNull);
- sqlite3VdbeChangeP5(v, zAff[0]);
+ sqlite3VdbeChangeP5(v, zAff[0]);
}else{
int op = rLhs!=r2 ? OP_Ne : OP_IsNull;
assert( destIfNull==destIfFalse );
@@ -105119,123 +105119,123 @@ static void sqlite3ExprCodeIN(
(void*)pColl, P4_COLLSEQ);
VdbeCoverageIf(v, op==OP_Ne);
VdbeCoverageIf(v, op==OP_IsNull);
- sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL);
+ sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL);
}
}
if( regCkNull ){
sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v);
- sqlite3VdbeGoto(v, destIfFalse);
+ sqlite3VdbeGoto(v, destIfFalse);
}
sqlite3VdbeResolveLabel(v, labelOk);
sqlite3ReleaseTempReg(pParse, regCkNull);
- goto sqlite3ExprCodeIN_finished;
- }
-
- /* Step 2: Check to see if the LHS contains any NULL columns. If the
- ** LHS does contain NULLs then the result must be either FALSE or NULL.
- ** We will then skip the binary search of the RHS.
- */
- if( destIfNull==destIfFalse ){
- destStep2 = destIfFalse;
+ goto sqlite3ExprCodeIN_finished;
+ }
+
+ /* Step 2: Check to see if the LHS contains any NULL columns. If the
+ ** LHS does contain NULLs then the result must be either FALSE or NULL.
+ ** We will then skip the binary search of the RHS.
+ */
+ if( destIfNull==destIfFalse ){
+ destStep2 = destIfFalse;
}else{
destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
- }
+ }
if( pParse->nErr ) goto sqlite3ExprCodeIN_finished;
- for(i=0; i<nVector; i++){
- Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
+ for(i=0; i<nVector; i++){
+ Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
- if( sqlite3ExprCanBeNull(p) ){
- sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
+ if( sqlite3ExprCanBeNull(p) ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
VdbeCoverage(v);
}
}
-
- /* Step 3. The LHS is now known to be non-NULL. Do the binary search
- ** of the RHS using the LHS as a probe. If found, the result is
- ** true.
- */
- if( eType==IN_INDEX_ROWID ){
- /* In this case, the RHS is the ROWID of table b-tree and so we also
- ** know that the RHS is non-NULL. Hence, we combine steps 3 and 4
- ** into a single opcode. */
+
+ /* Step 3. The LHS is now known to be non-NULL. Do the binary search
+ ** of the RHS using the LHS as a probe. If found, the result is
+ ** true.
+ */
+ if( eType==IN_INDEX_ROWID ){
+ /* In this case, the RHS is the ROWID of table b-tree and so we also
+ ** know that the RHS is non-NULL. Hence, we combine steps 3 and 4
+ ** into a single opcode. */
sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs);
- VdbeCoverage(v);
- addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */
- }else{
- sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
- if( destIfFalse==destIfNull ){
- /* Combine Step 3 and Step 5 into a single opcode */
+ VdbeCoverage(v);
+ addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */
+ }else{
+ sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
+ if( destIfFalse==destIfNull ){
+ /* Combine Step 3 and Step 5 into a single opcode */
sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse,
- rLhs, nVector); VdbeCoverage(v);
- goto sqlite3ExprCodeIN_finished;
- }
- /* Ordinary Step 3, for the case where FALSE and NULL are distinct */
+ rLhs, nVector); VdbeCoverage(v);
+ goto sqlite3ExprCodeIN_finished;
+ }
+ /* Ordinary Step 3, for the case where FALSE and NULL are distinct */
addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0,
- rLhs, nVector); VdbeCoverage(v);
- }
-
- /* Step 4. If the RHS is known to be non-NULL and we did not find
- ** an match on the search above, then the result must be FALSE.
- */
- if( rRhsHasNull && nVector==1 ){
- sqlite3VdbeAddOp2(v, OP_NotNull, rRhsHasNull, destIfFalse);
- VdbeCoverage(v);
- }
-
- /* Step 5. If we do not care about the difference between NULL and
+ rLhs, nVector); VdbeCoverage(v);
+ }
+
+ /* Step 4. If the RHS is known to be non-NULL and we did not find
+ ** an match on the search above, then the result must be FALSE.
+ */
+ if( rRhsHasNull && nVector==1 ){
+ sqlite3VdbeAddOp2(v, OP_NotNull, rRhsHasNull, destIfFalse);
+ VdbeCoverage(v);
+ }
+
+ /* Step 5. If we do not care about the difference between NULL and
** FALSE, then just return false.
- */
- if( destIfFalse==destIfNull ) sqlite3VdbeGoto(v, destIfFalse);
-
- /* Step 6: Loop through rows of the RHS. Compare each row to the LHS.
- ** If any comparison is NULL, then the result is NULL. If all
- ** comparisons are FALSE then the final result is FALSE.
- **
- ** For a scalar LHS, it is sufficient to check just the first row
- ** of the RHS.
- */
- if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6);
+ */
+ if( destIfFalse==destIfNull ) sqlite3VdbeGoto(v, destIfFalse);
+
+ /* Step 6: Loop through rows of the RHS. Compare each row to the LHS.
+ ** If any comparison is NULL, then the result is NULL. If all
+ ** comparisons are FALSE then the final result is FALSE.
+ **
+ ** For a scalar LHS, it is sufficient to check just the first row
+ ** of the RHS.
+ */
+ if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6);
addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse);
- VdbeCoverage(v);
- if( nVector>1 ){
+ VdbeCoverage(v);
+ if( nVector>1 ){
destNotNull = sqlite3VdbeMakeLabel(pParse);
- }else{
- /* For nVector==1, combine steps 6 and 7 by immediately returning
- ** FALSE if the first comparison is not NULL */
- destNotNull = destIfFalse;
- }
- for(i=0; i<nVector; i++){
- Expr *p;
- CollSeq *pColl;
- int r3 = sqlite3GetTempReg(pParse);
- p = sqlite3VectorFieldSubexpr(pLeft, i);
- pColl = sqlite3ExprCollSeq(pParse, p);
+ }else{
+ /* For nVector==1, combine steps 6 and 7 by immediately returning
+ ** FALSE if the first comparison is not NULL */
+ destNotNull = destIfFalse;
+ }
+ for(i=0; i<nVector; i++){
+ Expr *p;
+ CollSeq *pColl;
+ int r3 = sqlite3GetTempReg(pParse);
+ p = sqlite3VectorFieldSubexpr(pLeft, i);
+ pColl = sqlite3ExprCollSeq(pParse, p);
sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3);
- sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
- (void*)pColl, P4_COLLSEQ);
- VdbeCoverage(v);
- sqlite3ReleaseTempReg(pParse, r3);
- }
- sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
- if( nVector>1 ){
- sqlite3VdbeResolveLabel(v, destNotNull);
+ sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
+ (void*)pColl, P4_COLLSEQ);
+ VdbeCoverage(v);
+ sqlite3ReleaseTempReg(pParse, r3);
+ }
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
+ if( nVector>1 ){
+ sqlite3VdbeResolveLabel(v, destNotNull);
sqlite3VdbeAddOp2(v, OP_Next, iTab, addrTop+1);
- VdbeCoverage(v);
-
- /* Step 7: If we reach this point, we know that the result must
- ** be false. */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
- }
-
- /* Jumps here in order to return true. */
- sqlite3VdbeJumpHere(v, addrTruthOp);
-
-sqlite3ExprCodeIN_finished:
- if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs);
+ VdbeCoverage(v);
+
+ /* Step 7: If we reach this point, we know that the result must
+ ** be false. */
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
+ }
+
+ /* Jumps here in order to return true. */
+ sqlite3VdbeJumpHere(v, addrTruthOp);
+
+sqlite3ExprCodeIN_finished:
+ if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs);
VdbeComment((v, "end IN expr"));
-sqlite3ExprCodeIN_oom_error:
- sqlite3DbFree(pParse->db, aiMap);
- sqlite3DbFree(pParse->db, zAff);
+sqlite3ExprCodeIN_oom_error:
+ sqlite3DbFree(pParse->db, aiMap);
+ sqlite3DbFree(pParse->db, zAff);
}
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -105279,50 +105279,50 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
const char *z = pExpr->u.zToken;
assert( z!=0 );
c = sqlite3DecOrHexToI64(z, &value);
- if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
+ if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
#ifdef SQLITE_OMIT_FLOATING_POINT
sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
#else
#ifndef SQLITE_OMIT_HEX_INTEGER
if( sqlite3_strnicmp(z,"0x",2)==0 ){
- sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z);
+ sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z);
}else
#endif
{
codeReal(v, z, negFlag, iMem);
}
#endif
- }else{
- if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; }
- sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64);
- }
- }
-}
-
-
-/* Generate code that will load into register regOut a value that is
-** appropriate for the iIdxCol-th column of index pIdx.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(
- Parse *pParse, /* The parsing context */
- Index *pIdx, /* The index whose column is to be loaded */
- int iTabCur, /* Cursor pointing to a table row */
- int iIdxCol, /* The column of the index to be loaded */
- int regOut /* Store the index column value in this register */
-){
- i16 iTabCol = pIdx->aiColumn[iIdxCol];
- if( iTabCol==XN_EXPR ){
- assert( pIdx->aColExpr );
- assert( pIdx->aColExpr->nExpr>iIdxCol );
- pParse->iSelfTab = iTabCur + 1;
- sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
- pParse->iSelfTab = 0;
- }else{
- sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
- iTabCol, regOut);
- }
-}
-
+ }else{
+ if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; }
+ sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64);
+ }
+ }
+}
+
+
+/* Generate code that will load into register regOut a value that is
+** appropriate for the iIdxCol-th column of index pIdx.
+*/
+SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(
+ Parse *pParse, /* The parsing context */
+ Index *pIdx, /* The index whose column is to be loaded */
+ int iTabCur, /* Cursor pointing to a table row */
+ int iIdxCol, /* The column of the index to be loaded */
+ int regOut /* Store the index column value in this register */
+){
+ i16 iTabCol = pIdx->aiColumn[iIdxCol];
+ if( iTabCol==XN_EXPR ){
+ assert( pIdx->aColExpr );
+ assert( pIdx->aColExpr->nExpr>iIdxCol );
+ pParse->iSelfTab = iTabCur + 1;
+ sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
+ pParse->iSelfTab = 0;
+ }else{
+ sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
+ iTabCol, regOut);
+ }
+}
+
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/*
** Generate code that will compute the value of generated column pCol
@@ -105363,10 +105363,10 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
){
Column *pCol;
assert( v!=0 );
- if( pTab==0 ){
- sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
- return;
- }
+ if( pTab==0 ){
+ sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
+ return;
+ }
if( iCol<0 || iCol==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
}else{
@@ -105418,7 +105418,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(
int iColumn, /* Index of the table column */
int iTable, /* The cursor pointing to the table */
int iReg, /* Store results here */
- u8 p5 /* P5 value for OP_Column + FLAGS */
+ u8 p5 /* P5 value for OP_Column + FLAGS */
){
assert( pParse->pVdbe!=0 );
sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg);
@@ -105438,9 +105438,9 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n
}
/*
-** Convert a scalar expression node to a TK_REGISTER referencing
-** register iReg. The caller must ensure that iReg already contains
-** the correct value for the expression.
+** Convert a scalar expression node to a TK_REGISTER referencing
+** register iReg. The caller must ensure that iReg already contains
+** the correct value for the expression.
*/
static void exprToRegister(Expr *pExpr, int iReg){
Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr);
@@ -105452,41 +105452,41 @@ static void exprToRegister(Expr *pExpr, int iReg){
}
/*
-** Evaluate an expression (either a vector or a scalar expression) and store
-** the result in continguous temporary registers. Return the index of
-** the first register used to store the result.
-**
-** If the returned result register is a temporary scalar, then also write
-** that register number into *piFreeable. If the returned result register
-** is not a temporary or if the expression is a vector set *piFreeable
-** to 0.
-*/
-static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
- int iResult;
- int nResult = sqlite3ExprVectorSize(p);
- if( nResult==1 ){
- iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable);
- }else{
- *piFreeable = 0;
- if( p->op==TK_SELECT ){
-#if SQLITE_OMIT_SUBQUERY
- iResult = 0;
-#else
+** Evaluate an expression (either a vector or a scalar expression) and store
+** the result in continguous temporary registers. Return the index of
+** the first register used to store the result.
+**
+** If the returned result register is a temporary scalar, then also write
+** that register number into *piFreeable. If the returned result register
+** is not a temporary or if the expression is a vector set *piFreeable
+** to 0.
+*/
+static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
+ int iResult;
+ int nResult = sqlite3ExprVectorSize(p);
+ if( nResult==1 ){
+ iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable);
+ }else{
+ *piFreeable = 0;
+ if( p->op==TK_SELECT ){
+#if SQLITE_OMIT_SUBQUERY
+ iResult = 0;
+#else
iResult = sqlite3CodeSubselect(pParse, p);
-#endif
- }else{
- int i;
- iResult = pParse->nMem+1;
- pParse->nMem += nResult;
+#endif
+ }else{
+ int i;
+ iResult = pParse->nMem+1;
+ pParse->nMem += nResult;
assert( ExprUseXList(p) );
- for(i=0; i<nResult; i++){
- sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
- }
- }
- }
- return iResult;
-}
-
+ for(i=0; i<nResult; i++){
+ sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
+ }
+ }
+ }
+ return iResult;
+}
+
/*
** If the last opcode is a OP_Copy, then set the do-not-merge flag (p5)
** so that a subsequent copy will not be merged into this one.
@@ -105496,8 +105496,8 @@ static void setDoNotMergeFlagOnCopy(Vdbe *v){
sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */
}
}
-
-/*
+
+/*
** Generate code to implement special SQL functions that are implemented
** in-line rather than by using the usual callbacks.
*/
@@ -105623,9 +105623,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
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; /* Various register numbers */
+ int r1, r2; /* Various register numbers */
Expr tempX; /* Temporary expression node */
- int p5 = 0;
+ int p5 = 0;
assert( target>0 && target<=pParse->nMem );
assert( v!=0 );
@@ -105646,7 +105646,7 @@ expr_code_doover:
pCol = &pAggInfo->aCol[pExpr->iAgg];
if( !pAggInfo->directMode ){
assert( pCol->iMem>0 );
- return pCol->iMem;
+ return pCol->iMem;
}else if( pAggInfo->useSortingIdx ){
Table *pTab = pCol->pTab;
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
@@ -105660,7 +105660,7 @@ expr_code_doover:
sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
}
}
- return target;
+ return target;
}
/* Otherwise, fall thru into the TK_COLUMN case */
/* no break */ deliberate_fall_through
@@ -105693,7 +105693,7 @@ expr_code_doover:
return iReg;
}
if( iTab<0 ){
- if( pParse->iSelfTab<0 ){
+ if( pParse->iSelfTab<0 ){
/* Other columns in the same row for CHECK constraints or
** generated columns or for inserting into partial index.
** The row is unpacked into registers beginning at
@@ -105738,9 +105738,9 @@ expr_code_doover:
return iSrc;
}
}else{
- /* Coding an expression that is part of an index where column names
- ** in the index refer to the table to which the index belongs */
- iTab = pParse->iSelfTab - 1;
+ /* Coding an expression that is part of an index where column names
+ ** in the index refer to the table to which the index belongs */
+ iTab = pParse->iSelfTab - 1;
}
}
assert( ExprUseYTab(pExpr) );
@@ -105754,7 +105754,7 @@ expr_code_doover:
}
case TK_INTEGER: {
codeInteger(pParse, pExpr, 0, target);
- return target;
+ return target;
}
case TK_TRUEFALSE: {
sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target);
@@ -105764,13 +105764,13 @@ expr_code_doover:
case TK_FLOAT: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
codeReal(v, pExpr->u.zToken, 0, target);
- return target;
+ return target;
}
#endif
case TK_STRING: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
- return target;
+ sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
+ return target;
}
default: {
/* Make NULL the default case so that if a bug causes an illegal
@@ -105779,7 +105779,7 @@ expr_code_doover:
** to the attention of the developers. */
assert( op==TK_NULL || op==TK_ERROR || pParse->db->mallocFailed );
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
- return target;
+ return target;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case TK_BLOB: {
@@ -105794,7 +105794,7 @@ expr_code_doover:
assert( z[n]=='\'' );
zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n);
sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC);
- return target;
+ return target;
}
#endif
case TK_VARIABLE: {
@@ -105803,15 +105803,15 @@ expr_code_doover:
assert( pExpr->u.zToken[0]!=0 );
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
if( pExpr->u.zToken[1]!=0 ){
- const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
+ const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) );
- pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */
- sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
+ pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */
+ sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
}
- return target;
+ return target;
}
case TK_REGISTER: {
- return pExpr->iTable;
+ return pExpr->iTable;
}
#ifndef SQLITE_OMIT_CAST
case TK_CAST: {
@@ -105824,44 +105824,44 @@ expr_code_doover:
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3VdbeAddOp2(v, OP_Cast, target,
sqlite3AffinityType(pExpr->u.zToken, 0));
- return inReg;
+ return inReg;
}
#endif /* SQLITE_OMIT_CAST */
- case TK_IS:
- case TK_ISNOT:
- op = (op==TK_IS) ? TK_EQ : TK_NE;
- p5 = SQLITE_NULLEQ;
- /* fall-through */
+ case TK_IS:
+ case TK_ISNOT:
+ op = (op==TK_IS) ? TK_EQ : TK_NE;
+ p5 = SQLITE_NULLEQ;
+ /* fall-through */
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
- Expr *pLeft = pExpr->pLeft;
- if( sqlite3ExprIsVector(pLeft) ){
- codeVectorCompare(pParse, pExpr, target, op, p5);
- }else{
- r1 = sqlite3ExprCodeTemp(pParse, pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
+ Expr *pLeft = pExpr->pLeft;
+ if( sqlite3ExprIsVector(pLeft) ){
+ codeVectorCompare(pParse, pExpr, target, op, p5);
+ }else{
+ r1 = sqlite3ExprCodeTemp(pParse, pLeft, &regFree1);
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
sqlite3VdbeAddOp2(v, OP_Integer, 1, inReg);
codeCompare(pParse, pLeft, pExpr->pRight, op, r1, r2,
sqlite3VdbeCurrentAddr(v)+2, p5,
ExprHasProperty(pExpr,EP_Commuted));
- assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
- assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
- assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
- assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
- assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
- assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
+ assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
+ assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
+ assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
+ assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+ assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+ assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
if( p5==SQLITE_NULLEQ ){
sqlite3VdbeAddOp2(v, OP_Integer, 0, inReg);
}else{
sqlite3VdbeAddOp3(v, OP_ZeroOrNull, r1, inReg, r2);
}
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- }
+ testcase( regFree1==0 );
+ testcase( regFree2==0 );
+ }
break;
}
case TK_AND:
@@ -105899,12 +105899,12 @@ expr_code_doover:
assert( pLeft );
if( pLeft->op==TK_INTEGER ){
codeInteger(pParse, pLeft, 1, target);
- return target;
+ return target;
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( pLeft->op==TK_FLOAT ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
codeReal(v, pLeft->u.zToken, 1, target);
- return target;
+ return target;
#endif
}else{
tempX.op = TK_INTEGER;
@@ -105963,7 +105963,7 @@ expr_code_doover:
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
}else{
- return pInfo->aFunc[pExpr->iAgg].iMem;
+ return pInfo->aFunc[pExpr->iAgg].iMem;
}
break;
}
@@ -105974,7 +105974,7 @@ expr_code_doover:
const char *zId; /* The function name */
u32 constMask = 0; /* Mask of function arguments that are constant */
int i; /* Loop counter */
- sqlite3 *db = pParse->db; /* The database connection */
+ sqlite3 *db = pParse->db; /* The database connection */
u8 enc = ENC(db); /* The text encoding used by this database */
CollSeq *pColl = 0; /* A collating sequence */
@@ -105984,25 +105984,25 @@ expr_code_doover:
}
#endif
- if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
+ if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
/* SQL functions can be expensive. So try to avoid running them
** multiple times if we know they always give the same result */
return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
- }
+ }
assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
assert( ExprUseXList(pExpr) );
pFarg = pExpr->x.pList;
nFarg = pFarg ? pFarg->nExpr : 0;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
zId = pExpr->u.zToken;
- pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
-#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
- if( pDef==0 && pParse->explain ){
- pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
- }
-#endif
- if( pDef==0 || pDef->xFinalize!=0 ){
- sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
+ pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
+#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
+ if( pDef==0 && pParse->explain ){
+ pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
+ }
+#endif
+ if( pDef==0 || pDef->xFinalize!=0 ){
+ sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
break;
}
if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
@@ -106050,7 +106050,7 @@ expr_code_doover:
}
}
- sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
+ sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
}else{
r1 = 0;
@@ -106078,20 +106078,20 @@ expr_code_doover:
if( !pColl ) pColl = db->pDfltColl;
sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
}
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
if( (pDef->funcFlags & SQLITE_FUNC_OFFSET)!=0 && ALWAYS(pFarg!=0) ){
- Expr *pArg = pFarg->a[0].pExpr;
- if( pArg->op==TK_COLUMN ){
- sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
- }else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, target);
- }
- }else
-#endif
- {
+ Expr *pArg = pFarg->a[0].pExpr;
+ if( pArg->op==TK_COLUMN ){
+ sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Null, 0, target);
+ }
+ }else
+#endif
+ {
sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
pDef, pExpr->op2);
- }
+ }
if( nFarg ){
if( constMask==0 ){
sqlite3ReleaseTempRange(pParse, r1, nFarg);
@@ -106099,12 +106099,12 @@ expr_code_doover:
sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1);
}
}
- return target;
+ return target;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_EXISTS:
case TK_SELECT: {
- int nCol;
+ int nCol;
testcase( op==TK_EXISTS );
testcase( op==TK_SELECT );
if( pParse->db->mallocFailed ){
@@ -106113,25 +106113,25 @@ expr_code_doover:
&& ALWAYS( ExprUseXSelect(pExpr) )
&& (nCol = pExpr->x.pSelect->pEList->nExpr)!=1
){
- sqlite3SubselectError(pParse, nCol, 1);
- }else{
+ sqlite3SubselectError(pParse, nCol, 1);
+ }else{
return sqlite3CodeSubselect(pParse, pExpr);
- }
+ }
break;
}
- case TK_SELECT_COLUMN: {
- int n;
- if( pExpr->pLeft->iTable==0 ){
+ case TK_SELECT_COLUMN: {
+ int n;
+ if( pExpr->pLeft->iTable==0 ){
pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
- }
+ }
assert( pExpr->pLeft->op==TK_SELECT || pExpr->pLeft->op==TK_ERROR );
n = sqlite3ExprVectorSize(pExpr->pLeft);
if( pExpr->iTable!=n ){
- sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
- pExpr->iTable, n);
- }
- return pExpr->pLeft->iTable + pExpr->iColumn;
- }
+ sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
+ pExpr->iTable, n);
+ }
+ return pExpr->pLeft->iTable + pExpr->iColumn;
+ }
case TK_IN: {
int destIfFalse = sqlite3VdbeMakeLabel(pParse);
int destIfNull = sqlite3VdbeMakeLabel(pParse);
@@ -106141,7 +106141,7 @@ expr_code_doover:
sqlite3VdbeResolveLabel(v, destIfFalse);
sqlite3VdbeAddOp2(v, OP_AddImm, target, 0);
sqlite3VdbeResolveLabel(v, destIfNull);
- return target;
+ return target;
}
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -106158,10 +106158,10 @@ expr_code_doover:
** Z is stored in pExpr->pList->a[1].pExpr.
*/
case TK_BETWEEN: {
- exprCodeBetween(pParse, pExpr, target, 0, 0);
- return target;
+ exprCodeBetween(pParse, pExpr, target, 0, 0);
+ return target;
}
- case TK_SPAN:
+ case TK_SPAN:
case TK_COLLATE:
case TK_UPLUS: {
pExpr = pExpr->pLeft;
@@ -106228,10 +106228,10 @@ expr_code_doover:
break;
}
- case TK_VECTOR: {
- sqlite3ErrorMsg(pParse, "row value misused");
- break;
- }
+ case TK_VECTOR: {
+ sqlite3ErrorMsg(pParse, "row value misused");
+ break;
+ }
/* TK_IF_NULL_ROW Expr nodes are inserted ahead of expressions
** that derive from the right-hand table of a LEFT JOIN. The
@@ -106239,22 +106239,22 @@ expr_code_doover:
** The expression is only evaluated if that table is not currently
** on a LEFT JOIN NULL row.
*/
- case TK_IF_NULL_ROW: {
- int addrINR;
+ case TK_IF_NULL_ROW: {
+ int addrINR;
u8 okConstFactor = pParse->okConstFactor;
- addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
+ addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
/* Temporarily disable factoring of constant expressions, since
** even though expressions may appear to be constant, they are not
** really constant because they originate from the right-hand side
** of a LEFT JOIN. */
pParse->okConstFactor = 0;
- inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
+ inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
pParse->okConstFactor = okConstFactor;
- sqlite3VdbeJumpHere(v, addrINR);
- sqlite3VdbeChangeP3(v, addrINR, inReg);
- break;
- }
-
+ sqlite3VdbeJumpHere(v, addrINR);
+ sqlite3VdbeChangeP3(v, addrINR, inReg);
+ break;
+ }
+
/*
** Form A:
** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
@@ -106304,7 +106304,7 @@ expr_code_doover:
testcase( pX->op==TK_COLUMN );
exprToRegister(pDel, exprCodeVector(pParse, pDel, &regFree1));
testcase( regFree1==0 );
- memset(&opCompare, 0, sizeof(opCompare));
+ memset(&opCompare, 0, sizeof(opCompare));
opCompare.op = TK_EQ;
opCompare.pLeft = pDel;
pTest = &opCompare;
@@ -106326,7 +106326,7 @@ expr_code_doover:
sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
- sqlite3VdbeGoto(v, endLabel);
+ sqlite3VdbeGoto(v, endLabel);
sqlite3VdbeResolveLabel(v, nextCase);
}
if( (nExpr&1)!=0 ){
@@ -106377,13 +106377,13 @@ expr_code_doover:
/*
** Generate code that will evaluate expression pExpr just one time
** per prepared statement execution.
-**
+**
** If the expression uses functions (that might throw an exception) then
** guard them with an OP_Once opcode to ensure that the code is only executed
** once. If no functions are involved, then factor the code out and put it at
** the end of the prepared statement in the initialization section.
**
-** If regDest>=0 then the result is always stored in that register and the
+** If regDest>=0 then the result is always stored in that register and the
** result is not reusable. If regDest<0 then this routine is free to
** store the value whereever it wants. The register where the expression
** is stored is returned. When regDest<0, two identical expressions might
@@ -106394,20 +106394,20 @@ expr_code_doover:
SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(
Parse *pParse, /* Parsing context */
Expr *pExpr, /* The expression to code when the VDBE initializes */
- int regDest /* Store the value in this register */
+ int regDest /* Store the value in this register */
){
ExprList *p;
assert( ConstFactorOk(pParse) );
p = pParse->pConstExpr;
- if( regDest<0 && p ){
- struct ExprList_item *pItem;
- int i;
- for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
- if( pItem->reusable && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 ){
- return pItem->u.iConstExprReg;
- }
- }
- }
+ if( regDest<0 && p ){
+ struct ExprList_item *pItem;
+ int i;
+ for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
+ if( pItem->reusable && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 ){
+ return pItem->u.iConstExprReg;
+ }
+ }
+ }
pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
if( pExpr!=0 && ExprHasProperty(pExpr, EP_HasFunc) ){
Vdbe *v = pParse->pVdbe;
@@ -106432,7 +106432,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(
}
pParse->pConstExpr = p;
}
- return regDest;
+ return regDest;
}
/*
@@ -106496,18 +106496,18 @@ SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
}
/*
-** Make a transient copy of expression pExpr and then code it using
-** sqlite3ExprCode(). This routine works just like sqlite3ExprCode()
-** except that the input expression is guaranteed to be unchanged.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
- sqlite3 *db = pParse->db;
- pExpr = sqlite3ExprDup(db, pExpr, 0);
- if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target);
- sqlite3ExprDelete(db, pExpr);
-}
-
-/*
+** Make a transient copy of expression pExpr and then code it using
+** sqlite3ExprCode(). This routine works just like sqlite3ExprCode()
+** except that the input expression is guaranteed to be unchanged.
+*/
+SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
+ sqlite3 *db = pParse->db;
+ pExpr = sqlite3ExprDup(db, pExpr, 0);
+ if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target);
+ sqlite3ExprDelete(db, pExpr);
+}
+
+/*
** Generate code that will evaluate expression pExpr and store the
** results in register target. The results are guaranteed to appear
** in register target. If the expression is constant, then this routine
@@ -106525,33 +106525,33 @@ SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int ta
** Generate code that pushes the value of every element of the given
** expression list into a sequence of registers beginning at target.
**
-** Return the number of elements evaluated. The number returned will
-** usually be pList->nExpr but might be reduced if SQLITE_ECEL_OMITREF
-** is defined.
+** Return the number of elements evaluated. The number returned will
+** usually be pList->nExpr but might be reduced if SQLITE_ECEL_OMITREF
+** is defined.
**
** The SQLITE_ECEL_DUP flag prevents the arguments from being
** filled using OP_SCopy. OP_Copy must be used instead.
**
** The SQLITE_ECEL_FACTOR argument allows constant arguments to be
** factored out into initialization code.
-**
-** The SQLITE_ECEL_REF flag means that expressions in the list with
-** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored
-** in registers at srcReg, and so the value can be copied from there.
-** If SQLITE_ECEL_OMITREF is also set, then the values with u.x.iOrderByCol>0
-** are simply omitted rather than being copied from srcReg.
+**
+** The SQLITE_ECEL_REF flag means that expressions in the list with
+** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored
+** in registers at srcReg, and so the value can be copied from there.
+** If SQLITE_ECEL_OMITREF is also set, then the values with u.x.iOrderByCol>0
+** are simply omitted rather than being copied from srcReg.
*/
SQLITE_PRIVATE int sqlite3ExprCodeExprList(
Parse *pParse, /* Parsing context */
ExprList *pList, /* The expression list to be coded */
int target, /* Where to write results */
- int srcReg, /* Source registers if SQLITE_ECEL_REF */
+ int srcReg, /* Source registers if SQLITE_ECEL_REF */
u8 flags /* SQLITE_ECEL_* flags */
){
struct ExprList_item *pItem;
- int i, j, n;
+ int i, j, n;
u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy;
- Vdbe *v = pParse->pVdbe;
+ Vdbe *v = pParse->pVdbe;
assert( pList!=0 );
assert( target>0 );
assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */
@@ -106565,13 +106565,13 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
n--;
}else
#endif
- if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){
- if( flags & SQLITE_ECEL_OMITREF ){
- i--;
- n--;
- }else{
- sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
- }
+ if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){
+ if( flags & SQLITE_ECEL_OMITREF ){
+ i--;
+ n--;
+ }else{
+ sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
+ }
}else if( (flags & SQLITE_ECEL_FACTOR)!=0
&& sqlite3ExprIsConstantNotJoin(pExpr)
){
@@ -106607,20 +106607,20 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
**
** Code it as such, taking care to do the common subexpression
** elimination of x.
-**
-** The xJumpIf parameter determines details:
-**
-** NULL: Store the boolean result in reg[dest]
-** sqlite3ExprIfTrue: Jump to dest if true
-** sqlite3ExprIfFalse: Jump to dest if false
-**
-** The jumpIfNull parameter is ignored if xJumpIf is NULL.
+**
+** The xJumpIf parameter determines details:
+**
+** NULL: Store the boolean result in reg[dest]
+** sqlite3ExprIfTrue: Jump to dest if true
+** sqlite3ExprIfFalse: Jump to dest if false
+**
+** The jumpIfNull parameter is ignored if xJumpIf is NULL.
*/
static void exprCodeBetween(
Parse *pParse, /* Parsing and code generating context */
Expr *pExpr, /* The BETWEEN expression */
- int dest, /* Jump destination or storage location */
- void (*xJump)(Parse*,Expr*,int,int), /* Action to take */
+ int dest, /* Jump destination or storage location */
+ void (*xJump)(Parse*,Expr*,int,int), /* Action to take */
int jumpIfNull /* Take the jump if the BETWEEN is NULL */
){
Expr exprAnd; /* The AND operator in x>=y AND x<=z */
@@ -106630,10 +106630,10 @@ static void exprCodeBetween(
Expr *pDel = 0;
sqlite3 *db = pParse->db;
- memset(&compLeft, 0, sizeof(Expr));
- memset(&compRight, 0, sizeof(Expr));
- memset(&exprAnd, 0, sizeof(Expr));
-
+ memset(&compLeft, 0, sizeof(Expr));
+ memset(&compRight, 0, sizeof(Expr));
+ memset(&exprAnd, 0, sizeof(Expr));
+
assert( ExprUseXList(pExpr) );
pDel = sqlite3ExprDup(db, pExpr->pLeft, 0);
if( db->mallocFailed==0 ){
@@ -106663,15 +106663,15 @@ static void exprCodeBetween(
sqlite3ExprDelete(db, pDel);
/* Ensure adequate test coverage */
- testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 );
- testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 );
- testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 );
- testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 );
- testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 );
- testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 );
- testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 );
- testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 );
- testcase( xJump==0 );
+ testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 );
+ testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 );
+ testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 );
+ testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 );
+ testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 );
+ testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 );
+ testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 );
+ testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 );
+ testcase( xJump==0 );
}
/*
@@ -106742,12 +106742,12 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
}
break;
}
- case TK_IS:
- case TK_ISNOT:
- testcase( op==TK_IS );
- testcase( op==TK_ISNOT );
- op = (op==TK_IS) ? TK_EQ : TK_NE;
- jumpIfNull = SQLITE_NULLEQ;
+ case TK_IS:
+ case TK_ISNOT:
+ testcase( op==TK_IS );
+ testcase( op==TK_ISNOT );
+ op = (op==TK_IS) ? TK_EQ : TK_NE;
+ jumpIfNull = SQLITE_NULLEQ;
/* no break */ deliberate_fall_through
case TK_LT:
case TK_LE:
@@ -106755,7 +106755,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
case TK_GE:
case TK_NE:
case TK_EQ: {
- if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
+ if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
@@ -106765,12 +106765,12 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
- assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
- VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
- VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
- assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
- VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
- VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
+ assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
+ VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
+ VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
+ assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
+ VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
+ VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -106788,7 +106788,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
}
case TK_BETWEEN: {
testcase( jumpIfNull==0 );
- exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull);
+ exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
@@ -106796,15 +106796,15 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
int destIfFalse = sqlite3VdbeMakeLabel(pParse);
int destIfNull = jumpIfNull ? dest : destIfFalse;
sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
- sqlite3VdbeGoto(v, dest);
+ sqlite3VdbeGoto(v, dest);
sqlite3VdbeResolveLabel(v, destIfFalse);
break;
}
#endif
default: {
- default_expr:
+ default_expr:
if( ExprAlwaysTrue(pExpr) ){
- sqlite3VdbeGoto(v, dest);
+ sqlite3VdbeGoto(v, dest);
}else if( ExprAlwaysFalse(pExpr) ){
/* No-op */
}else{
@@ -106918,12 +106918,12 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
}
break;
}
- case TK_IS:
- case TK_ISNOT:
- testcase( pExpr->op==TK_IS );
- testcase( pExpr->op==TK_ISNOT );
- op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
- jumpIfNull = SQLITE_NULLEQ;
+ case TK_IS:
+ case TK_ISNOT:
+ testcase( pExpr->op==TK_IS );
+ testcase( pExpr->op==TK_ISNOT );
+ op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
+ jumpIfNull = SQLITE_NULLEQ;
/* no break */ deliberate_fall_through
case TK_LT:
case TK_LE:
@@ -106931,7 +106931,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
case TK_GE:
case TK_NE:
case TK_EQ: {
- if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
+ if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
@@ -106941,12 +106941,12 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
- assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
- VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
- VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
- assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
- VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
- VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
+ assert(TK_EQ==OP_Eq); testcase(op==OP_Eq);
+ VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ);
+ VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ);
+ assert(TK_NE==OP_Ne); testcase(op==OP_Ne);
+ VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ);
+ VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -106962,7 +106962,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
}
case TK_BETWEEN: {
testcase( jumpIfNull==0 );
- exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull);
+ exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
@@ -106980,7 +106980,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
default: {
default_expr:
if( ExprAlwaysFalse(pExpr) ){
- sqlite3VdbeGoto(v, dest);
+ sqlite3VdbeGoto(v, dest);
}else if( ExprAlwaysTrue(pExpr) ){
/* no-op */
}else{
@@ -107011,46 +107011,46 @@ SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,i
sqlite3ExprDelete(db, pCopy);
}
-/*
-** Expression pVar is guaranteed to be an SQL variable. pExpr may be any
-** type of expression.
-**
-** If pExpr is a simple SQL value - an integer, real, string, blob
-** or NULL value - then the VDBE currently being prepared is configured
-** to re-prepare each time a new value is bound to variable pVar.
-**
-** Additionally, if pExpr is a simple SQL value and the value is the
-** same as that currently bound to variable pVar, non-zero is returned.
-** Otherwise, if the values are not the same or if pExpr is not a simple
-** SQL value, zero is returned.
-*/
+/*
+** Expression pVar is guaranteed to be an SQL variable. pExpr may be any
+** type of expression.
+**
+** If pExpr is a simple SQL value - an integer, real, string, blob
+** or NULL value - then the VDBE currently being prepared is configured
+** to re-prepare each time a new value is bound to variable pVar.
+**
+** Additionally, if pExpr is a simple SQL value and the value is the
+** same as that currently bound to variable pVar, non-zero is returned.
+** Otherwise, if the values are not the same or if pExpr is not a simple
+** SQL value, zero is returned.
+*/
static int exprCompareVariable(
const Parse *pParse,
const Expr *pVar,
const Expr *pExpr
){
- int res = 0;
- int iVar;
- sqlite3_value *pL, *pR = 0;
-
- sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR);
- if( pR ){
- iVar = pVar->iColumn;
- sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
- pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB);
- if( pL ){
- if( sqlite3_value_type(pL)==SQLITE_TEXT ){
- sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */
- }
- res = 0==sqlite3MemCompare(pL, pR, 0);
- }
- sqlite3ValueFree(pR);
- sqlite3ValueFree(pL);
- }
-
- return res;
-}
-
+ int res = 0;
+ int iVar;
+ sqlite3_value *pL, *pR = 0;
+
+ sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR);
+ if( pR ){
+ iVar = pVar->iColumn;
+ sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
+ pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB);
+ if( pL ){
+ if( sqlite3_value_type(pL)==SQLITE_TEXT ){
+ sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */
+ }
+ res = 0==sqlite3MemCompare(pL, pR, 0);
+ }
+ sqlite3ValueFree(pR);
+ sqlite3ValueFree(pL);
+ }
+
+ return res;
+}
+
/*
** Do a deep comparison of two expression trees. Return 0 if the two
** expressions are completely identical. Return 1 if they differ only
@@ -107072,13 +107072,13 @@ static int exprCompareVariable(
** this routine is used, it does not hurt to get an extra 2 - that
** just might result in some slightly slower code. But returning
** an incorrect 0 or 1 could lead to a malfunction.
-**
-** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in
+**
+** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in
** pParse->pReprepare can be matched against literals in pB. The
-** pParse->pVdbe->expmask bitmask is updated for each variable referenced.
+** pParse->pVdbe->expmask bitmask is updated for each variable referenced.
** If pParse is NULL (the normal case) then any TK_VARIABLE term in
-** Argument pParse should normally be NULL. If it is not NULL and pA or
-** pB causes a return value of 2.
+** Argument pParse should normally be NULL. If it is not NULL and pA or
+** pB causes a return value of 2.
*/
SQLITE_PRIVATE int sqlite3ExprCompare(
const Parse *pParse,
@@ -107090,9 +107090,9 @@ SQLITE_PRIVATE int sqlite3ExprCompare(
if( pA==0 || pB==0 ){
return pB==pA ? 0 : 2;
}
- if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){
- return 0;
- }
+ if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){
+ return 0;
+ }
combinedFlags = pA->flags | pB->flags;
if( combinedFlags & EP_IntValue ){
if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
@@ -107101,10 +107101,10 @@ SQLITE_PRIVATE int sqlite3ExprCompare(
return 2;
}
if( pA->op!=pB->op || pA->op==TK_RAISE ){
- if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){
+ if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){
return 1;
}
- if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
+ if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
return 1;
}
return 2;
@@ -107113,7 +107113,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(
assert( !ExprHasProperty(pB, EP_IntValue) );
if( pA->u.zToken ){
if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){
- if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
+ if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
#ifndef SQLITE_OMIT_WINDOWFUNC
assert( pA->op==pB->op );
if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){
@@ -107144,7 +107144,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(
if( combinedFlags & EP_xIsSelect ) return 2;
if( (combinedFlags & EP_FixedCol)==0
&& sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
- if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
+ if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
if( pA->op!=TK_STRING
&& pA->op!=TK_TRUEFALSE
@@ -107192,17 +107192,17 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB
}
/*
-** Like sqlite3ExprCompare() except COLLATE operators at the top-level
-** are ignored.
-*/
+** Like sqlite3ExprCompare() except COLLATE operators at the top-level
+** are ignored.
+*/
SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){
- return sqlite3ExprCompare(0,
+ return sqlite3ExprCompare(0,
sqlite3ExprSkipCollateAndLikely(pA),
sqlite3ExprSkipCollateAndLikely(pB),
- iTab);
-}
-
-/*
+ iTab);
+}
+
+/*
** Return non-zero if Expr p can only be true if pNN is not NULL.
**
** Or if seenNot is true, return non-zero if Expr p can only be
@@ -107297,10 +107297,10 @@ static int exprImpliesNotNull(
** Expr.iTable<0 then assume a table number given by iTab.
**
** If pParse is not NULL, then the values of bound variables in pE1 are
-** compared against literal values in pE2 and pParse->pVdbe->expmask is
+** compared against literal values in pE2 and pParse->pVdbe->expmask is
** modified to record which bound variables are referenced. If pParse
-** is NULL, then false will be returned if pE1 contains any bound variables.
-**
+** is NULL, then false will be returned if pE1 contains any bound variables.
+**
** When in doubt, return false. Returning true might give a performance
** improvement. Returning false might cause a performance reduction, but
** it will always give the correct answer and is hence always safe.
@@ -107311,12 +107311,12 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr(
const Expr *pE2,
int iTab
){
- if( sqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){
+ if( sqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){
return 1;
}
if( pE2->op==TK_OR
- && (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
- || sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
+ && (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
+ || sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
){
return 1;
}
@@ -107469,59 +107469,59 @@ SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
/*
** An instance of the following structure is used by the tree walker
-** to determine if an expression can be evaluated by reference to the
-** index only, without having to do a search for the corresponding
-** table entry. The IdxCover.pIdx field is the index. IdxCover.iCur
-** is the cursor for the table.
-*/
-struct IdxCover {
- Index *pIdx; /* The index to be tested for coverage */
- int iCur; /* Cursor number for the table corresponding to the index */
-};
-
-/*
+** to determine if an expression can be evaluated by reference to the
+** index only, without having to do a search for the corresponding
+** table entry. The IdxCover.pIdx field is the index. IdxCover.iCur
+** is the cursor for the table.
+*/
+struct IdxCover {
+ Index *pIdx; /* The index to be tested for coverage */
+ int iCur; /* Cursor number for the table corresponding to the index */
+};
+
+/*
** Check to see if there are references to columns in table
-** pWalker->u.pIdxCover->iCur can be satisfied using the index
-** pWalker->u.pIdxCover->pIdx.
-*/
-static int exprIdxCover(Walker *pWalker, Expr *pExpr){
- if( pExpr->op==TK_COLUMN
- && pExpr->iTable==pWalker->u.pIdxCover->iCur
+** pWalker->u.pIdxCover->iCur can be satisfied using the index
+** pWalker->u.pIdxCover->pIdx.
+*/
+static int exprIdxCover(Walker *pWalker, Expr *pExpr){
+ if( pExpr->op==TK_COLUMN
+ && pExpr->iTable==pWalker->u.pIdxCover->iCur
&& sqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
- ){
- pWalker->eCode = 1;
- return WRC_Abort;
- }
- return WRC_Continue;
-}
-
-/*
-** Determine if an index pIdx on table with cursor iCur contains will
-** the expression pExpr. Return true if the index does cover the
-** expression and false if the pExpr expression references table columns
-** that are not found in the index pIdx.
-**
-** An index covering an expression means that the expression can be
-** evaluated using only the index and without having to lookup the
-** corresponding table entry.
-*/
-SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(
- Expr *pExpr, /* The index to be tested */
- int iCur, /* The cursor number for the corresponding table */
- Index *pIdx /* The index that might be used for coverage */
-){
- Walker w;
- struct IdxCover xcov;
- memset(&w, 0, sizeof(w));
- xcov.iCur = iCur;
- xcov.pIdx = pIdx;
- w.xExprCallback = exprIdxCover;
- w.u.pIdxCover = &xcov;
- sqlite3WalkExpr(&w, pExpr);
- return !w.eCode;
-}
-
-
+ ){
+ pWalker->eCode = 1;
+ return WRC_Abort;
+ }
+ return WRC_Continue;
+}
+
+/*
+** Determine if an index pIdx on table with cursor iCur contains will
+** the expression pExpr. Return true if the index does cover the
+** expression and false if the pExpr expression references table columns
+** that are not found in the index pIdx.
+**
+** An index covering an expression means that the expression can be
+** evaluated using only the index and without having to lookup the
+** corresponding table entry.
+*/
+SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(
+ Expr *pExpr, /* The index to be tested */
+ int iCur, /* The cursor number for the corresponding table */
+ Index *pIdx /* The index that might be used for coverage */
+){
+ Walker w;
+ struct IdxCover xcov;
+ memset(&w, 0, sizeof(w));
+ xcov.iCur = iCur;
+ xcov.pIdx = pIdx;
+ w.xExprCallback = exprIdxCover;
+ w.u.pIdxCover = &xcov;
+ sqlite3WalkExpr(&w, pExpr);
+ return !w.eCode;
+}
+
+
/* Structure used to pass information throught the Walker in order to
** implement sqlite3ReferencesSrcList().
*/
@@ -107879,7 +107879,7 @@ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
w.xExprCallback = analyzeAggregate;
w.xSelectCallback = sqlite3WalkerDepthIncrease;
w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
- w.walkerDepth = 0;
+ w.walkerDepth = 0;
w.u.pNC = pNC;
w.pParse = 0;
assert( pNC->pSrcList!=0 );
@@ -107926,11 +107926,11 @@ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
}
/*
-** Allocate or deallocate a block of nReg consecutive registers.
+** Allocate or deallocate a block of nReg consecutive registers.
*/
SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){
int i, n;
- if( nReg==1 ) return sqlite3GetTempReg(pParse);
+ if( nReg==1 ) return sqlite3GetTempReg(pParse);
i = pParse->iRangeReg;
n = pParse->nRangeReg;
if( nReg<=n ){
@@ -107943,10 +107943,10 @@ SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){
return i;
}
SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
- if( nReg==1 ){
- sqlite3ReleaseTempReg(pParse, iReg);
- return;
- }
+ if( nReg==1 ){
+ sqlite3ReleaseTempReg(pParse, iReg);
+ return;
+ }
sqlite3VdbeReleaseRegisters(pParse, iReg, nReg, 0, 0);
if( nReg>pParse->nRangeReg ){
pParse->nRangeReg = nReg;
@@ -107967,29 +107967,29 @@ SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){
pParse->nRangeReg = 0;
}
-/*
-** Validate that no temporary register falls within the range of
-** iFirst..iLast, inclusive. This routine is only call from within assert()
-** statements.
-*/
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
- int i;
- if( pParse->nRangeReg>0
- && pParse->iRangeReg+pParse->nRangeReg > iFirst
- && pParse->iRangeReg <= iLast
- ){
- return 0;
- }
- for(i=0; i<pParse->nTempReg; i++){
- if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){
- return 0;
- }
- }
- return 1;
-}
-#endif /* SQLITE_DEBUG */
-
+/*
+** Validate that no temporary register falls within the range of
+** iFirst..iLast, inclusive. This routine is only call from within assert()
+** statements.
+*/
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
+ int i;
+ if( pParse->nRangeReg>0
+ && pParse->iRangeReg+pParse->nRangeReg > iFirst
+ && pParse->iRangeReg <= iLast
+ ){
+ return 0;
+ }
+ for(i=0; i<pParse->nTempReg; i++){
+ if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){
+ return 0;
+ }
+ }
+ return 1;
+}
+#endif /* SQLITE_DEBUG */
+
/************** End of expr.c ************************************************/
/************** Begin file alter.c *******************************************/
/*
@@ -108137,7 +108137,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
if( !pTab ) goto exit_rename_table;
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- zDb = db->aDb[iDb].zDbSName;
+ zDb = db->aDb[iDb].zDbSName;
/* Get a NULL terminated version of the new table name. */
zName = sqlite3NameFromToken(db, pName);
@@ -108315,7 +108315,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
Expr *pDflt; /* Default value for the new column */
sqlite3 *db; /* The database connection; */
Vdbe *v; /* The prepared statement under construction */
- int r1; /* Temporary registers */
+ int r1; /* Temporary registers */
db = pParse->db;
if( pParse->nErr || db->mallocFailed ) return;
@@ -108324,7 +108324,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
assert( sqlite3BtreeHoldsAllMutexes(db) );
iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
- zDb = db->aDb[iDb].zDbSName;
+ zDb = db->aDb[iDb].zDbSName;
zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */
pCol = &pNew->aCol[pNew->nCol-1];
pDflt = sqlite3ColumnExpr(pNew, pCol);
@@ -108513,7 +108513,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table));
if( !pNew ) goto exit_begin_add_column;
pParse->pNewTable = pNew;
- pNew->nTabRef = 1;
+ pNew->nTabRef = 1;
pNew->nCol = pTab->nCol;
assert( pNew->nCol>0 );
nAlloc = (((pNew->nCol-1)/8)*8)+8;
@@ -108521,7 +108521,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc);
pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName);
if( !pNew->aCol || !pNew->zName ){
- assert( db->mallocFailed );
+ assert( db->mallocFailed );
goto exit_begin_add_column;
}
memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
@@ -108534,7 +108534,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0);
pNew->pSchema = db->aDb[iDb].pSchema;
pNew->u.tab.addColOffset = pTab->u.tab.addColOffset;
- pNew->nTabRef = 1;
+ pNew->nTabRef = 1;
exit_begin_add_column:
sqlite3SrcListDelete(db, pSrc);
@@ -110435,14 +110435,14 @@ static void openStatTable(
const char *zTab = aTable[i].zName;
Table *pStat;
aCreateTbl[i] = 0;
- if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
+ if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
if( i<nToOpen ){
/* The sqlite_statN table does not exist. Create it. Note that a
** side-effect of the CREATE TABLE statement is to leave the rootpage
** of the new table in register pParse->regRoot. This is important
** because the OpenWrite opcode below will be needing it. */
sqlite3NestedParse(pParse,
- "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols
+ "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols
);
aRoot[i] = (u32)pParse->regRoot;
aCreateTbl[i] = OPFLAG_P2ISREG;
@@ -110456,12 +110456,12 @@ static void openStatTable(
if( zWhere ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE %s=%Q",
- pDb->zDbSName, zTab, zWhereType, zWhere
+ pDb->zDbSName, zTab, zWhereType, zWhere
);
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
- }else if( db->xPreUpdateCallback ){
- sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab);
-#endif
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ }else if( db->xPreUpdateCallback ){
+ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab);
+#endif
}else{
/* The sqlite_stat[134] table already exists. Delete all rows. */
sqlite3VdbeAddOp2(v, OP_Clear, (int)aRoot[i], iDb);
@@ -110523,7 +110523,7 @@ struct StatAccum {
StatSample *aBest; /* Array of nCol best samples */
int iMin; /* Index in a[] of entry with minimum score */
int nSample; /* Current number of samples */
- int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */
+ int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */
int iGet; /* Index of current sample accessed by stat_get() */
StatSample *a; /* Array of mxSample StatSample objects */
#endif
@@ -110547,7 +110547,7 @@ static void sampleClear(sqlite3 *db, StatSample *p){
static void sampleSetRowid(sqlite3 *db, StatSample *p, int n, const u8 *pData){
assert( db!=0 );
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
- p->u.aRowid = sqlite3DbMallocRawNN(db, n);
+ p->u.aRowid = sqlite3DbMallocRawNN(db, n);
if( p->u.aRowid ){
p->nRowid = n;
memcpy(p->u.aRowid, pData, n);
@@ -110717,11 +110717,11 @@ static const FuncDef statInitFuncdef = {
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
- statInit, /* xSFunc */
+ statInit, /* xSFunc */
0, /* xFinalize */
0, 0, /* xValue, xInverse */
"stat_init", /* zName */
- {0}
+ {0}
};
#ifdef SQLITE_ENABLE_STAT4
@@ -110791,11 +110791,11 @@ static void sampleInsert(StatAccum *p, StatSample *pNew, int nEqZero){
/* StatAccum.nMaxEqZero is set to the maximum number of leading 0
** values in the anEq[] array of any sample in StatAccum.a[]. In
- ** other words, if nMaxEqZero is n, then it is guaranteed that there
+ ** other words, if nMaxEqZero is n, then it is guaranteed that there
** are no samples with StatSample.anEq[m]==0 for (m>=n). */
- if( nEqZero>p->nMaxEqZero ){
- p->nMaxEqZero = nEqZero;
- }
+ if( nEqZero>p->nMaxEqZero ){
+ p->nMaxEqZero = nEqZero;
+ }
if( pNew->isPSample==0 ){
StatSample *pUpgrade = 0;
assert( pNew->anEq[pNew->iCol]>0 );
@@ -110888,22 +110888,22 @@ static void samplePushPrevious(StatAccum *p, int iChng){
}
}
- /* Check that no sample contains an anEq[] entry with an index of
- ** p->nMaxEqZero or greater set to zero. */
+ /* Check that no sample contains an anEq[] entry with an index of
+ ** p->nMaxEqZero or greater set to zero. */
for(i=p->nSample-1; i>=0; i--){
int j;
- for(j=p->nMaxEqZero; j<p->nCol; j++) assert( p->a[i].anEq[j]>0 );
- }
-
- /* Update the anEq[] fields of any samples already collected. */
- if( iChng<p->nMaxEqZero ){
- for(i=p->nSample-1; i>=0; i--){
- int j;
- for(j=iChng; j<p->nCol; j++){
- if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
- }
+ for(j=p->nMaxEqZero; j<p->nCol; j++) assert( p->a[i].anEq[j]>0 );
+ }
+
+ /* Update the anEq[] fields of any samples already collected. */
+ if( iChng<p->nMaxEqZero ){
+ for(i=p->nSample-1; i>=0; i--){
+ int j;
+ for(j=iChng; j<p->nCol; j++){
+ if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
+ }
}
- p->nMaxEqZero = iChng;
+ p->nMaxEqZero = iChng;
}
}
#endif /* SQLITE_ENABLE_STAT4 */
@@ -111007,11 +111007,11 @@ static const FuncDef statPushFuncdef = {
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
- statPush, /* xSFunc */
+ statPush, /* xSFunc */
0, /* xFinalize */
0, 0, /* xValue, xInverse */
"stat_push", /* zName */
- {0}
+ {0}
};
#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */
@@ -111028,12 +111028,12 @@ static const FuncDef statPushFuncdef = {
** The content to returned is determined by the parameter J
** which is one of the STAT_GET_xxxx values defined above.
**
-** The stat_get(P,J) function is not available to generic SQL. It is
-** inserted as part of a manually constructed bytecode program. (See
-** the callStatGet() routine below.) It is guaranteed that the P
+** The stat_get(P,J) function is not available to generic SQL. It is
+** inserted as part of a manually constructed bytecode program. (See
+** the callStatGet() routine below.) It is guaranteed that the P
** parameter will always be a pointer to a StatAccum object, never a
-** NULL.
-**
+** NULL.
+**
** If STAT4 is not enabled, then J is always
** STAT_GET_STAT1 and is hence omitted and this routine becomes
** a one-parameter function, stat_get(P), that always returns the
@@ -111141,11 +111141,11 @@ static const FuncDef statGetFuncdef = {
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
- statGet, /* xSFunc */
+ statGet, /* xSFunc */
0, /* xFinalize */
0, 0, /* xValue, xInverse */
"stat_get", /* zName */
- {0}
+ {0}
};
static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){
@@ -111216,9 +111216,9 @@ static void analyzeOneTable(
int regIdxname = iMem++; /* Register containing index name */
int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
int regPrev = iMem; /* MUST BE LAST (see below) */
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
Table *pStat1 = 0;
-#endif
+#endif
pParse->nMem = MAX(pParse->nMem, iMem);
v = sqlite3GetVdbe(pParse);
@@ -111239,23 +111239,23 @@ static void analyzeOneTable(
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
- db->aDb[iDb].zDbSName ) ){
+ db->aDb[iDb].zDbSName ) ){
return;
}
#endif
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
- if( db->xPreUpdateCallback ){
- pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13);
- if( pStat1==0 ) return;
- pStat1->zName = (char*)&pStat1[1];
- memcpy(pStat1->zName, "sqlite_stat1", 13);
- pStat1->nCol = 3;
- pStat1->iPKey = -1;
- sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
- }
-#endif
-
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ if( db->xPreUpdateCallback ){
+ pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13);
+ if( pStat1==0 ) return;
+ pStat1->zName = (char*)&pStat1[1];
+ memcpy(pStat1->zName, "sqlite_stat1", 13);
+ pStat1->nCol = 3;
+ pStat1->iPKey = -1;
+ sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
+ }
+#endif
+
/* Establish a read-lock on the table at the shared-cache level.
** Open a read-only cursor on the table. Also allocate a cursor number
** to use for scanning indexes (iIdxCur). No index cursor is opened at
@@ -111265,7 +111265,7 @@ static void analyzeOneTable(
iIdxCur = iTab++;
pParse->nTab = MAX(pParse->nTab, iTab);
sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
- sqlite3VdbeLoadString(v, regTabname, pTab->zName);
+ sqlite3VdbeLoadString(v, regTabname, pTab->zName);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int nCol; /* Number of columns in pIdx. "N" */
@@ -111287,7 +111287,7 @@ static void analyzeOneTable(
}
/* Populate the register containing the index name. */
- sqlite3VdbeLoadString(v, regIdxname, zIdxName);
+ sqlite3VdbeLoadString(v, regIdxname, zIdxName);
VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName));
/*
@@ -111375,7 +111375,7 @@ static void analyzeOneTable(
if( nColTest>0 ){
int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
int *aGotoChng; /* Array of jump instruction addresses */
- aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest);
+ aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest);
if( aGotoChng==0 ) continue;
/*
@@ -111408,7 +111408,7 @@ static void analyzeOneTable(
VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng);
- sqlite3VdbeGoto(v, endDistinctTest);
+ sqlite3VdbeGoto(v, endDistinctTest);
/*
@@ -111480,9 +111480,9 @@ static void analyzeOneTable(
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
- sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
-#endif
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
+#endif
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
/* Add the entries to the stat4 table. */
@@ -111510,7 +111510,7 @@ static void analyzeOneTable(
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
VdbeCoverage(v);
for(i=0; i<nCol; i++){
- sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
@@ -111539,9 +111539,9 @@ static void analyzeOneTable(
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
- sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
-#endif
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
+#endif
sqlite3VdbeJumpHere(v, jZeroRows);
}
}
@@ -111643,14 +111643,14 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
if( i==1 ) continue; /* Do not analyze the TEMP database */
analyzeDatabase(pParse, i);
}
- }else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){
- /* Analyze the schema named as the argument */
- analyzeDatabase(pParse, iDb);
+ }else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){
+ /* Analyze the schema named as the argument */
+ analyzeDatabase(pParse, iDb);
}else{
- /* Form 3: Analyze the table or index named as an argument */
+ /* Form 3: Analyze the table or index named as an argument */
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
if( iDb>=0 ){
- zDb = pName2->n ? db->aDb[iDb].zDbSName : 0;
+ zDb = pName2->n ? db->aDb[iDb].zDbSName : 0;
z = sqlite3NameFromToken(db, pTableName);
if( z ){
if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){
@@ -111660,11 +111660,11 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
}
sqlite3DbFree(db, z);
}
- }
+ }
+ }
+ if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){
+ sqlite3VdbeAddOp0(v, OP_Expire);
}
- if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){
- sqlite3VdbeAddOp0(v, OP_Expire);
- }
}
/*
@@ -111789,17 +111789,17 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
** the old data with the new instead of allocating a new array. */
if( pIndex->aiRowEst==0 ){
pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
- if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db);
+ if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db);
}
aiRowEst = pIndex->aiRowEst;
#endif
pIndex->bUnordered = 0;
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
- pIndex->hasStat1 = 1;
- if( pIndex->pPartIdxWhere==0 ){
- pTable->nRowLogEst = pIndex->aiRowLogEst[0];
- pTable->tabFlags |= TF_HasStat1;
- }
+ pIndex->hasStat1 = 1;
+ if( pIndex->pPartIdxWhere==0 ){
+ pTable->nRowLogEst = pIndex->aiRowLogEst[0];
+ pTable->tabFlags |= TF_HasStat1;
+ }
}else{
Index fakeIdx;
fakeIdx.szIdxRow = pTable->szTabRow;
@@ -111808,7 +111808,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
#endif
decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
pTable->szTabRow = fakeIdx.szIdxRow;
- pTable->tabFlags |= TF_HasStat1;
+ pTable->tabFlags |= TF_HasStat1;
}
return 0;
@@ -111889,7 +111889,7 @@ static void initAvgEq(Index *pIdx){
}
}
- if( nDist100>nSum100 && sumEq<nRow ){
+ if( nDist100>nSum100 && sumEq<nRow ){
avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
}
if( avgEq==0 ) avgEq = 1;
@@ -111939,10 +111939,10 @@ static int loadStatTbl(
Index *pPrevIdx = 0; /* Previous index in the loop */
IndexSample *pSample; /* A slot in pIdx->aSample[] */
- assert( db->lookaside.bDisable );
+ assert( db->lookaside.bDisable );
zSql = sqlite3MPrintf(db, zSql1, zDb);
if( !zSql ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
sqlite3DbFree(db, zSql);
@@ -111978,7 +111978,7 @@ static int loadStatTbl(
pIdx->aSample = sqlite3DbMallocZero(db, nByte);
if( pIdx->aSample==0 ){
sqlite3_finalize(pStmt);
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
pSpace = (tRowcnt*)&pIdx->aSample[nSample];
pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
@@ -111995,7 +111995,7 @@ static int loadStatTbl(
zSql = sqlite3MPrintf(db, zSql2, zDb);
if( !zSql ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
sqlite3DbFree(db, zSql);
@@ -112032,11 +112032,11 @@ static int loadStatTbl(
pSample->p = sqlite3DbMallocZero(db, pSample->n + 2);
if( pSample->p==0 ){
sqlite3_finalize(pStmt);
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
+ }
+ if( pSample->n ){
+ memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
}
- if( pSample->n ){
- memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
- }
pIdx->nSample++;
}
rc = sqlite3_finalize(pStmt);
@@ -112052,7 +112052,7 @@ static int loadStat4(sqlite3 *db, const char *zDb){
int rc = SQLITE_OK; /* Result codes from subroutines */
const Table *pStat4;
- assert( db->lookaside.bDisable );
+ assert( db->lookaside.bDisable );
if( (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0
&& IsOrdinaryTable(pStat4)
){
@@ -112090,8 +112090,8 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
analysisInfo sInfo;
HashElem *i;
char *zSql;
- int rc = SQLITE_OK;
- Schema *pSchema = db->aDb[iDb].pSchema;
+ int rc = SQLITE_OK;
+ Schema *pSchema = db->aDb[iDb].pSchema;
const Table *pStat1;
assert( iDb>=0 && iDb<db->nDb );
@@ -112099,40 +112099,40 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
/* Clear any prior statistics */
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){
- Table *pTab = sqliteHashData(i);
- pTab->tabFlags &= ~TF_HasStat1;
- }
- for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
+ for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){
+ Table *pTab = sqliteHashData(i);
+ pTab->tabFlags &= ~TF_HasStat1;
+ }
+ for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
- pIdx->hasStat1 = 0;
+ pIdx->hasStat1 = 0;
#ifdef SQLITE_ENABLE_STAT4
sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
#endif
}
- /* Load new statistics out of the sqlite_stat1 table */
+ /* Load new statistics out of the sqlite_stat1 table */
sInfo.db = db;
- sInfo.zDatabase = db->aDb[iDb].zDbSName;
+ sInfo.zDatabase = db->aDb[iDb].zDbSName;
if( (pStat1 = sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase))
&& IsOrdinaryTable(pStat1)
){
zSql = sqlite3MPrintf(db,
- "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
- if( zSql==0 ){
- rc = SQLITE_NOMEM_BKPT;
- }else{
- rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
- sqlite3DbFree(db, zSql);
- }
+ "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM_BKPT;
+ }else{
+ rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
+ sqlite3DbFree(db, zSql);
+ }
}
- /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
- Index *pIdx = sqliteHashData(i);
- if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
+ /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
+ Index *pIdx = sqliteHashData(i);
+ if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
}
/* Load the statistics from the sqlite_stat4 table. */
@@ -112142,7 +112142,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
rc = loadStat4(db, sInfo.zDatabase);
EnableLookaside;
}
- for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
+ for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3_free(pIdx->aiRowEst);
pIdx->aiRowEst = 0;
@@ -112150,7 +112150,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
#endif
if( rc==SQLITE_NOMEM ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
}
return rc;
}
@@ -112246,8 +112246,8 @@ static void attachFunc(
char *zPath = 0;
char *zErr = 0;
unsigned int flags;
- Db *aNew; /* New array of Db pointers */
- Db *pNew; /* Db object for the newly attached database */
+ Db *aNew; /* New array of Db pointers */
+ Db *pNew; /* Db object for the newly attached database */
char *zErrDyn = 0;
sqlite3_vfs *pVfs;
@@ -112336,28 +112336,28 @@ static void attachFunc(
zErrDyn = sqlite3MPrintf(db, "database is already attached");
}else if( rc==SQLITE_OK ){
Pager *pPager;
- pNew->pSchema = sqlite3SchemaGet(db, pNew->pBt);
- if( !pNew->pSchema ){
- rc = SQLITE_NOMEM_BKPT;
- }else if( pNew->pSchema->file_format && pNew->pSchema->enc!=ENC(db) ){
+ pNew->pSchema = sqlite3SchemaGet(db, pNew->pBt);
+ if( !pNew->pSchema ){
+ rc = SQLITE_NOMEM_BKPT;
+ }else if( pNew->pSchema->file_format && pNew->pSchema->enc!=ENC(db) ){
zErrDyn = sqlite3MPrintf(db,
"attached databases must use the same text encoding as main database");
rc = SQLITE_ERROR;
}
- sqlite3BtreeEnter(pNew->pBt);
- pPager = sqlite3BtreePager(pNew->pBt);
+ sqlite3BtreeEnter(pNew->pBt);
+ pPager = sqlite3BtreePager(pNew->pBt);
sqlite3PagerLockingMode(pPager, db->dfltLockMode);
- sqlite3BtreeSecureDelete(pNew->pBt,
+ sqlite3BtreeSecureDelete(pNew->pBt,
sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
- sqlite3BtreeSetPagerFlags(pNew->pBt,
- PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK));
+ sqlite3BtreeSetPagerFlags(pNew->pBt,
+ PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK));
#endif
- sqlite3BtreeLeave(pNew->pBt);
+ sqlite3BtreeLeave(pNew->pBt);
}
- pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
- if( rc==SQLITE_OK && pNew->zDbSName==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
+ if( rc==SQLITE_OK && pNew->zDbSName==0 ){
+ rc = SQLITE_NOMEM_BKPT;
}
sqlite3_free_filename( zPath );
@@ -112503,7 +112503,7 @@ static void codeAttach(
sqlite3* db = pParse->db;
int regArgs;
- if( pParse->nErr ) goto attach_end;
+ if( pParse->nErr ) goto attach_end;
memset(&sName, 0, sizeof(NameContext));
sName.pParse = pParse;
@@ -112566,11 +112566,11 @@ SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
- detachFunc, /* xSFunc */
+ detachFunc, /* xSFunc */
0, /* xFinalize */
0, 0, /* xValue, xInverse */
"sqlite_detach", /* zName */
- {0}
+ {0}
};
codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
}
@@ -112586,11 +112586,11 @@ SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *p
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
- attachFunc, /* xSFunc */
+ attachFunc, /* xSFunc */
0, /* xFinalize */
0, 0, /* xValue, xInverse */
"sqlite_attach", /* zName */
- {0}
+ {0}
};
codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
}
@@ -112669,7 +112669,7 @@ SQLITE_PRIVATE void sqlite3FixInit(
sqlite3 *db = pParse->db;
assert( db->nDb>iDb );
pFix->pParse = pParse;
- pFix->zDb = db->aDb[iDb].zDbSName;
+ pFix->zDb = db->aDb[iDb].zDbSName;
pFix->pSchema = db->aDb[iDb].pSchema;
pFix->zType = zType;
pFix->pName = pName;
@@ -112830,7 +112830,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep(
** Setting the auth function to NULL disables this hook. The default
** setting of the auth function is NULL.
*/
-SQLITE_API int sqlite3_set_authorizer(
+SQLITE_API int sqlite3_set_authorizer(
sqlite3 *db,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg
@@ -112870,20 +112870,20 @@ SQLITE_PRIVATE int sqlite3AuthReadCol(
const char *zCol, /* Column name */
int iDb /* Index of containing database. */
){
- sqlite3 *db = pParse->db; /* Database handle */
- char *zDb = db->aDb[iDb].zDbSName; /* Schema name of attached database */
- int rc; /* Auth callback return code */
+ sqlite3 *db = pParse->db; /* Database handle */
+ char *zDb = db->aDb[iDb].zDbSName; /* Schema name of attached database */
+ int rc; /* Auth callback return code */
- if( db->init.busy ) return SQLITE_OK;
+ if( db->init.busy ) return SQLITE_OK;
rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext
#ifdef SQLITE_USER_AUTHENTICATION
,db->auth.zAuthUser
#endif
);
if( rc==SQLITE_DENY ){
- char *z = sqlite3_mprintf("%s.%s", zTab, zCol);
- if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z);
- sqlite3ErrorMsg(pParse, "access to %z is prohibited", z);
+ char *z = sqlite3_mprintf("%s.%s", zTab, zCol);
+ if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z);
+ sqlite3ErrorMsg(pParse, "access to %z is prohibited", z);
pParse->rc = SQLITE_AUTH;
}else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){
sqliteAuthBadReturnCode(pParse);
@@ -112975,17 +112975,17 @@ SQLITE_PRIVATE int sqlite3AuthCheck(
return SQLITE_OK;
}
- /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the
- ** callback are either NULL pointers or zero-terminated strings that
- ** contain additional details about the action to be authorized.
- **
- ** The following testcase() macros show that any of the 3rd through 6th
- ** parameters can be either NULL or a string. */
- testcase( zArg1==0 );
- testcase( zArg2==0 );
- testcase( zArg3==0 );
- testcase( pParse->zAuthContext==0 );
-
+ /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the
+ ** callback are either NULL pointers or zero-terminated strings that
+ ** contain additional details about the action to be authorized.
+ **
+ ** The following testcase() macros show that any of the 3rd through 6th
+ ** parameters can be either NULL or a string. */
+ testcase( zArg1==0 );
+ testcase( zArg2==0 );
+ testcase( zArg3==0 );
+ testcase( pParse->zAuthContext==0 );
+
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
#ifdef SQLITE_USER_AUTHENTICATION
,db->auth.zAuthUser
@@ -113064,10 +113064,10 @@ SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){
** codeTableLocks() functions.
*/
struct TableLock {
- int iDb; /* The database containing the table to be locked */
+ int iDb; /* The database containing the table to be locked */
Pgno iTab; /* The root page of the table to be locked */
- u8 isWriteLock; /* True for write lock. False for a read lock */
- const char *zLockName; /* Name of the table */
+ u8 isWriteLock; /* True for write lock. False for a read lock */
+ const char *zLockName; /* Name of the table */
};
/*
@@ -113110,10 +113110,10 @@ static SQLITE_NOINLINE void lockTable(
p->iDb = iDb;
p->iTab = iTab;
p->isWriteLock = isWriteLock;
- p->zLockName = zName;
+ p->zLockName = zName;
}else{
pToplevel->nTableLock = 0;
- sqlite3OomFault(pToplevel->db);
+ sqlite3OomFault(pToplevel->db);
}
}
SQLITE_PRIVATE void sqlite3TableLock(
@@ -113141,7 +113141,7 @@ static void codeTableLocks(Parse *pParse){
TableLock *p = &pParse->aTableLock[i];
int p1 = p->iDb;
sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock,
- p->zLockName, P4_STATIC);
+ p->zLockName, P4_STATIC);
}
}
#else
@@ -113226,7 +113226,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
if( pParse->nTableLock>0 && db->init.busy==0 ){
sqlite3UserAuthInit(db);
if( db->auth.authLevel<UAUTH_User ){
- sqlite3ErrorMsg(pParse, "user not authenticated");
+ sqlite3ErrorMsg(pParse, "user not authenticated");
pParse->rc = SQLITE_AUTH_USER;
return;
}
@@ -113246,20 +113246,20 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
sqlite3VdbeJumpHere(v, 0);
for(iDb=0; iDb<db->nDb; iDb++){
- Schema *pSchema;
+ Schema *pSchema;
if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
sqlite3VdbeUsesBtree(v, iDb);
- pSchema = db->aDb[iDb].pSchema;
+ pSchema = db->aDb[iDb].pSchema;
sqlite3VdbeAddOp4Int(v,
OP_Transaction, /* Opcode */
iDb, /* P1 */
DbMaskTest(pParse->writeMask,iDb), /* P2 */
- pSchema->schema_cookie, /* P3 */
- pSchema->iGeneration /* P4 */
+ pSchema->schema_cookie, /* P3 */
+ pSchema->iGeneration /* P4 */
);
if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
- VdbeComment((v,
- "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
+ VdbeComment((v,
+ "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
for(i=0; i<pParse->nVtabLock; i++){
@@ -113307,7 +113307,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
}
/* Finally, jump back to the beginning of the executable code. */
- sqlite3VdbeGoto(v, 1);
+ sqlite3VdbeGoto(v, 1);
}
}
@@ -113343,7 +113343,7 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
char *zErrMsg = 0;
sqlite3 *db = pParse->db;
u32 savedDbFlags = db->mDbFlags;
- char saveBuf[PARSE_TAIL_SZ];
+ char saveBuf[PARSE_TAIL_SZ];
if( pParse->nErr ) return;
assert( pParse->nested<10 ); /* Nesting should only be of limited depth */
@@ -113359,14 +113359,14 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
return;
}
pParse->nested++;
- memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
- memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
+ memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
+ memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
db->mDbFlags |= DBFLAG_PreferBuiltin;
sqlite3RunParser(pParse, zSql, &zErrMsg);
db->mDbFlags = savedDbFlags;
sqlite3DbFree(db, zErrMsg);
sqlite3DbFree(db, zSql);
- memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
+ memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
pParse->nested--;
}
@@ -113416,8 +113416,8 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha
i = 0;
}else{
return 0;
- }
- }
+ }
+ }
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
if( i==1 ){
@@ -113472,7 +113472,7 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha
*/
SQLITE_PRIVATE Table *sqlite3LocateTable(
Parse *pParse, /* context in which to report errors */
- u32 flags, /* LOCATE_VIEW or LOCATE_NOERR */
+ u32 flags, /* LOCATE_VIEW or LOCATE_NOERR */
const char *zName, /* Name of the table we are looking for */
const char *zDbase /* Name of the database. Might be NULL */
){
@@ -113489,21 +113489,21 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
p = sqlite3FindTable(db, zName, zDbase);
if( p==0 ){
-#ifndef SQLITE_OMIT_VIRTUALTABLE
+#ifndef SQLITE_OMIT_VIRTUALTABLE
/* If zName is the not the name of a table in the schema created using
** CREATE, then check to see if it is the name of an virtual table that
** can be an eponymous virtual table. */
if( pParse->disableVtab==0 && db->init.busy==0 ){
Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
- if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
+ if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
pMod = sqlite3PragmaVtabRegister(db, zName);
- }
- if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
+ }
+ if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
testcase( pMod->pEpoTab==0 );
- return pMod->pEpoTab;
- }
+ return pMod->pEpoTab;
+ }
}
-#endif
+#endif
if( flags & LOCATE_NOERR ) return 0;
pParse->checkSchema = 1;
}else if( IsVirtual(p) && pParse->disableVtab ){
@@ -113516,11 +113516,11 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
}else{
sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
- }
+ }
}else{
assert( HasRowid(p) || p->iPKey<0 );
}
-
+
return p;
}
@@ -113535,18 +113535,18 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
*/
SQLITE_PRIVATE Table *sqlite3LocateTableItem(
Parse *pParse,
- u32 flags,
+ u32 flags,
SrcItem *p
){
const char *zDb;
assert( p->pSchema==0 || p->zDatabase==0 );
if( p->pSchema ){
int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
- zDb = pParse->db->aDb[iDb].zDbSName;
+ zDb = pParse->db->aDb[iDb].zDbSName;
}else{
zDb = p->zDatabase;
}
- return sqlite3LocateTable(pParse, flags, p->zName, zDb);
+ return sqlite3LocateTable(pParse, flags, p->zName, zDb);
}
/*
@@ -113602,9 +113602,9 @@ SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3 *db, Index *p){
sqlite3DeleteIndexSamples(db, p);
#endif
sqlite3ExprDelete(db, p->pPartIdxWhere);
- sqlite3ExprListDelete(db, p->aColExpr);
+ sqlite3ExprListDelete(db, p->aColExpr);
sqlite3DbFree(db, p->zColAff);
- if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl);
+ if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl);
#ifdef SQLITE_ENABLE_STAT4
sqlite3_free(p->aiRowEst);
#endif
@@ -113639,7 +113639,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char
}
sqlite3FreeIndex(db, pIndex);
}
- db->mDbFlags |= DBFLAG_SchemaChange;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
/*
@@ -113655,8 +113655,8 @@ SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){
for(i=j=2; i<db->nDb; i++){
struct Db *pDb = &db->aDb[i];
if( pDb->pBt==0 ){
- sqlite3DbFree(db, pDb->zDbSName);
- pDb->zDbSName = 0;
+ sqlite3DbFree(db, pDb->zDbSName);
+ pDb->zDbSName = 0;
continue;
}
if( j<i ){
@@ -113674,26 +113674,26 @@ SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){
/*
** Reset the schema for the database at index iDb. Also reset the
-** TEMP schema. The reset is deferred if db->nSchemaLock is not zero.
-** Deferred resets may be run by calling with iDb<0.
+** TEMP schema. The reset is deferred if db->nSchemaLock is not zero.
+** Deferred resets may be run by calling with iDb<0.
*/
SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
- int i;
+ int i;
assert( iDb<db->nDb );
- if( iDb>=0 ){
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- DbSetProperty(db, iDb, DB_ResetWanted);
- DbSetProperty(db, 1, DB_ResetWanted);
+ if( iDb>=0 ){
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ DbSetProperty(db, iDb, DB_ResetWanted);
+ DbSetProperty(db, 1, DB_ResetWanted);
db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
- }
+ }
- if( db->nSchemaLock==0 ){
- for(i=0; i<db->nDb; i++){
- if( DbHasProperty(db, i, DB_ResetWanted) ){
- sqlite3SchemaClear(db->aDb[i].pSchema);
- }
- }
+ if( db->nSchemaLock==0 ){
+ for(i=0; i<db->nDb; i++){
+ if( DbHasProperty(db, i, DB_ResetWanted) ){
+ sqlite3SchemaClear(db->aDb[i].pSchema);
+ }
+ }
}
}
@@ -113726,7 +113726,7 @@ SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
** This routine is called when a commit occurs.
*/
SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){
- db->mDbFlags &= ~DBFLAG_SchemaChange;
+ db->mDbFlags &= ~DBFLAG_SchemaChange;
}
/*
@@ -113811,7 +113811,7 @@ SQLITE_PRIVATE const char *sqlite3ColumnColl(Column *pCol){
** Delete memory allocated for the column names of a table or view (the
** Table.aCol[] array).
*/
-SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
+SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
int i;
Column *pCol;
assert( pTable!=0 );
@@ -113849,10 +113849,10 @@ SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
** db parameter can be used with db->pnBytesFreed to measure the memory
** used by the Table object.
*/
-static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
+static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
Index *pIndex, *pNext;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/* Record the number of outstanding lookaside allocations in schema Tables
** prior to doing any free() operations. Since schema Tables do not use
** lookaside, this number should not change.
@@ -113860,18 +113860,18 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
** If malloc has already failed, it may be that it failed while allocating
** a Table object that was going to be marked ephemeral. So do not check
** that no lookaside memory is used in this case either. */
- int nLookaside = 0;
+ int nLookaside = 0;
if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){
- nLookaside = sqlite3LookasideUsed(db, 0);
- }
-#endif
+ nLookaside = sqlite3LookasideUsed(db, 0);
+ }
+#endif
/* Delete all indices associated with this table. */
for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
pNext = pIndex->pNext;
- assert( pIndex->pSchema==pTable->pSchema
- || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) );
- if( (db==0 || db->pnBytesFreed==0) && !IsVirtual(pTable) ){
+ assert( pIndex->pSchema==pTable->pSchema
+ || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) );
+ if( (db==0 || db->pnBytesFreed==0) && !IsVirtual(pTable) ){
char *zName = pIndex->zName;
TESTONLY ( Index *pOld = ) sqlite3HashInsert(
&pIndex->pSchema->idxHash, zName, 0
@@ -113897,23 +113897,23 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
/* Delete the Table structure itself.
*/
- sqlite3DeleteColumnNames(db, pTable);
+ sqlite3DeleteColumnNames(db, pTable);
sqlite3DbFree(db, pTable->zName);
sqlite3DbFree(db, pTable->zColAff);
sqlite3ExprListDelete(db, pTable->pCheck);
sqlite3DbFree(db, pTable);
/* Verify that no lookaside memory was used by schema tables */
- assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) );
+ assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) );
}
-SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
- /* Do not delete the table until the reference count reaches zero. */
- if( !pTable ) return;
- if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return;
- deleteTable(db, pTable);
-}
+SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
+ /* Do not delete the table until the reference count reaches zero. */
+ if( !pTable ) return;
+ if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return;
+ deleteTable(db, pTable);
+}
+
-
/*
** Unlink the given table from the hash tables and the delete the
** table structure with all its indices and foreign keys.
@@ -113930,7 +113930,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char
pDb = &db->aDb[iDb];
p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0);
sqlite3DeleteTable(db, p);
- db->mDbFlags |= DBFLAG_SchemaChange;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
/*
@@ -113981,10 +113981,10 @@ SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){
if( zName ){
Db *pDb;
for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
- if( 0==sqlite3_stricmp(pDb->zDbSName, zName) ) break;
- /* "main" is always an acceptable alias for the primary database
- ** even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME. */
- if( i==0 && 0==sqlite3_stricmp("main", zName) ) break;
+ if( 0==sqlite3_stricmp(pDb->zDbSName, zName) ) break;
+ /* "main" is always an acceptable alias for the primary database
+ ** even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME. */
+ if( i==0 && 0==sqlite3_stricmp("main", zName) ) break;
}
}
return i;
@@ -114030,8 +114030,8 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
int iDb; /* Database holding the object */
sqlite3 *db = pParse->db;
- assert( pName2!=0 );
- if( pName2->n>0 ){
+ assert( pName2!=0 );
+ if( pName2->n>0 ){
if( db->init.busy ) {
sqlite3ErrorMsg(pParse, "corrupt database");
return -1;
@@ -114044,7 +114044,7 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
}
}else{
assert( db->init.iDb==0 || db->init.busy || IN_SPECIAL_PARSE
- || (db->mDbFlags & DBFLAG_Vacuum)!=0);
+ || (db->mDbFlags & DBFLAG_Vacuum)!=0);
iDb = db->init.iDb;
*pUnqual = pName1;
}
@@ -114261,23 +114261,23 @@ SQLITE_PRIVATE void sqlite3StartTable(
int iDb; /* Database number to create the table in */
Token *pName; /* Unqualified name of the table to create */
- if( db->init.busy && db->init.newTnum==1 ){
+ if( db->init.busy && db->init.newTnum==1 ){
/* Special case: Parsing the sqlite_schema or sqlite_temp_schema schema */
- iDb = db->init.iDb;
- zName = sqlite3DbStrDup(db, SCHEMA_TABLE(iDb));
- pName = pName1;
- }else{
- /* The common case */
- iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
- if( iDb<0 ) return;
- if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){
+ iDb = db->init.iDb;
+ zName = sqlite3DbStrDup(db, SCHEMA_TABLE(iDb));
+ pName = pName1;
+ }else{
+ /* The common case */
+ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
+ if( iDb<0 ) return;
+ if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){
/* If creating a temp table, the name may not be qualified. Unless
- ** the database name is "temp" anyway. */
- sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
- return;
- }
- if( !OMIT_TEMPDB && isTemp ) iDb = 1;
- zName = sqlite3NameFromToken(db, pName);
+ ** the database name is "temp" anyway. */
+ sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
+ return;
+ }
+ if( !OMIT_TEMPDB && isTemp ) iDb = 1;
+ zName = sqlite3NameFromToken(db, pName);
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenMap(pParse, (void*)zName, pName);
}
@@ -114289,21 +114289,21 @@ SQLITE_PRIVATE void sqlite3StartTable(
}
if( db->init.iDb==1 ) isTemp = 1;
#ifndef SQLITE_OMIT_AUTHORIZATION
- assert( isTemp==0 || isTemp==1 );
- assert( isView==0 || isView==1 );
+ assert( isTemp==0 || isTemp==1 );
+ assert( isView==0 || isView==1 );
{
- static const u8 aCode[] = {
- SQLITE_CREATE_TABLE,
- SQLITE_CREATE_TEMP_TABLE,
- SQLITE_CREATE_VIEW,
- SQLITE_CREATE_TEMP_VIEW
- };
- char *zDb = db->aDb[iDb].zDbSName;
+ static const u8 aCode[] = {
+ SQLITE_CREATE_TABLE,
+ SQLITE_CREATE_TEMP_TABLE,
+ SQLITE_CREATE_VIEW,
+ SQLITE_CREATE_TEMP_VIEW
+ };
+ char *zDb = db->aDb[iDb].zDbSName;
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
goto begin_table_error;
}
- if( !isVirtual && sqlite3AuthCheck(pParse, (int)aCode[isTemp+2*isView],
- zName, 0, zDb) ){
+ if( !isVirtual && sqlite3AuthCheck(pParse, (int)aCode[isTemp+2*isView],
+ zName, 0, zDb) ){
goto begin_table_error;
}
}
@@ -114317,7 +114317,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
** collisions.
*/
if( !IN_SPECIAL_PARSE ){
- char *zDb = db->aDb[iDb].zDbSName;
+ char *zDb = db->aDb[iDb].zDbSName;
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto begin_table_error;
}
@@ -114340,20 +114340,20 @@ SQLITE_PRIVATE void sqlite3StartTable(
pTable = sqlite3DbMallocZero(db, sizeof(Table));
if( pTable==0 ){
- assert( db->mallocFailed );
- pParse->rc = SQLITE_NOMEM_BKPT;
+ assert( db->mallocFailed );
+ pParse->rc = SQLITE_NOMEM_BKPT;
pParse->nErr++;
goto begin_table_error;
}
pTable->zName = zName;
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
- pTable->nTabRef = 1;
-#ifdef SQLITE_DEFAULT_ROWEST
- pTable->nRowLogEst = sqlite3LogEst(SQLITE_DEFAULT_ROWEST);
-#else
+ pTable->nTabRef = 1;
+#ifdef SQLITE_DEFAULT_ROWEST
+ pTable->nRowLogEst = sqlite3LogEst(SQLITE_DEFAULT_ROWEST);
+#else
pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
-#endif
+#endif
assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable;
@@ -114366,11 +114366,11 @@ SQLITE_PRIVATE void sqlite3StartTable(
** now.
*/
if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
- int addr1;
+ int addr1;
int fileFormat;
int reg1, reg2, reg3;
- /* nullRow[] is an OP_Record encoding of a row containing 5 NULLs */
- static const char nullRow[] = { 6, 0, 0, 0, 0, 0 };
+ /* nullRow[] is an OP_Record encoding of a row containing 5 NULLs */
+ static const char nullRow[] = { 6, 0, 0, 0, 0, 0 };
sqlite3BeginWriteOperation(pParse, 1, iDb);
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -114387,12 +114387,12 @@ SQLITE_PRIVATE void sqlite3StartTable(
reg3 = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
sqlite3VdbeUsesBtree(v, iDb);
- addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
+ addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
1 : SQLITE_MAX_FILE_FORMAT;
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db));
- sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db));
+ sqlite3VdbeJumpHere(v, addr1);
/* This just creates a place-holder record in the sqlite_schema table.
** The record created does not contain anything yet. It will be replaced
@@ -114411,11 +114411,11 @@ SQLITE_PRIVATE void sqlite3StartTable(
{
assert( !pParse->bReturning );
pParse->u1.addrCrTab =
- sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY);
+ sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY);
}
sqlite3OpenSchemaTable(pParse, iDb);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
- sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
+ sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3VdbeAddOp0(v, OP_Close);
@@ -114431,19 +114431,19 @@ begin_table_error:
return;
}
-/* Set properties of a table column based on the (magical)
-** name of the column.
+/* Set properties of a table column based on the (magical)
+** name of the column.
*/
-#if SQLITE_ENABLE_HIDDEN_COLUMNS
-SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
+#if SQLITE_ENABLE_HIDDEN_COLUMNS
+SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
if( sqlite3_strnicmp(pCol->zCnName, "__hidden__", 10)==0 ){
- pCol->colFlags |= COLFLAG_HIDDEN;
+ pCol->colFlags |= COLFLAG_HIDDEN;
if( pTab ) pTab->tabFlags |= TF_HasHidden;
- }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){
- pTab->tabFlags |= TF_OOOHidden;
- }
-}
-#endif
+ }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){
+ pTab->tabFlags |= TF_OOOHidden;
+ }
+}
+#endif
/*
** Name of the special TEMP trigger used to implement RETURNING. The
@@ -114451,7 +114451,7 @@ SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
** with any application-generated triggers.
*/
#define RETURNING_TRIGGER_NAME "sqlite_returning"
-
+
/*
** Clean up the data structures associated with the RETURNING clause.
*/
@@ -114531,7 +114531,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){
Table *p;
int i;
char *z;
- char *zType;
+ char *zType;
Column *pCol;
sqlite3 *db = pParse->db;
u8 hName;
@@ -114587,7 +114587,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){
if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName);
memcpy(z, sName.z, sName.n);
z[sName.n] = 0;
- sqlite3Dequote(z);
+ sqlite3Dequote(z);
hName = sqlite3StrIHash(z);
for(i=0; i<p->nCol; i++){
if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zCnName)==0 ){
@@ -114606,10 +114606,10 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){
memset(pCol, 0, sizeof(p->aCol[0]));
pCol->zCnName = z;
pCol->hName = hName;
- sqlite3ColumnPropertiesFromName(p, pCol);
+ sqlite3ColumnPropertiesFromName(p, pCol);
if( sType.n==0 ){
- /* If there is no type specified, columns have the default affinity
+ /* If there is no type specified, columns have the default affinity
** 'BLOB' with a default size of 4 bytes. */
pCol->affinity = affinity;
pCol->eCType = eType;
@@ -114621,17 +114621,17 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){
}
}
#endif
- }else{
- zType = z + sqlite3Strlen30(z) + 1;
+ }else{
+ zType = z + sqlite3Strlen30(z) + 1;
memcpy(zType, sType.z, sType.n);
zType[sType.n] = 0;
- sqlite3Dequote(zType);
+ sqlite3Dequote(zType);
pCol->affinity = sqlite3AffinityType(zType, pCol);
- pCol->colFlags |= COLFLAG_HASTYPE;
- }
+ pCol->colFlags |= COLFLAG_HASTYPE;
+ }
p->nCol++;
p->nNVCol++;
- pParse->constraintName.n = 0;
+ pParse->constraintName.n = 0;
}
/*
@@ -114647,7 +114647,7 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
if( p==0 || NEVER(p->nCol<1) ) return;
pCol = &p->aCol[p->nCol-1];
pCol->notNull = (u8)onError;
- p->tabFlags |= TF_HasNotNull;
+ p->tabFlags |= TF_HasNotNull;
/* Set the uniqNotNull flag on any UNIQUE or PK indexes already created
** on this column. */
@@ -114692,7 +114692,7 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){
char aff = SQLITE_AFF_NUMERIC;
const char *zChar = 0;
- assert( zIn!=0 );
+ assert( zIn!=0 );
while( zIn[0] ){
h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff];
zIn++;
@@ -114764,12 +114764,12 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.
*/
-SQLITE_PRIVATE void sqlite3AddDefaultValue(
- Parse *pParse, /* Parsing context */
- Expr *pExpr, /* The parsed expression of the default value */
- const char *zStart, /* Start of the default value text */
- const char *zEnd /* First character past end of defaut value text */
-){
+SQLITE_PRIVATE void sqlite3AddDefaultValue(
+ Parse *pParse, /* Parsing context */
+ Expr *pExpr, /* The parsed expression of the default value */
+ const char *zStart, /* Start of the default value text */
+ const char *zEnd /* First character past end of defaut value text */
+){
Table *p;
Column *pCol;
sqlite3 *db = pParse->db;
@@ -114791,47 +114791,47 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(
** tokens that point to volatile memory.
*/
Expr x, *pDfltExpr;
- memset(&x, 0, sizeof(x));
- x.op = TK_SPAN;
- x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd);
- x.pLeft = pExpr;
- x.flags = EP_Skip;
+ memset(&x, 0, sizeof(x));
+ x.op = TK_SPAN;
+ x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd);
+ x.pLeft = pExpr;
+ x.flags = EP_Skip;
pDfltExpr = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
- sqlite3DbFree(db, x.u.zToken);
+ sqlite3DbFree(db, x.u.zToken);
sqlite3ColumnSetExpr(pParse, p, pCol, pDfltExpr);
}
}
if( IN_RENAME_OBJECT ){
sqlite3RenameExprUnmap(pParse, pExpr);
}
- sqlite3ExprDelete(db, pExpr);
+ sqlite3ExprDelete(db, pExpr);
}
/*
-** Backwards Compatibility Hack:
+** Backwards Compatibility Hack:
+**
+** Historical versions of SQLite accepted strings as column names in
+** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example:
+**
+** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim)
+** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC);
**
-** Historical versions of SQLite accepted strings as column names in
-** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example:
-**
-** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim)
-** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC);
-**
-** This is goofy. But to preserve backwards compatibility we continue to
-** accept it. This routine does the necessary conversion. It converts
-** the expression given in its argument from a TK_STRING into a TK_ID
-** if the expression is just a TK_STRING with an optional COLLATE clause.
+** This is goofy. But to preserve backwards compatibility we continue to
+** accept it. This routine does the necessary conversion. It converts
+** the expression given in its argument from a TK_STRING into a TK_ID
+** if the expression is just a TK_STRING with an optional COLLATE clause.
** If the expression is anything other than TK_STRING, the expression is
-** unchanged.
-*/
-static void sqlite3StringToId(Expr *p){
- if( p->op==TK_STRING ){
- p->op = TK_ID;
- }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){
- p->pLeft->op = TK_ID;
- }
-}
-
-/*
+** unchanged.
+*/
+static void sqlite3StringToId(Expr *p){
+ if( p->op==TK_STRING ){
+ p->op = TK_ID;
+ }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){
+ p->pLeft->op = TK_ID;
+ }
+}
+
+/*
** Tag the given column as being part of the PRIMARY KEY
*/
static void makeColumnPartOfPrimaryKey(Parse *pParse, Column *pCol){
@@ -114872,10 +114872,10 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */
){
Table *pTab = pParse->pNewTable;
- Column *pCol = 0;
+ Column *pCol = 0;
int iCol = -1, i;
int nTerm;
- if( pTab==0 ) goto primary_key_exit;
+ if( pTab==0 ) goto primary_key_exit;
if( pTab->tabFlags & TF_HasPrimaryKey ){
sqlite3ErrorMsg(pParse,
"table \"%s\" has more than one primary key", pTab->zName);
@@ -114884,33 +114884,33 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
pTab->tabFlags |= TF_HasPrimaryKey;
if( pList==0 ){
iCol = pTab->nCol - 1;
- pCol = &pTab->aCol[iCol];
+ pCol = &pTab->aCol[iCol];
makeColumnPartOfPrimaryKey(pParse, pCol);
nTerm = 1;
}else{
nTerm = pList->nExpr;
for(i=0; i<nTerm; i++){
- Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
- assert( pCExpr!=0 );
- sqlite3StringToId(pCExpr);
- if( pCExpr->op==TK_ID ){
+ Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
+ assert( pCExpr!=0 );
+ sqlite3StringToId(pCExpr);
+ if( pCExpr->op==TK_ID ){
const char *zCName;
assert( !ExprHasProperty(pCExpr, EP_IntValue) );
zCName = pCExpr->u.zToken;
- for(iCol=0; iCol<pTab->nCol; iCol++){
+ for(iCol=0; iCol<pTab->nCol; iCol++){
if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zCnName)==0 ){
- pCol = &pTab->aCol[iCol];
+ pCol = &pTab->aCol[iCol];
makeColumnPartOfPrimaryKey(pParse, pCol);
- break;
- }
+ break;
+ }
}
}
}
}
if( nTerm==1
- && pCol
+ && pCol
&& pCol->eCType==COLTYPE_INTEGER
- && sortOrder!=SQLITE_SO_DESC
+ && sortOrder!=SQLITE_SO_DESC
){
if( IN_RENAME_OBJECT && pList ){
Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr);
@@ -114928,8 +114928,8 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
"INTEGER PRIMARY KEY");
#endif
}else{
- sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
- 0, sortOrder, 0, SQLITE_IDXTYPE_PRIMARYKEY);
+ sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
+ 0, sortOrder, 0, SQLITE_IDXTYPE_PRIMARYKEY);
pList = 0;
}
@@ -115072,9 +115072,9 @@ generated_done:
** set back to prior value. But schema changes are infrequent
** and the probability of hitting the same cookie value is only
** 1 chance in 2^32. So we're safe enough.
-**
-** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments
-** the schema-version whenever the schema changes.
+**
+** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments
+** the schema-version whenever the schema changes.
*/
SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){
sqlite3 *db = pParse->db;
@@ -115163,7 +115163,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){
n += 35 + 6*p->nCol;
zStmt = sqlite3DbMallocRaw(0, n);
if( zStmt==0 ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
return 0;
}
sqlite3_snprintf(n, zStmt, "CREATE TABLE ");
@@ -115216,9 +115216,9 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
assert( pIdx->isResized==0 );
nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*N;
zExtra = sqlite3DbMallocZero(db, nByte);
- if( zExtra==0 ) return SQLITE_NOMEM_BKPT;
+ if( zExtra==0 ) return SQLITE_NOMEM_BKPT;
memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
- pIdx->azColl = (const char**)zExtra;
+ pIdx->azColl = (const char**)zExtra;
zExtra += sizeof(char*)*N;
memcpy(zExtra, pIdx->aiRowLogEst, sizeof(LogEst)*(pIdx->nKeyCol+1));
pIdx->aiRowLogEst = (LogEst*)zExtra;
@@ -115350,22 +115350,22 @@ static void recomputeColumnsNotIndexed(Index *pIdx){
** are appropriate for a WITHOUT ROWID table instead of a rowid table.
** Changes include:
**
-** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL.
+** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL.
** (2) Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY
-** into BTREE_BLOBKEY.
+** into BTREE_BLOBKEY.
** (3) Bypass the creation of the sqlite_schema table entry
** for the PRIMARY KEY as the primary key index is now
** identified by the sqlite_schema table entry of the table itself.
-** (4) Set the Index.tnum of the PRIMARY KEY Index object in the
+** (4) Set the Index.tnum of the PRIMARY KEY Index object in the
** schema to the rootpage from the main table.
** (5) Add all table columns to the PRIMARY KEY Index object
** so that the PRIMARY KEY is a covering index. The surplus
-** columns are part of KeyInfo.nAllField and are not used for
+** columns are part of KeyInfo.nAllField and are not used for
** sorting or lookup or uniqueness checks.
** (6) Replace the rowid tail on all automatically generated UNIQUE
** indices with the PRIMARY KEY columns.
-**
-** For virtual tables, only (1) is performed.
+**
+** For virtual tables, only (1) is performed.
*/
static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
Index *pIdx;
@@ -115376,22 +115376,22 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
sqlite3 *db = pParse->db;
Vdbe *v = pParse->pVdbe;
- /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
+ /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
*/
- if( !db->init.imposterTable ){
- for(i=0; i<pTab->nCol; i++){
+ if( !db->init.imposterTable ){
+ for(i=0; i<pTab->nCol; i++){
if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0
&& (pTab->aCol[i].notNull==OE_None)
){
- pTab->aCol[i].notNull = OE_Abort;
- }
- }
+ pTab->aCol[i].notNull = OE_Abort;
+ }
+ }
pTab->tabFlags |= TF_HasNotNull;
- }
-
- /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
- ** into BTREE_BLOBKEY.
- */
+ }
+
+ /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
+ ** into BTREE_BLOBKEY.
+ */
assert( !pParse->bReturning );
if( pParse->u1.addrCrTab ){
assert( v );
@@ -115403,10 +115403,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
*/
if( pTab->iPKey>=0 ){
ExprList *pList;
- Token ipkToken;
+ Token ipkToken;
sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zCnName);
pList = sqlite3ExprListAppend(pParse, 0,
- sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
+ sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
if( pList==0 ){
pTab->tabFlags &= ~TF_WithoutRowid;
return;
@@ -115417,13 +115417,13 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
pList->a[0].sortFlags = pParse->iPkSortOrder;
assert( pParse->pNewTable==pTab );
pTab->iPKey = -1;
- sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
- SQLITE_IDXTYPE_PRIMARYKEY);
+ sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
+ SQLITE_IDXTYPE_PRIMARYKEY);
if( db->mallocFailed || pParse->nErr ){
pTab->tabFlags &= ~TF_WithoutRowid;
return;
}
- pPk = sqlite3PrimaryKeyIndex(pTab);
+ pPk = sqlite3PrimaryKeyIndex(pTab);
assert( pPk->nKeyCol==1 );
}else{
pPk = sqlite3PrimaryKeyIndex(pTab);
@@ -115446,17 +115446,17 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
}
pPk->nKeyCol = j;
}
- assert( pPk!=0 );
+ assert( pPk!=0 );
pPk->isCovering = 1;
- if( !db->init.imposterTable ) pPk->uniqNotNull = 1;
+ if( !db->init.imposterTable ) pPk->uniqNotNull = 1;
nPk = pPk->nColumn = pPk->nKeyCol;
/* Bypass the creation of the PRIMARY KEY btree and the sqlite_schema
- ** table entry. This is only required if currently generating VDBE
- ** code for a CREATE TABLE (not when parsing one as part of reading
- ** a database schema). */
- if( v && pPk->tnum>0 ){
- assert( db->init.busy==0 );
+ ** table entry. This is only required if currently generating VDBE
+ ** code for a CREATE TABLE (not when parsing one as part of reading
+ ** a database schema). */
+ if( v && pPk->tnum>0 ){
+ assert( db->init.busy==0 );
sqlite3VdbeChangeOpcode(v, (int)pPk->tnum, OP_Goto);
}
@@ -115658,7 +115658,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
int iDb; /* Database in which the table lives */
Index *pIdx; /* An implied index of the table */
- if( pEnd==0 && pSelect==0 ){
+ if( pEnd==0 && pSelect==0 ){
return;
}
p = pParse->pNewTable;
@@ -115673,9 +115673,9 @@ SQLITE_PRIVATE void sqlite3EndTable(
** So do not write to the disk again. Extract the root page number
** for the table from the db->init.newTnum field. (The page number
** should have been put there by the sqliteOpenCb routine.)
- **
+ **
** If the root page number is 1, that means this is the sqlite_schema
- ** table itself. So mark it read-only.
+ ** table itself. So mark it read-only.
*/
if( db->init.busy ){
if( pSelect || (!IsOrdinaryTable(p) && db->init.newTnum) ){
@@ -115683,7 +115683,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
return;
}
p->tnum = db->init.newTnum;
- if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
+ if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
}
/* Special processing for tables that include the STRICT keyword:
@@ -115872,18 +115872,18 @@ SQLITE_PRIVATE void sqlite3EndTable(
pSelTab->nCol = 0;
pSelTab->aCol = 0;
sqlite3DeleteTable(db, pSelTab);
- sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
- sqlite3Select(pParse, pSelect, &dest);
- if( pParse->nErr ) return;
- sqlite3VdbeEndCoroutine(v, regYield);
- sqlite3VdbeJumpHere(v, addrTop - 1);
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
+ sqlite3Select(pParse, pSelect, &dest);
+ if( pParse->nErr ) return;
+ sqlite3VdbeEndCoroutine(v, regYield);
+ sqlite3VdbeJumpHere(v, addrTop - 1);
addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec);
sqlite3TableAffinity(v, p, 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid);
- sqlite3VdbeGoto(v, addrInsLoop);
+ sqlite3VdbeGoto(v, addrInsLoop);
sqlite3VdbeJumpHere(v, addrInsLoop);
sqlite3VdbeAddOp1(v, OP_Close, 1);
}
@@ -115929,7 +115929,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
if( pDb->pSchema->pSeqTab==0 ){
sqlite3NestedParse(pParse,
"CREATE TABLE %Q.sqlite_sequence(name,seq)",
- pDb->zDbSName
+ pDb->zDbSName
);
}
}
@@ -115950,11 +115950,11 @@ SQLITE_PRIVATE void sqlite3EndTable(
pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p);
if( pOld ){
assert( p==pOld ); /* Malloc must have failed inside HashInsert() */
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
return;
}
pParse->pNewTable = 0;
- db->mDbFlags |= DBFLAG_SchemaChange;
+ db->mDbFlags |= DBFLAG_SchemaChange;
/* If this is the magic sqlite_sequence table used by autoincrement,
** then record a pointer to this table in the main database structure
@@ -115988,7 +115988,7 @@ SQLITE_PRIVATE void sqlite3CreateView(
Token *pBegin, /* The CREATE token that begins the statement */
Token *pName1, /* The token that holds the name of the view */
Token *pName2, /* The token that holds the name of the view */
- ExprList *pCNames, /* Optional list of view column names */
+ ExprList *pCNames, /* Optional list of view column names */
Select *pSelect, /* A SELECT statement that will become the new view */
int isTemp, /* TRUE for a TEMPORARY view */
int noErr /* Suppress error messages if VIEW already exists */
@@ -116004,11 +116004,11 @@ SQLITE_PRIVATE void sqlite3CreateView(
if( pParse->nVar>0 ){
sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
- goto create_view_fail;
+ goto create_view_fail;
}
sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
p = pParse->pNewTable;
- if( p==0 || pParse->nErr ) goto create_view_fail;
+ if( p==0 || pParse->nErr ) goto create_view_fail;
/* Legacy versions of SQLite allowed the use of the magic "rowid" column
** on a view, even though views do not have rowids. The following flag
@@ -116022,7 +116022,7 @@ SQLITE_PRIVATE void sqlite3CreateView(
sqlite3TwoPartName(pParse, pName1, pName2, &pName);
iDb = sqlite3SchemaToIndex(db, p->pSchema);
sqlite3FixInit(&sFix, pParse, iDb, "view", pName);
- if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail;
+ if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail;
/* Make a copy of the entire SELECT statement that defines the view.
** This will force all the Expr.token.z values to be dynamically
@@ -116036,35 +116036,35 @@ SQLITE_PRIVATE void sqlite3CreateView(
}else{
p->u.view.pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
}
- p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE);
+ p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE);
p->eTabType = TABTYP_VIEW;
- if( db->mallocFailed ) goto create_view_fail;
+ if( db->mallocFailed ) goto create_view_fail;
/* Locate the end of the CREATE VIEW statement. Make sEnd point to
** the end.
*/
sEnd = pParse->sLastToken;
- assert( sEnd.z[0]!=0 || sEnd.n==0 );
- if( sEnd.z[0]!=';' ){
+ assert( sEnd.z[0]!=0 || sEnd.n==0 );
+ if( sEnd.z[0]!=';' ){
sEnd.z += sEnd.n;
}
sEnd.n = 0;
n = (int)(sEnd.z - pBegin->z);
- assert( n>0 );
+ assert( n>0 );
z = pBegin->z;
- while( sqlite3Isspace(z[n-1]) ){ n--; }
+ while( sqlite3Isspace(z[n-1]) ){ n--; }
sEnd.z = &z[n-1];
sEnd.n = 1;
/* Use sqlite3EndTable() to add the view to the schema table */
sqlite3EndTable(pParse, 0, &sEnd, 0, 0);
-
-create_view_fail:
- sqlite3SelectDelete(db, pSelect);
+
+create_view_fail:
+ sqlite3SelectDelete(db, pSelect);
if( IN_RENAME_OBJECT ){
sqlite3RenameExprlistUnmap(pParse, pCNames);
}
- sqlite3ExprListDelete(db, pCNames);
+ sqlite3ExprListDelete(db, pCNames);
return;
}
#endif /* SQLITE_OMIT_VIEW */
@@ -116082,11 +116082,11 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
int n; /* Temporarily holds the number of cursors assigned */
sqlite3 *db = pParse->db; /* Database connection for malloc errors */
#ifndef SQLITE_OMIT_VIRTUALTABLE
- int rc;
-#endif
-#ifndef SQLITE_OMIT_AUTHORIZATION
+ int rc;
+#endif
+#ifndef SQLITE_OMIT_AUTHORIZATION
sqlite3_xauth xAuth; /* Saved xAuth pointer */
-#endif
+#endif
assert( pTable );
@@ -116155,25 +116155,25 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
pTable->nCol = 0;
nErr++;
}else if( pTable->pCheck ){
- /* CREATE VIEW name(arglist) AS ...
- ** The names of the columns in the table are taken from
- ** arglist which is stored in pTable->pCheck. The pCheck field
- ** normally holds CHECK constraints on an ordinary table, but for
- ** a VIEW it holds the list of column names.
- */
+ /* CREATE VIEW name(arglist) AS ...
+ ** The names of the columns in the table are taken from
+ ** arglist which is stored in pTable->pCheck. The pCheck field
+ ** normally holds CHECK constraints on an ordinary table, but for
+ ** a VIEW it holds the list of column names.
+ */
sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
- &pTable->nCol, &pTable->aCol);
+ &pTable->nCol, &pTable->aCol);
if( db->mallocFailed==0
- && pParse->nErr==0
- && pTable->nCol==pSel->pEList->nExpr
- ){
+ && pParse->nErr==0
+ && pTable->nCol==pSel->pEList->nExpr
+ ){
sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
SQLITE_AFF_NONE);
- }
+ }
}else{
- /* CREATE VIEW name AS... without an argument list. Construct
- ** the column names from the SELECT statement that defines the view.
- */
+ /* CREATE VIEW name AS... without an argument list. Construct
+ ** the column names from the SELECT statement that defines the view.
+ */
assert( pTable->aCol==0 );
pTable->nCol = pSelTab->nCol;
pTable->aCol = pSelTab->aCol;
@@ -116183,14 +116183,14 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
}
pTable->nNVCol = pTable->nCol;
- sqlite3DeleteTable(db, pSelTab);
+ sqlite3DeleteTable(db, pSelTab);
sqlite3SelectDelete(db, pSel);
EnableLookaside;
pParse->eParseMode = eParseMode;
} else {
nErr++;
}
- pTable->pSchema->schemaFlags |= DB_UnresetViews;
+ pTable->pSchema->schemaFlags |= DB_UnresetViews;
if( db->mallocFailed ){
sqlite3DeleteColumnNames(db, pTable);
}
@@ -116210,7 +116210,7 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){
for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){
Table *pTab = sqliteHashData(i);
if( IsView(pTab) ){
- sqlite3DeleteColumnNames(db, pTab);
+ sqlite3DeleteColumnNames(db, pTab);
}
}
DbClearProperty(db, idx, DB_UnresetViews);
@@ -116353,7 +116353,7 @@ static void sqlite3ClearStatTables(
const char *zName /* Name of index or table */
){
int i;
- const char *zDbName = pParse->db->aDb[iDb].zDbSName;
+ const char *zDbName = pParse->db->aDb[iDb].zDbSName;
for(i=1; i<=4; i++){
char zTab[24];
sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i);
@@ -116406,7 +116406,7 @@ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, in
if( pTab->tabFlags & TF_Autoincrement ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.sqlite_sequence WHERE name=%Q",
- pDb->zDbSName, pTab->zName
+ pDb->zDbSName, pTab->zName
);
}
#endif
@@ -116490,7 +116490,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
assert( pName->nSrc==1 );
if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
if( noErr ) db->suppressErr++;
- assert( isView==0 || isView==LOCATE_VIEW );
+ assert( isView==0 || isView==LOCATE_VIEW );
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
if( noErr ) db->suppressErr--;
@@ -116514,7 +116514,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
{
int code;
const char *zTab = SCHEMA_TABLE(iDb);
- const char *zDb = db->aDb[iDb].zDbSName;
+ const char *zDb = db->aDb[iDb].zDbSName;
const char *zArg2 = 0;
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
goto exit_drop_table;
@@ -116700,7 +116700,7 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey(
pFKey->zTo, (void *)pFKey
);
if( pNextTo==pFKey ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
goto fk_end;
}
if( pNextTo ){
@@ -116769,7 +116769,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
- db->aDb[iDb].zDbSName ) ){
+ db->aDb[iDb].zDbSName ) ){
return;
}
#endif
@@ -116785,7 +116785,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
tnum = pIndex->tnum;
}
pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
- assert( pKey!=0 || db->mallocFailed || pParse->nErr );
+ assert( pKey!=0 || db->mallocFailed || pParse->nErr );
/* Open the sorter cursor if we are to use one. */
iSorter = pParse->nTab++;
@@ -116810,7 +116810,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
- if( IsUniqueIndex(pIndex) ){
+ if( IsUniqueIndex(pIndex) ){
int j2 = sqlite3VdbeGoto(v, 1);
addr2 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeVerifyAbortable(v, OE_Abort);
@@ -116840,7 +116840,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
*/
sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
}
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
@@ -116875,7 +116875,7 @@ SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(
p = sqlite3DbMallocZero(db, nByte + nExtra);
if( p ){
char *pExtra = ((char*)p)+ROUND8(sizeof(Index));
- p->azColl = (const char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
+ p->azColl = (const char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1);
p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol;
p->aSortOrder = (u8*)pExtra;
@@ -116919,7 +116919,7 @@ SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){
** is a primary key or unique-constraint on the most recent column added
** to the table currently under construction.
*/
-SQLITE_PRIVATE void sqlite3CreateIndex(
+SQLITE_PRIVATE void sqlite3CreateIndex(
Parse *pParse, /* All information about this parse */
Token *pName1, /* First part of index name. May be NULL */
Token *pName2, /* Second part of index name. May be NULL */
@@ -116929,8 +116929,8 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
Token *pStart, /* The CREATE token that begins this statement */
Expr *pPIWhere, /* WHERE clause for partial indices */
int sortOrder, /* Sort order of primary key when pList==NULL */
- int ifNotExist, /* Omit error if index already exists */
- u8 idxType /* The index type */
+ int ifNotExist, /* Omit error if index already exists */
+ u8 idxType /* The index type */
){
Table *pTab = 0; /* Table to be indexed */
Index *pIndex = 0; /* The index to be created */
@@ -116949,12 +116949,12 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
char *zExtra = 0; /* Extra space after the Index object */
Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
- if( db->mallocFailed || pParse->nErr>0 ){
+ if( db->mallocFailed || pParse->nErr>0 ){
+ goto exit_create_index;
+ }
+ if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
goto exit_create_index;
}
- if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
- goto exit_create_index;
- }
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto exit_create_index;
}
@@ -117085,12 +117085,12 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
if( zName==0 ){
goto exit_create_index;
}
-
- /* Automatic index names generated from within sqlite3_declare_vtab()
- ** must have names that are distinct from normal automatic index names.
- ** The following statement converts "sqlite3_autoindex..." into
- ** "sqlite3_butoindex..." in order to make the names distinct.
- ** The "vtab_err.test" test demonstrates the need of this statement. */
+
+ /* Automatic index names generated from within sqlite3_declare_vtab()
+ ** must have names that are distinct from normal automatic index names.
+ ** The following statement converts "sqlite3_autoindex..." into
+ ** "sqlite3_butoindex..." in order to make the names distinct.
+ ** The "vtab_err.test" test demonstrates the need of this statement. */
if( IN_SPECIAL_PARSE ) zName[7]++;
}
@@ -117098,7 +117098,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
*/
#ifndef SQLITE_OMIT_AUTHORIZATION
if( !IN_RENAME_OBJECT ){
- const char *zDb = pDb->zDbSName;
+ const char *zDb = pDb->zDbSName;
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
goto exit_create_index;
}
@@ -117115,17 +117115,17 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
** So create a fake list to simulate this.
*/
if( pList==0 ){
- Token prevCol;
+ Token prevCol;
Column *pCol = &pTab->aCol[pTab->nCol-1];
pCol->colFlags |= COLFLAG_UNIQUE;
sqlite3TokenInit(&prevCol, pCol->zCnName);
- pList = sqlite3ExprListAppend(pParse, 0,
- sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
+ pList = sqlite3ExprListAppend(pParse, 0,
+ sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
if( pList==0 ) goto exit_create_index;
- assert( pList->nExpr==1 );
+ assert( pList->nExpr==1 );
sqlite3ExprListSetSortOrder(pList, sortOrder, SQLITE_SO_UNDEFINED);
- }else{
- sqlite3ExprListCheckLength(pParse, pList, "index");
+ }else{
+ sqlite3ExprListCheckLength(pParse, pList, "index");
if( pParse->nErr ) goto exit_create_index;
}
@@ -117134,8 +117134,8 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
*/
for(i=0; i<pList->nExpr; i++){
Expr *pExpr = pList->a[i].pExpr;
- assert( pExpr!=0 );
- if( pExpr->op==TK_COLLATE ){
+ assert( pExpr!=0 );
+ if( pExpr->op==TK_COLLATE ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken));
}
@@ -117160,7 +117160,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
pIndex->pTable = pTab;
pIndex->onError = (u8)onError;
pIndex->uniqNotNull = onError!=OE_None;
- pIndex->idxType = idxType;
+ pIndex->idxType = idxType;
pIndex->pSchema = db->aDb[iDb].pSchema;
pIndex->nKeyCol = pList->nExpr;
if( pPIWhere ){
@@ -117178,14 +117178,14 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
sortOrderMask = 0; /* Ignore DESC */
}
- /* Analyze the list of expressions that form the terms of the index and
- ** report any errors. In the common case where the expression is exactly
- ** a table column, store that column in aiColumn[]. For general expressions,
- ** populate pIndex->aColExpr and store XN_EXPR (-2) in aiColumn[].
+ /* Analyze the list of expressions that form the terms of the index and
+ ** report any errors. In the common case where the expression is exactly
+ ** a table column, store that column in aiColumn[]. For general expressions,
+ ** populate pIndex->aColExpr and store XN_EXPR (-2) in aiColumn[].
**
- ** TODO: Issue a warning if two or more columns of the index are identical.
- ** TODO: Issue a warning if the table primary key is used as part of the
- ** index key.
+ ** TODO: Issue a warning if two or more columns of the index are identical.
+ ** TODO: Issue a warning if the table primary key is used as part of the
+ ** index key.
*/
pListItem = pList->a;
if( IN_RENAME_OBJECT ){
@@ -117193,32 +117193,32 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
pList = 0;
}
for(i=0; i<pIndex->nKeyCol; i++, pListItem++){
- Expr *pCExpr; /* The i-th index expression */
- int requestedSortOrder; /* ASC or DESC on the i-th expression */
- const char *zColl; /* Collation sequence name */
-
- sqlite3StringToId(pListItem->pExpr);
- sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0);
- if( pParse->nErr ) goto exit_create_index;
- pCExpr = sqlite3ExprSkipCollate(pListItem->pExpr);
- if( pCExpr->op!=TK_COLUMN ){
- if( pTab==pParse->pNewTable ){
- sqlite3ErrorMsg(pParse, "expressions prohibited in PRIMARY KEY and "
- "UNIQUE constraints");
- goto exit_create_index;
- }
- if( pIndex->aColExpr==0 ){
+ Expr *pCExpr; /* The i-th index expression */
+ int requestedSortOrder; /* ASC or DESC on the i-th expression */
+ const char *zColl; /* Collation sequence name */
+
+ sqlite3StringToId(pListItem->pExpr);
+ sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0);
+ if( pParse->nErr ) goto exit_create_index;
+ pCExpr = sqlite3ExprSkipCollate(pListItem->pExpr);
+ if( pCExpr->op!=TK_COLUMN ){
+ if( pTab==pParse->pNewTable ){
+ sqlite3ErrorMsg(pParse, "expressions prohibited in PRIMARY KEY and "
+ "UNIQUE constraints");
+ goto exit_create_index;
+ }
+ if( pIndex->aColExpr==0 ){
pIndex->aColExpr = pList;
pList = 0;
- }
- j = XN_EXPR;
- pIndex->aiColumn[i] = XN_EXPR;
- pIndex->uniqNotNull = 0;
- }else{
- j = pCExpr->iColumn;
- assert( j<=0x7fff );
- if( j<0 ){
- j = pTab->iPKey;
+ }
+ j = XN_EXPR;
+ pIndex->aiColumn[i] = XN_EXPR;
+ pIndex->uniqNotNull = 0;
+ }else{
+ j = pCExpr->iColumn;
+ assert( j<=0x7fff );
+ if( j<0 ){
+ j = pTab->iPKey;
}else{
if( pTab->aCol[j].notNull==0 ){
pIndex->uniqNotNull = 0;
@@ -117226,11 +117226,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){
pIndex->bHasVCol = 1;
}
- }
- pIndex->aiColumn[i] = (i16)j;
+ }
+ pIndex->aiColumn[i] = (i16)j;
}
- zColl = 0;
- if( pListItem->pExpr->op==TK_COLLATE ){
+ zColl = 0;
+ if( pListItem->pExpr->op==TK_COLLATE ){
int nColl;
assert( !ExprHasProperty(pListItem->pExpr, EP_IntValue) );
zColl = pListItem->pExpr->u.zToken;
@@ -117240,10 +117240,10 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
zColl = zExtra;
zExtra += nColl;
nExtra -= nColl;
- }else if( j>=0 ){
+ }else if( j>=0 ){
zColl = sqlite3ColumnColl(&pTab->aCol[j]);
}
- if( !zColl ) zColl = sqlite3StrBINARY;
+ if( !zColl ) zColl = sqlite3StrBINARY;
if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
}
@@ -117251,15 +117251,15 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
requestedSortOrder = pListItem->sortFlags & sortOrderMask;
pIndex->aSortOrder[i] = (u8)requestedSortOrder;
}
-
- /* Append the table key to the end of the index. For WITHOUT ROWID
- ** tables (when pPk!=0) this will be the declared PRIMARY KEY. For
- ** normal tables (when pPk==0) this will be the rowid.
- */
+
+ /* Append the table key to the end of the index. For WITHOUT ROWID
+ ** tables (when pPk!=0) this will be the declared PRIMARY KEY. For
+ ** normal tables (when pPk==0) this will be the rowid.
+ */
if( pPk ){
for(j=0; j<pPk->nKeyCol; j++){
int x = pPk->aiColumn[j];
- assert( x>=0 );
+ assert( x>=0 );
if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){
pIndex->nColumn--;
}else{
@@ -117272,27 +117272,27 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
}
assert( i==pIndex->nColumn );
}else{
- pIndex->aiColumn[i] = XN_ROWID;
- pIndex->azColl[i] = sqlite3StrBINARY;
+ pIndex->aiColumn[i] = XN_ROWID;
+ pIndex->azColl[i] = sqlite3StrBINARY;
}
sqlite3DefaultRowEst(pIndex);
if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
- /* If this index contains every column of its table, then mark
- ** it as a covering index */
+ /* If this index contains every column of its table, then mark
+ ** it as a covering index */
assert( HasRowid(pTab)
|| pTab->iPKey<0 || sqlite3TableColumnToIndex(pIndex, pTab->iPKey)>=0 );
recomputeColumnsNotIndexed(pIndex);
- if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
- pIndex->isCovering = 1;
- for(j=0; j<pTab->nCol; j++){
- if( j==pTab->iPKey ) continue;
+ if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
+ pIndex->isCovering = 1;
+ for(j=0; j<pTab->nCol; j++){
+ if( j==pTab->iPKey ) continue;
if( sqlite3TableColumnToIndex(pIndex,j)>=0 ) continue;
- pIndex->isCovering = 0;
- break;
- }
- }
-
+ pIndex->isCovering = 0;
+ break;
+ }
+ }
+
if( pTab==pParse->pNewTable ){
/* This routine has been called to create an automatic index as a
** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
@@ -117326,11 +117326,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
for(k=0; k<pIdx->nKeyCol; k++){
const char *z1;
const char *z2;
- assert( pIdx->aiColumn[k]>=0 );
+ assert( pIdx->aiColumn[k]>=0 );
if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
z1 = pIdx->azColl[k];
z2 = pIndex->azColl[k];
- if( sqlite3StrICmp(z1, z2) ) break;
+ if( sqlite3StrICmp(z1, z2) ) break;
}
if( k==pIdx->nKeyCol ){
if( pIdx->onError!=pIndex->onError ){
@@ -117349,7 +117349,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
pIdx->onError = pIndex->onError;
}
}
- if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType;
+ if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType;
if( IN_RENAME_OBJECT ){
pIndex->pNext = pParse->pNewIndex;
pParse->pNewIndex = pIndex;
@@ -117537,11 +117537,11 @@ SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol);
int i;
- /* Indexes with default row estimates should not have stat1 data */
- assert( !pIdx->hasStat1 );
-
+ /* Indexes with default row estimates should not have stat1 data */
+ assert( !pIdx->hasStat1 );
+
/* Set the first entry (number of rows in the index) to the estimated
- ** number of rows in the table, or half the number of rows in the table
+ ** number of rows in the table, or half the number of rows in the table
** for a partial index.
**
** 2020-05-27: If some of the stat data is coming from the sqlite_stat1
@@ -117608,7 +117608,7 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists
{
int code = SQLITE_DROP_INDEX;
Table *pTab = pIndex->pTable;
- const char *zDb = db->aDb[iDb].zDbSName;
+ const char *zDb = db->aDb[iDb].zDbSName;
const char *zTab = SCHEMA_TABLE(iDb);
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
goto exit_drop_index;
@@ -117720,7 +117720,7 @@ SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
sqlite3DbFree(db, pList->a[i].zName);
}
sqlite3DbFree(db, pList->a);
- sqlite3DbFreeNN(db, pList);
+ sqlite3DbFreeNN(db, pList);
}
/*
@@ -117873,10 +117873,10 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) );
if( pList==0 ) return 0;
pList->nAlloc = 1;
- pList->nSrc = 1;
- memset(&pList->a[0], 0, sizeof(pList->a[0]));
- pList->a[0].iCursor = -1;
- }else{
+ pList->nSrc = 1;
+ memset(&pList->a[0], 0, sizeof(pList->a[0]));
+ pList->a[0].iCursor = -1;
+ }else{
SrcList *pNew = sqlite3SrcListEnlarge(pParse, pList, 1, pList->nSrc);
if( pNew==0 ){
sqlite3SrcListDelete(db, pList);
@@ -117890,11 +117890,11 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
pDatabase = 0;
}
if( pDatabase ){
- pItem->zName = sqlite3NameFromToken(db, pDatabase);
- pItem->zDatabase = sqlite3NameFromToken(db, pTable);
- }else{
- pItem->zName = sqlite3NameFromToken(db, pTable);
- pItem->zDatabase = 0;
+ pItem->zName = sqlite3NameFromToken(db, pDatabase);
+ pItem->zDatabase = sqlite3NameFromToken(db, pTable);
+ }else{
+ pItem->zName = sqlite3NameFromToken(db, pTable);
+ pItem->zDatabase = 0;
}
return pList;
}
@@ -117928,14 +117928,14 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase);
sqlite3DbFree(db, pItem->zName);
if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias);
- if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
- if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
+ if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
+ if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
sqlite3DeleteTable(db, pItem->pTab);
if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect);
if( pItem->pOn ) sqlite3ExprDelete(db, pItem->pOn);
if( pItem->pUsing ) sqlite3IdListDelete(db, pItem->pUsing);
}
- sqlite3DbFreeNN(db, pList);
+ sqlite3DbFreeNN(db, pList);
}
/*
@@ -117973,10 +117973,10 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
goto append_from_error;
}
p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase);
- if( p==0 ){
+ if( p==0 ){
goto append_from_error;
}
- assert( p->nSrc>0 );
+ assert( p->nSrc>0 );
pItem = &p->a[p->nSrc-1];
assert( (pTable==0)==(pDatabase==0) );
assert( pItem->zName==0 || pDatabase!=0 );
@@ -118007,20 +118007,20 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
*/
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
assert( pIndexedBy!=0 );
- if( p && pIndexedBy->n>0 ){
+ if( p && pIndexedBy->n>0 ){
SrcItem *pItem;
- assert( p->nSrc>0 );
- pItem = &p->a[p->nSrc-1];
- assert( pItem->fg.notIndexed==0 );
- assert( pItem->fg.isIndexedBy==0 );
- assert( pItem->fg.isTabFunc==0 );
+ assert( p->nSrc>0 );
+ pItem = &p->a[p->nSrc-1];
+ assert( pItem->fg.notIndexed==0 );
+ assert( pItem->fg.isIndexedBy==0 );
+ assert( pItem->fg.isTabFunc==0 );
if( pIndexedBy->n==1 && !pIndexedBy->z ){
/* A "NOT INDEXED" clause was supplied. See parse.y
** construct "indexed_opt" for details. */
- pItem->fg.notIndexed = 1;
+ pItem->fg.notIndexed = 1;
}else{
- pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
- pItem->fg.isIndexedBy = 1;
+ pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
+ pItem->fg.isIndexedBy = 1;
assert( pItem->fg.isCte==0 ); /* No collision on union u2 */
}
}
@@ -118047,23 +118047,23 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, Src
}
/*
-** Add the list of function arguments to the SrcList entry for a
-** table-valued-function.
-*/
-SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){
- if( p ){
+** Add the list of function arguments to the SrcList entry for a
+** table-valued-function.
+*/
+SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){
+ if( p ){
SrcItem *pItem = &p->a[p->nSrc-1];
- assert( pItem->fg.notIndexed==0 );
- assert( pItem->fg.isIndexedBy==0 );
- assert( pItem->fg.isTabFunc==0 );
- pItem->u1.pFuncArg = pList;
- pItem->fg.isTabFunc = 1;
- }else{
- sqlite3ExprListDelete(pParse->db, pList);
- }
-}
-
-/*
+ assert( pItem->fg.notIndexed==0 );
+ assert( pItem->fg.isIndexedBy==0 );
+ assert( pItem->fg.isTabFunc==0 );
+ pItem->u1.pFuncArg = pList;
+ pItem->fg.isTabFunc = 1;
+ }else{
+ sqlite3ExprListDelete(pParse->db, pList);
+ }
+}
+
+/*
** When building up a FROM clause in the parser, the join operator
** is initially attached to the left operand. But the code generator
** expects the join operator to be on the right operand. This routine
@@ -118082,14 +118082,14 @@ SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){
if( p ){
int i;
for(i=p->nSrc-1; i>0; i--){
- p->a[i].fg.jointype = p->a[i-1].fg.jointype;
+ p->a[i].fg.jointype = p->a[i-1].fg.jointype;
}
- p->a[0].fg.jointype = 0;
+ p->a[0].fg.jointype = 0;
}
}
/*
-** Generate VDBE code for a BEGIN statement.
+** Generate VDBE code for a BEGIN statement.
*/
SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){
sqlite3 *db;
@@ -118119,29 +118119,29 @@ SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){
sqlite3VdbeUsesBtree(v, i);
}
}
- sqlite3VdbeAddOp0(v, OP_AutoCommit);
+ sqlite3VdbeAddOp0(v, OP_AutoCommit);
}
/*
-** Generate VDBE code for a COMMIT or ROLLBACK statement.
-** Code for ROLLBACK is generated if eType==TK_ROLLBACK. Otherwise
-** code is generated for a COMMIT.
+** Generate VDBE code for a COMMIT or ROLLBACK statement.
+** Code for ROLLBACK is generated if eType==TK_ROLLBACK. Otherwise
+** code is generated for a COMMIT.
*/
-SQLITE_PRIVATE void sqlite3EndTransaction(Parse *pParse, int eType){
+SQLITE_PRIVATE void sqlite3EndTransaction(Parse *pParse, int eType){
Vdbe *v;
- int isRollback;
+ int isRollback;
assert( pParse!=0 );
assert( pParse->db!=0 );
- assert( eType==TK_COMMIT || eType==TK_END || eType==TK_ROLLBACK );
- isRollback = eType==TK_ROLLBACK;
+ assert( eType==TK_COMMIT || eType==TK_END || eType==TK_ROLLBACK );
+ isRollback = eType==TK_ROLLBACK;
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION,
- isRollback ? "ROLLBACK" : "COMMIT", 0, 0) ){
+ isRollback ? "ROLLBACK" : "COMMIT", 0, 0) ){
return;
}
v = sqlite3GetVdbe(pParse);
if( v ){
- sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, isRollback);
+ sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, isRollback);
}
}
@@ -118191,7 +118191,7 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){
db->aDb[1].pBt = pBt;
assert( db->aDb[1].pSchema );
if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, 0, 0) ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
return 1;
}
}
@@ -118230,7 +118230,7 @@ SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb)
int i;
for(i=0; i<db->nDb; i++){
Db *pDb = &db->aDb[i];
- if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zDbSName)) ){
+ if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zDbSName)) ){
sqlite3CodeVerifySchema(pParse, i);
}
}
@@ -118310,7 +118310,7 @@ SQLITE_PRIVATE void sqlite3HaltConstraint(
sqlite3MayAbort(pParse);
}
sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
- sqlite3VdbeChangeP5(v, p5Errmsg);
+ sqlite3VdbeChangeP5(v, p5Errmsg);
}
/*
@@ -118328,18 +118328,18 @@ SQLITE_PRIVATE void sqlite3UniqueConstraint(
sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0,
pParse->db->aLimit[SQLITE_LIMIT_LENGTH]);
- if( pIdx->aColExpr ){
+ if( pIdx->aColExpr ){
sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
- }else{
- for(j=0; j<pIdx->nKeyCol; j++){
- char *zCol;
- assert( pIdx->aiColumn[j]>=0 );
+ }else{
+ for(j=0; j<pIdx->nKeyCol; j++){
+ char *zCol;
+ assert( pIdx->aiColumn[j]>=0 );
zCol = pTab->aCol[pIdx->aiColumn[j]].zCnName;
if( j ) sqlite3_str_append(&errMsg, ", ", 2);
sqlite3_str_appendall(&errMsg, pTab->zName);
sqlite3_str_append(&errMsg, ".", 1);
sqlite3_str_appendall(&errMsg, zCol);
- }
+ }
}
zErr = sqlite3StrAccumFinish(&errMsg);
sqlite3HaltConstraint(pParse,
@@ -118484,7 +118484,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
if( iDb<0 ) return;
z = sqlite3NameFromToken(db, pObjName);
if( z==0 ) return;
- zDb = db->aDb[iDb].zDbSName;
+ zDb = db->aDb[iDb].zDbSName;
pTab = sqlite3FindTable(db, z, zDb);
if( pTab ){
reindexTable(pParse, pTab, 0);
@@ -118522,25 +118522,25 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
if( pKey ){
assert( sqlite3KeyInfoIsWriteable(pKey) );
for(i=0; i<nCol; i++){
- const char *zColl = pIdx->azColl[i];
- pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 :
+ const char *zColl = pIdx->azColl[i];
+ pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 :
sqlite3LocateCollSeq(pParse, zColl);
pKey->aSortFlags[i] = pIdx->aSortOrder[i];
assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) );
}
if( pParse->nErr ){
- assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
- if( pIdx->bNoQuery==0 ){
- /* Deactivate the index because it contains an unknown collating
- ** sequence. The only way to reactive the index is to reload the
- ** schema. Adding the missing collating sequence later does not
- ** reactive the index. The application had the chance to register
- ** the missing index using the collation-needed callback. For
- ** simplicity, SQLite will not give the application a second chance.
- */
- pIdx->bNoQuery = 1;
- pParse->rc = SQLITE_ERROR_RETRY;
- }
+ assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
+ if( pIdx->bNoQuery==0 ){
+ /* Deactivate the index because it contains an unknown collating
+ ** sequence. The only way to reactive the index is to reload the
+ ** schema. Adding the missing collating sequence later does not
+ ** reactive the index. The application had the chance to register
+ ** the missing index using the collation-needed callback. For
+ ** simplicity, SQLite will not give the application a second chance.
+ */
+ pIdx->bNoQuery = 1;
+ pParse->rc = SQLITE_ERROR_RETRY;
+ }
sqlite3KeyInfoUnref(pKey);
pKey = 0;
}
@@ -118634,9 +118634,9 @@ SQLITE_PRIVATE With *sqlite3WithAdd(
}else{
pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
}
- assert( (pNew!=0 && zName!=0) || db->mallocFailed );
+ assert( (pNew!=0 && zName!=0) || db->mallocFailed );
- if( db->mallocFailed ){
+ if( db->mallocFailed ){
sqlite3CteDelete(db, pCte);
pNew = pWith;
}else{
@@ -118742,7 +118742,7 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
** from the main database is substituted, if one is available.
*/
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
- if( pColl && pColl->xCmp==0 ){
+ if( pColl && pColl->xCmp==0 ){
const char *zName = pColl->zName;
sqlite3 *db = pParse->db;
CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName);
@@ -118778,8 +118778,8 @@ static CollSeq *findCollSeqEntry(
pColl = sqlite3HashFind(&db->aCollSeq, zName);
if( 0==pColl && create ){
- int nName = sqlite3Strlen30(zName) + 1;
- pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName);
+ int nName = sqlite3Strlen30(zName) + 1;
+ pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName);
if( pColl ){
CollSeq *pDel = 0;
pColl[0].zName = (char*)&pColl[3];
@@ -118797,7 +118797,7 @@ static CollSeq *findCollSeqEntry(
*/
assert( pDel==0 || pDel==pColl );
if( pDel!=0 ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
sqlite3DbFree(db, pDel);
pColl = 0;
}
@@ -118955,8 +118955,8 @@ SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
** 5: UTF16 byte order conversion required - argument count matches exactly
** 6: Perfect match: encoding and argument count match exactly.
**
-** If nArg==(-2) then any function with a non-null xSFunc is
-** a perfect match and any function with xSFunc NULL is
+** If nArg==(-2) then any function with a non-null xSFunc is
+** a perfect match and any function with xSFunc NULL is
** a non-match.
*/
#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */
@@ -118998,12 +118998,12 @@ static int matchQuality(
*/
SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(
int h, /* Hash of the name */
- const char *zFunc /* Name of function */
+ const char *zFunc /* Name of function */
){
FuncDef *p;
- for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
+ for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
assert( p->funcFlags & SQLITE_FUNC_BUILTIN );
- if( sqlite3StrICmp(p->zName, zFunc)==0 ){
+ if( sqlite3StrICmp(p->zName, zFunc)==0 ){
return p;
}
}
@@ -119013,28 +119013,28 @@ SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(
/*
** Insert a new FuncDef into a FuncDefHash hash table.
*/
-SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
- FuncDef *aDef, /* List of global functions to be inserted */
- int nDef /* Length of the apDef[] list */
+SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
+ FuncDef *aDef, /* List of global functions to be inserted */
+ int nDef /* Length of the apDef[] list */
){
- int i;
- for(i=0; i<nDef; i++){
- FuncDef *pOther;
- const char *zName = aDef[i].zName;
- int nName = sqlite3Strlen30(zName);
+ int i;
+ for(i=0; i<nDef; i++){
+ FuncDef *pOther;
+ const char *zName = aDef[i].zName;
+ int nName = sqlite3Strlen30(zName);
int h = SQLITE_FUNC_HASH(zName[0], nName);
- assert( zName[0]>='a' && zName[0]<='z' );
+ assert( zName[0]>='a' && zName[0]<='z' );
assert( aDef[i].funcFlags & SQLITE_FUNC_BUILTIN );
pOther = sqlite3FunctionSearch(h, zName);
- if( pOther ){
- assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
- aDef[i].pNext = pOther->pNext;
- pOther->pNext = &aDef[i];
- }else{
- aDef[i].pNext = 0;
- aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h];
- sqlite3BuiltinFunctions.a[h] = &aDef[i];
- }
+ if( pOther ){
+ assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
+ aDef[i].pNext = pOther->pNext;
+ pOther->pNext = &aDef[i];
+ }else{
+ aDef[i].pNext = 0;
+ aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h];
+ sqlite3BuiltinFunctions.a[h] = &aDef[i];
+ }
}
}
@@ -119051,7 +119051,7 @@ SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
** no matching function previously existed.
**
** If nArg is -2, then the first valid function found is returned. A
-** function is valid if xSFunc is non-zero. The nArg==(-2)
+** function is valid if xSFunc is non-zero. The nArg==(-2)
** case is used to see if zName is a valid function name for some number
** of arguments. If nArg is -2, then createFlag must be 0.
**
@@ -119061,7 +119061,7 @@ SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
*/
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
sqlite3 *db, /* An open database */
- const char *zName, /* Name of the function. zero-terminated */
+ const char *zName, /* Name of the function. zero-terminated */
int nArg, /* Number of arguments. -1 means any number */
u8 enc, /* Preferred text encoding */
u8 createFlag /* Create new entry if true and does not otherwise exist */
@@ -119070,15 +119070,15 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
FuncDef *pBest = 0; /* Best match found so far */
int bestScore = 0; /* Score of best match */
int h; /* Hash value */
- int nName; /* Length of the name */
+ int nName; /* Length of the name */
assert( nArg>=(-2) );
assert( nArg>=(-1) || createFlag==0 );
- nName = sqlite3Strlen30(zName);
+ nName = sqlite3Strlen30(zName);
/* First search for a match amongst the application-defined functions.
*/
- p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName);
+ p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName);
while( p ){
int score = matchQuality(p, nArg, enc);
if( score>bestScore ){
@@ -119090,7 +119090,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
/* If no match is found, search the built-in functions.
**
- ** If the DBFLAG_PreferBuiltin flag is set, then search the built-in
+ ** If the DBFLAG_PreferBuiltin flag is set, then search the built-in
** functions even if a prior app-defined function was found. And give
** priority to built-in functions.
**
@@ -119100,7 +119100,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
** new function. But the FuncDefs for built-in functions are read-only.
** So we must not search for built-ins when creating a new function.
*/
- if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
+ if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
bestScore = 0;
h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
p = sqlite3FunctionSearch(h, zName);
@@ -119120,24 +119120,24 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
*/
if( createFlag && bestScore<FUNC_PERFECT_MATCH &&
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
- FuncDef *pOther;
+ FuncDef *pOther;
u8 *z;
- pBest->zName = (const char*)&pBest[1];
+ pBest->zName = (const char*)&pBest[1];
pBest->nArg = (u16)nArg;
pBest->funcFlags = enc;
- memcpy((char*)&pBest[1], zName, nName+1);
+ memcpy((char*)&pBest[1], zName, nName+1);
for(z=(u8*)pBest->zName; *z; z++) *z = sqlite3UpperToLower[*z];
- pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
- if( pOther==pBest ){
- sqlite3DbFree(db, pBest);
- sqlite3OomFault(db);
- return 0;
- }else{
- pBest->pNext = pOther;
- }
+ pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
+ if( pOther==pBest ){
+ sqlite3DbFree(db, pBest);
+ sqlite3OomFault(db);
+ return 0;
+ }else{
+ pBest->pNext = pOther;
+ }
}
- if( pBest && (pBest->xSFunc || createFlag) ){
+ if( pBest && (pBest->xSFunc || createFlag) ){
return pBest;
}
return 0;
@@ -119176,7 +119176,7 @@ SQLITE_PRIVATE void sqlite3SchemaClear(void *p){
if( pSchema->schemaFlags & DB_SchemaLoaded ){
pSchema->iGeneration++;
}
- pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted);
+ pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted);
}
/*
@@ -119191,7 +119191,7 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){
p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema));
}
if( !p ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
}else if ( 0==p->file_format ){
sqlite3HashInit(&p->tblHash);
sqlite3HashInit(&p->idxHash);
@@ -119242,7 +119242,7 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
sqlite3DeleteTable(pParse->db, pItem->pTab);
pItem->pTab = pTab;
if( pTab ){
- pTab->nTabRef++;
+ pTab->nTabRef++;
if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){
pTab = 0;
}
@@ -119309,8 +119309,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
Parse *pParse, /* Parsing context */
Table *pView, /* View definition */
Expr *pWhere, /* Optional WHERE clause to be added */
- ExprList *pOrderBy, /* Optional ORDER BY clause */
- Expr *pLimit, /* Optional LIMIT clause */
+ ExprList *pOrderBy, /* Optional ORDER BY clause */
+ Expr *pLimit, /* Optional LIMIT clause */
int iCur /* Cursor number for ephemeral table */
){
SelectDest dest;
@@ -119323,12 +119323,12 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
if( pFrom ){
assert( pFrom->nSrc==1 );
pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
- pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
+ pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
assert( pFrom->a[0].pOn==0 );
assert( pFrom->a[0].pUsing==0 );
}
pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy,
- SF_IncludeHidden, pLimit);
+ SF_IncludeHidden, pLimit);
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite3Select(pParse, pSel, &dest);
sqlite3SelectDelete(db, pSel);
@@ -119352,21 +119352,21 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
Expr *pLimit, /* The LIMIT clause. May be null */
char *zStmtType /* Either DELETE or UPDATE. For err msgs. */
){
- sqlite3 *db = pParse->db;
- Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */
+ sqlite3 *db = pParse->db;
+ Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */
Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */
ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */
SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */
Select *pSelect = NULL; /* Complete SELECT tree */
- Table *pTab;
+ Table *pTab;
/* Check that there isn't an ORDER BY without a LIMIT clause.
*/
- if( pOrderBy && pLimit==0 ) {
+ if( pOrderBy && pLimit==0 ) {
sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
- sqlite3ExprDelete(pParse->db, pWhere);
- sqlite3ExprListDelete(pParse->db, pOrderBy);
- return 0;
+ sqlite3ExprDelete(pParse->db, pWhere);
+ sqlite3ExprListDelete(pParse->db, pOrderBy);
+ return 0;
}
/* We only need to generate a select expression if there
@@ -119385,36 +119385,36 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
** );
*/
- pTab = pSrc->a[0].pTab;
- if( HasRowid(pTab) ){
- pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0);
- pEList = sqlite3ExprListAppend(
- pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0)
- );
- }else{
- Index *pPk = sqlite3PrimaryKeyIndex(pTab);
- if( pPk->nKeyCol==1 ){
+ pTab = pSrc->a[0].pTab;
+ if( HasRowid(pTab) ){
+ pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0);
+ pEList = sqlite3ExprListAppend(
+ pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0)
+ );
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ if( pPk->nKeyCol==1 ){
const char *zName = pTab->aCol[pPk->aiColumn[0]].zCnName;
- pLhs = sqlite3Expr(db, TK_ID, zName);
- pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName));
- }else{
- int i;
- for(i=0; i<pPk->nKeyCol; i++){
+ pLhs = sqlite3Expr(db, TK_ID, zName);
+ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName));
+ }else{
+ int i;
+ for(i=0; i<pPk->nKeyCol; i++){
Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zCnName);
- pEList = sqlite3ExprListAppend(pParse, pEList, p);
- }
- pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
- if( pLhs ){
- pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0);
- }
- }
- }
+ pEList = sqlite3ExprListAppend(pParse, pEList, p);
+ }
+ pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( pLhs ){
+ pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0);
+ }
+ }
+ }
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
** and the SELECT subtree. */
- pSrc->a[0].pTab = 0;
+ pSrc->a[0].pTab = 0;
pSelectSrc = sqlite3SrcListDup(db, pSrc, 0);
- pSrc->a[0].pTab = pTab;
+ pSrc->a[0].pTab = pTab;
if( pSrc->a[0].fg.isIndexedBy ){
assert( pSrc->a[0].fg.isCte==0 );
pSrc->a[0].u2.pIBIndex = 0;
@@ -119426,12 +119426,12 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
/* generate the SELECT expression tree. */
pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0,
- pOrderBy,0,pLimit
- );
+ pOrderBy,0,pLimit
+ );
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
- pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0);
- sqlite3PExprAddSelect(pParse, pInClause, pSelect);
+ pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0);
+ sqlite3PExprAddSelect(pParse, pInClause, pSelect);
return pInClause;
}
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */
@@ -119447,9 +119447,9 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
SQLITE_PRIVATE void sqlite3DeleteFrom(
Parse *pParse, /* The parser context */
SrcList *pTabList, /* The table from which we should delete things */
- Expr *pWhere, /* The WHERE clause. May be null */
- ExprList *pOrderBy, /* ORDER BY clause. May be null */
- Expr *pLimit /* LIMIT clause. May be null */
+ Expr *pWhere, /* The WHERE clause. May be null */
+ ExprList *pOrderBy, /* ORDER BY clause. May be null */
+ Expr *pLimit /* LIMIT clause. May be null */
){
Vdbe *v; /* The virtual database engine */
Table *pTab; /* The table from which records will be deleted */
@@ -119466,7 +119466,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
int iDb; /* Database number */
int memCnt = 0; /* Memory cell used for change counting */
int rcauth; /* Value returned by authorization callback */
- int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */
+ int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */
int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */
Index *pPk; /* The PRIMARY KEY index on the table */
@@ -119479,8 +119479,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
int addrBypass = 0; /* Address of jump over the delete logic */
int addrLoop = 0; /* Top of the delete loop */
int addrEphOpen = 0; /* Instruction to open the Ephemeral table */
- int bComplex; /* True if there are triggers or FKs or
- ** subqueries in the WHERE clause */
+ int bComplex; /* True if there are triggers or FKs or
+ ** subqueries in the WHERE clause */
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True if attempting to delete from a view */
@@ -119494,7 +119494,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
}
assert( pTabList->nSrc==1 );
-
+
/* Locate the table which we want to delete. This table has to be
** put in an SrcList structure because some of the subroutines we
** will be calling are designed to work with multiple tables and expect
@@ -119513,22 +119513,22 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
# define pTrigger 0
# define isView 0
#endif
- bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
+ bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif
-#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
- if( !isView ){
- pWhere = sqlite3LimitWhere(
- pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE"
- );
- pOrderBy = 0;
- pLimit = 0;
- }
-#endif
-
+#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
+ if( !isView ){
+ pWhere = sqlite3LimitWhere(
+ pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE"
+ );
+ pOrderBy = 0;
+ pLimit = 0;
+ }
+#endif
+
/* If pTab is really a view, make sure it has been initialized.
*/
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
@@ -119541,7 +119541,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb<db->nDb );
rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0,
- db->aDb[iDb].zDbSName);
+ db->aDb[iDb].zDbSName);
assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
if( rcauth==SQLITE_DENY ){
goto delete_from_cleanup;
@@ -119577,11 +119577,11 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
sqlite3MaterializeView(pParse, pTab,
- pWhere, pOrderBy, pLimit, iTabCur
- );
+ pWhere, pOrderBy, pLimit, iTabCur
+ );
iDataCur = iIdxCur = iTabCur;
- pOrderBy = 0;
- pLimit = 0;
+ pOrderBy = 0;
+ pLimit = 0;
}
#endif
@@ -119610,21 +119610,21 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
/* Special case: A DELETE without a WHERE clause deletes everything.
** It is easier just to erase the whole table. Prior to version 3.6.5,
** this optimization caused the row change count (the value returned by
- ** API function sqlite3_count_changes) to be set incorrectly.
- **
- ** The "rcauth==SQLITE_OK" terms is the
- ** IMPLEMENTATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and
- ** the callback returns SQLITE_IGNORE then the DELETE operation proceeds but
- ** the truncate optimization is disabled and all rows are deleted
- ** individually.
- */
- if( rcauth==SQLITE_OK
- && pWhere==0
- && !bComplex
- && !IsVirtual(pTab)
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
- && db->xPreUpdateCallback==0
-#endif
+ ** API function sqlite3_count_changes) to be set incorrectly.
+ **
+ ** The "rcauth==SQLITE_OK" terms is the
+ ** IMPLEMENTATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and
+ ** the callback returns SQLITE_IGNORE then the DELETE operation proceeds but
+ ** the truncate optimization is disabled and all rows are deleted
+ ** individually.
+ */
+ if( rcauth==SQLITE_OK
+ && pWhere==0
+ && !bComplex
+ && !IsVirtual(pTab)
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ && db->xPreUpdateCallback==0
+#endif
){
assert( !isView );
sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
@@ -119643,8 +119643,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
{
u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK;
- if( sNC.ncFlags & NC_VarSelect ) bComplex = 1;
- wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
+ if( sNC.ncFlags & NC_VarSelect ) bComplex = 1;
+ wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
if( HasRowid(pTab) ){
/* For a rowid table, initialize the RowSet to an empty set */
pPk = 0;
@@ -119665,18 +119665,18 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
}
/* Construct a query to find the rowid or primary key for every row
- ** to be deleted, based on the WHERE clause. Set variable eOnePass
- ** to indicate the strategy used to implement this delete:
- **
- ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
- ** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
- ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
+ ** to be deleted, based on the WHERE clause. Set variable eOnePass
+ ** to indicate the strategy used to implement this delete:
+ **
+ ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
+ ** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
+ ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
*/
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
if( pWInfo==0 ) goto delete_from_cleanup;
- eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
- assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
- assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
+ eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+ assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
+ assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
if( sqlite3WhereUsesDeferredSeek(pWInfo) ){
sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur);
@@ -119690,7 +119690,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
/* Extract the rowid or primary key for the current row */
if( pPk ){
for(i=0; i<nPk; i++){
- assert( pPk->aiColumn[i]>=0 );
+ assert( pPk->aiColumn[i]>=0 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
pPk->aiColumn[i], iPk+i);
}
@@ -119700,12 +119700,12 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey);
}
- if( eOnePass!=ONEPASS_OFF ){
- /* For ONEPASS, no need to store the rowid/primary-key. There is only
+ if( eOnePass!=ONEPASS_OFF ){
+ /* For ONEPASS, no need to store the rowid/primary-key. There is only
** one, so just keep it in its register(s) and fall through to the
- ** delete code. */
+ ** delete code. */
nKey = nPk; /* OP_Found will use an unpacked key */
- aToOpen = sqlite3DbMallocRawNN(db, nIdx+2);
+ aToOpen = sqlite3DbMallocRawNN(db, nIdx+2);
if( aToOpen==0 ){
sqlite3WhereEnd(pWInfo);
goto delete_from_cleanup;
@@ -119717,19 +119717,19 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen);
addrBypass = sqlite3VdbeMakeLabel(pParse);
}else{
- if( pPk ){
- /* Add the PK key for this row to the temporary table */
- iKey = ++pParse->nMem;
- nKey = 0; /* Zero tells OP_Found to use a composite key */
- sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
- sqlite3IndexAffinityStr(pParse->db, pPk), nPk);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk);
- }else{
- /* Add the rowid of the row to be deleted to the RowSet */
- nKey = 1; /* OP_DeferredSeek always uses a single rowid */
- sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
- }
- sqlite3WhereEnd(pWInfo);
+ if( pPk ){
+ /* Add the PK key for this row to the temporary table */
+ iKey = ++pParse->nMem;
+ nKey = 0; /* Zero tells OP_Found to use a composite key */
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
+ sqlite3IndexAffinityStr(pParse->db, pPk), nPk);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk);
+ }else{
+ /* Add the rowid of the row to be deleted to the RowSet */
+ nKey = 1; /* OP_DeferredSeek always uses a single rowid */
+ sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
+ }
+ sqlite3WhereEnd(pWInfo);
}
/* Unless this is a view, open cursors for the table we are
@@ -119738,13 +119738,13 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
** triggers.
*/
if( !isView ){
- int iAddrOnce = 0;
- if( eOnePass==ONEPASS_MULTI ){
- iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
- }
+ int iAddrOnce = 0;
+ if( eOnePass==ONEPASS_MULTI ){
+ iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ }
testcase( IsVirtual(pTab) );
- sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE,
- iTabCur, aToOpen, &iDataCur, &iIdxCur);
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE,
+ iTabCur, aToOpen, &iDataCur, &iIdxCur);
assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
if( eOnePass==ONEPASS_MULTI ){
@@ -119755,20 +119755,20 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
/* Set up a loop over the rowids/primary-keys that were found in the
** where-clause loop above.
*/
- if( eOnePass!=ONEPASS_OFF ){
+ if( eOnePass!=ONEPASS_OFF ){
assert( nKey==nPk ); /* OP_Found will use an unpacked key */
- if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){
+ if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){
assert( pPk!=0 || IsView(pTab) );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
VdbeCoverage(v);
}
}else if( pPk ){
addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
- if( IsVirtual(pTab) ){
- sqlite3VdbeAddOp3(v, OP_Column, iEphCur, 0, iKey);
- }else{
- sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey);
- }
+ if( IsVirtual(pTab) ){
+ sqlite3VdbeAddOp3(v, OP_Column, iEphCur, 0, iKey);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey);
+ }
assert( nKey==0 ); /* OP_Found will use a composite key */
}else{
addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
@@ -119781,14 +119781,14 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
if( IsVirtual(pTab) ){
const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
sqlite3VtabMakeWritable(pParse, pTab);
- assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
+ assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
sqlite3MayAbort(pParse);
if( eOnePass==ONEPASS_SINGLE ){
sqlite3VdbeAddOp1(v, OP_Close, iTabCur);
if( sqlite3IsToplevel(pParse) ){
pParse->isMultiWrite = 0;
}
- }
+ }
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
sqlite3VdbeChangeP5(v, OE_Abort);
}else
@@ -119796,18 +119796,18 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
{
int count = (pParse->nested==0); /* True to count changes */
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
- iKey, nKey, count, OE_Default, eOnePass, aiCurOnePass[1]);
+ iKey, nKey, count, OE_Default, eOnePass, aiCurOnePass[1]);
}
/* End of the loop over all rowids/primary-keys. */
- if( eOnePass!=ONEPASS_OFF ){
+ if( eOnePass!=ONEPASS_OFF ){
sqlite3VdbeResolveLabel(v, addrBypass);
- sqlite3WhereEnd(pWInfo);
+ sqlite3WhereEnd(pWInfo);
}else if( pPk ){
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addrLoop);
}else{
- sqlite3VdbeGoto(v, addrLoop);
+ sqlite3VdbeGoto(v, addrLoop);
sqlite3VdbeJumpHere(v, addrLoop);
}
} /* End non-truncate path */
@@ -119835,9 +119835,9 @@ delete_from_cleanup:
sqlite3SrcListDelete(db, pTabList);
sqlite3ExprDelete(db, pWhere);
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
- sqlite3ExprListDelete(db, pOrderBy);
- sqlite3ExprDelete(db, pLimit);
-#endif
+ sqlite3ExprListDelete(db, pOrderBy);
+ sqlite3ExprDelete(db, pLimit);
+#endif
sqlite3DbFree(db, aToOpen);
return;
}
@@ -119870,27 +119870,27 @@ delete_from_cleanup:
** sequence of nPk memory cells starting at iPk. If nPk==0 that means
** that a search record formed from OP_MakeRecord is contained in the
** single memory location iPk.
-**
-** eMode:
-** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or
-** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor
-** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF
-** then this function must seek iDataCur to the entry identified by iPk
-** and nPk before reading from it.
-**
-** If eMode is ONEPASS_MULTI, then this call is being made as part
+**
+** eMode:
+** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or
+** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor
+** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF
+** then this function must seek iDataCur to the entry identified by iPk
+** and nPk before reading from it.
+**
+** If eMode is ONEPASS_MULTI, then this call is being made as part
** of a ONEPASS delete that affects multiple rows. In this case, if
-** iIdxNoSeek is a valid cursor number (>=0) and is not the same as
-** iDataCur, then its position should be preserved following the delete
-** operation. Or, if iIdxNoSeek is not a valid cursor number, the
-** position of iDataCur should be preserved instead.
-**
-** iIdxNoSeek:
-** If iIdxNoSeek is a valid cursor number (>=0) not equal to iDataCur,
-** then it identifies an index cursor (from within array of cursors
-** starting at iIdxCur) that already points to the index entry to be deleted.
-** Except, this optimization is disabled if there are BEFORE triggers since
-** the trigger body might have moved the cursor.
+** iIdxNoSeek is a valid cursor number (>=0) and is not the same as
+** iDataCur, then its position should be preserved following the delete
+** operation. Or, if iIdxNoSeek is not a valid cursor number, the
+** position of iDataCur should be preserved instead.
+**
+** iIdxNoSeek:
+** If iIdxNoSeek is a valid cursor number (>=0) not equal to iDataCur,
+** then it identifies an index cursor (from within array of cursors
+** starting at iIdxCur) that already points to the index entry to be deleted.
+** Except, this optimization is disabled if there are BEFORE triggers since
+** the trigger body might have moved the cursor.
*/
SQLITE_PRIVATE void sqlite3GenerateRowDelete(
Parse *pParse, /* Parsing context */
@@ -119902,8 +119902,8 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
i16 nPk, /* Number of PRIMARY KEY memory cells */
u8 count, /* If non-zero, increment the row change counter */
u8 onconf, /* Default ON CONFLICT policy for triggers */
- u8 eMode, /* ONEPASS_OFF, _SINGLE, or _MULTI. See above */
- int iIdxNoSeek /* Cursor number of cursor that does not need seeking */
+ u8 eMode, /* ONEPASS_OFF, _SINGLE, or _MULTI. See above */
+ int iIdxNoSeek /* Cursor number of cursor that does not need seeking */
){
Vdbe *v = pParse->pVdbe; /* Vdbe */
int iOld = 0; /* First register in OLD.* array */
@@ -119920,7 +119920,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
** not attempt to delete it or fire any DELETE triggers. */
iLabel = sqlite3VdbeMakeLabel(pParse);
opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
- if( eMode==ONEPASS_OFF ){
+ if( eMode==ONEPASS_OFF ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
VdbeCoverageIf(v, opSeek==OP_NotExists);
VdbeCoverageIf(v, opSeek==OP_NotFound);
@@ -119962,18 +119962,18 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
/* If any BEFORE triggers were coded, then seek the cursor to the
** row to be deleted again. It may be that the BEFORE triggers moved
- ** the cursor or already deleted the row that the cursor was
+ ** the cursor or already deleted the row that the cursor was
** pointing to.
- **
- ** Also disable the iIdxNoSeek optimization since the BEFORE trigger
- ** may have moved that cursor.
+ **
+ ** Also disable the iIdxNoSeek optimization since the BEFORE trigger
+ ** may have moved that cursor.
*/
if( addrStart<sqlite3VdbeCurrentAddr(v) ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
VdbeCoverageIf(v, opSeek==OP_NotExists);
VdbeCoverageIf(v, opSeek==OP_NotFound);
- testcase( iIdxNoSeek>=0 );
- iIdxNoSeek = -1;
+ testcase( iIdxNoSeek>=0 );
+ iIdxNoSeek = -1;
}
/* Do FK processing. This call checks that any FK constraints that
@@ -119985,28 +119985,28 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
/* Delete the index and table entries. Skip this step if pTab is really
** a view (in which case the only effect of the DELETE statement is to
** fire the INSTEAD OF triggers).
- **
- ** If variable 'count' is non-zero, then this OP_Delete instruction should
- ** invoke the update-hook. The pre-update-hook, on the other hand should
- ** be invoked unless table pTab is a system table. The difference is that
+ **
+ ** If variable 'count' is non-zero, then this OP_Delete instruction should
+ ** invoke the update-hook. The pre-update-hook, on the other hand should
+ ** be invoked unless table pTab is a system table. The difference is that
** the update-hook is not invoked for rows removed by REPLACE, but the
- ** pre-update-hook is.
+ ** pre-update-hook is.
*/
if( !IsView(pTab) ){
- u8 p5 = 0;
- sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
+ u8 p5 = 0;
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
- if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){
- sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE);
+ if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){
+ sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE);
+ }
+ if( eMode!=ONEPASS_OFF ){
+ sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE);
}
- if( eMode!=ONEPASS_OFF ){
- sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE);
- }
- if( iIdxNoSeek>=0 && iIdxNoSeek!=iDataCur ){
- sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);
- }
- if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION;
- sqlite3VdbeChangeP5(v, p5);
+ if( iIdxNoSeek>=0 && iIdxNoSeek!=iDataCur ){
+ sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);
+ }
+ if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION;
+ sqlite3VdbeChangeP5(v, p5);
}
/* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
@@ -120049,8 +120049,8 @@ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
Table *pTab, /* Table containing the row to be deleted */
int iDataCur, /* Cursor of table holding data. */
int iIdxCur, /* First index cursor */
- int *aRegIdx, /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
- int iIdxNoSeek /* Do not delete from this cursor */
+ int *aRegIdx, /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
+ int iIdxNoSeek /* Do not delete from this cursor */
){
int i; /* Index loop counter */
int r1 = -1; /* Register holding an index key */
@@ -120066,12 +120066,12 @@ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
assert( iIdxCur+i!=iDataCur || pPk==pIdx );
if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
if( pIdx==pPk ) continue;
- if( iIdxCur+i==iIdxNoSeek ) continue;
+ if( iIdxCur+i==iIdxNoSeek ) continue;
VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
- &iPartIdxLabel, pPrior, r1);
+ &iPartIdxLabel, pPrior, r1);
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
- pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
+ pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
sqlite3VdbeChangeP5(v, 1); /* Cause IdxDelete to error if no entry found */
sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
pPrior = pIdx;
@@ -120127,10 +120127,10 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
if( piPartIdxLabel ){
if( pIdx->pPartIdxWhere ){
*piPartIdxLabel = sqlite3VdbeMakeLabel(pParse);
- pParse->iSelfTab = iDataCur + 1;
+ pParse->iSelfTab = iDataCur + 1;
sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
SQLITE_JUMPIFNULL);
- pParse->iSelfTab = 0;
+ pParse->iSelfTab = 0;
pPrior = 0; /* Ticket a9efb42811fa41ee 2019-11-02;
** pPartIdxWhere may have corrupted regPrior registers */
}else{
@@ -120141,14 +120141,14 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
regBase = sqlite3GetTempRange(pParse, nCol);
if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;
for(j=0; j<nCol; j++){
- if( pPrior
- && pPrior->aiColumn[j]==pIdx->aiColumn[j]
- && pPrior->aiColumn[j]!=XN_EXPR
- ){
- /* This column was already computed by the previous index */
- continue;
- }
- sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j);
+ if( pPrior
+ && pPrior->aiColumn[j]==pIdx->aiColumn[j]
+ && pPrior->aiColumn[j]!=XN_EXPR
+ ){
+ /* This column was already computed by the previous index */
+ continue;
+ }
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j);
if( pIdx->aiColumn[j]>=0 ){
/* If the column affinity is REAL but the number is an integer, then it
** might be stored in the table as an integer (using a compact
@@ -120262,20 +120262,20 @@ static void typeofFunc(
int NotUsed,
sqlite3_value **argv
){
- static const char *azType[] = { "integer", "real", "text", "blob", "null" };
- int i = sqlite3_value_type(argv[0]) - 1;
+ static const char *azType[] = { "integer", "real", "text", "blob", "null" };
+ int i = sqlite3_value_type(argv[0]) - 1;
UNUSED_PARAMETER(NotUsed);
- assert( i>=0 && i<ArraySize(azType) );
- assert( SQLITE_INTEGER==1 );
- assert( SQLITE_FLOAT==2 );
- assert( SQLITE_TEXT==3 );
- assert( SQLITE_BLOB==4 );
- assert( SQLITE_NULL==5 );
- /* EVIDENCE-OF: R-01470-60482 The sqlite3_value_type(V) interface returns
- ** the datatype code for the initial datatype of the sqlite3_value object
- ** V. The returned value is one of SQLITE_INTEGER, SQLITE_FLOAT,
- ** SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL. */
- sqlite3_result_text(context, azType[i], -1, SQLITE_STATIC);
+ assert( i>=0 && i<ArraySize(azType) );
+ assert( SQLITE_INTEGER==1 );
+ assert( SQLITE_FLOAT==2 );
+ assert( SQLITE_TEXT==3 );
+ assert( SQLITE_BLOB==4 );
+ assert( SQLITE_NULL==5 );
+ /* EVIDENCE-OF: R-01470-60482 The sqlite3_value_type(V) interface returns
+ ** the datatype code for the initial datatype of the sqlite3_value object
+ ** V. The returned value is one of SQLITE_INTEGER, SQLITE_FLOAT,
+ ** SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL. */
+ sqlite3_result_text(context, azType[i], -1, SQLITE_STATIC);
}
@@ -120395,15 +120395,15 @@ static void instrFunc(
if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
nHaystack = sqlite3_value_bytes(argv[0]);
nNeedle = sqlite3_value_bytes(argv[1]);
- if( nNeedle>0 ){
- if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
- zHaystack = sqlite3_value_blob(argv[0]);
- zNeedle = sqlite3_value_blob(argv[1]);
- isText = 0;
+ if( nNeedle>0 ){
+ if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
+ zHaystack = sqlite3_value_blob(argv[0]);
+ zNeedle = sqlite3_value_blob(argv[1]);
+ isText = 0;
}else if( typeHaystack!=SQLITE_BLOB && typeNeedle!=SQLITE_BLOB ){
- zHaystack = sqlite3_value_text(argv[0]);
- zNeedle = sqlite3_value_text(argv[1]);
- isText = 1;
+ zHaystack = sqlite3_value_text(argv[0]);
+ zNeedle = sqlite3_value_text(argv[1]);
+ isText = 1;
}else{
pC1 = sqlite3_value_dup(argv[0]);
zHaystack = sqlite3_value_text(pC1);
@@ -120414,19 +120414,19 @@ static void instrFunc(
if( zNeedle==0 ) goto endInstrOOM;
nNeedle = sqlite3_value_bytes(pC2);
isText = 1;
- }
+ }
if( zNeedle==0 || (nHaystack && zHaystack==0) ) goto endInstrOOM;
firstChar = zNeedle[0];
while( nNeedle<=nHaystack
&& (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0)
){
- N++;
- do{
- nHaystack--;
- zHaystack++;
- }while( isText && (zHaystack[0]&0xc0)==0x80 );
- }
- if( nNeedle>nHaystack ) N = 0;
+ N++;
+ do{
+ nHaystack--;
+ zHaystack++;
+ }while( isText && (zHaystack[0]&0xc0)==0x80 );
+ }
+ if( nNeedle>nHaystack ) N = 0;
}
sqlite3_result_int(context, N);
endInstr:
@@ -120457,7 +120457,7 @@ static void printfFunc(
x.nUsed = 0;
x.apArg = argv+1;
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
- str.printfFlags = SQLITE_PRINTF_SQLFUNC;
+ str.printfFlags = SQLITE_PRINTF_SQLFUNC;
sqlite3_str_appendf(&str, zFormat, &x);
n = str.nChar;
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
@@ -120786,10 +120786,10 @@ static void total_changes(
** A structure defining how to do GLOB-style comparisons.
*/
struct compareInfo {
- u8 matchAll; /* "*" or "%" */
- u8 matchOne; /* "?" or "_" */
- u8 matchSet; /* "[" or 0 */
- u8 noCase; /* true to ignore case differences */
+ u8 matchAll; /* "*" or "%" */
+ u8 matchOne; /* "?" or "_" */
+ u8 matchSet; /* "[" or 0 */
+ u8 noCase; /* true to ignore case differences */
};
/*
@@ -120814,20 +120814,20 @@ static const struct compareInfo likeInfoNorm = { '%', '_', 0, 1 };
static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
/*
-** Possible error returns from patternMatch()
-*/
-#define SQLITE_MATCH 0
-#define SQLITE_NOMATCH 1
-#define SQLITE_NOWILDCARDMATCH 2
-
-/*
-** Compare two UTF-8 strings for equality where the first string is
-** a GLOB or LIKE expression. Return values:
-**
-** SQLITE_MATCH: Match
-** SQLITE_NOMATCH: No match
-** SQLITE_NOWILDCARDMATCH: No match in spite of having * or % wildcards.
-**
+** Possible error returns from patternMatch()
+*/
+#define SQLITE_MATCH 0
+#define SQLITE_NOMATCH 1
+#define SQLITE_NOWILDCARDMATCH 2
+
+/*
+** Compare two UTF-8 strings for equality where the first string is
+** a GLOB or LIKE expression. Return values:
+**
+** SQLITE_MATCH: Match
+** SQLITE_NOMATCH: No match
+** SQLITE_NOWILDCARDMATCH: No match in spite of having * or % wildcards.
+**
** Globbing rules:
**
** '*' Matches any sequence of zero or more characters.
@@ -120862,7 +120862,7 @@ static int patternCompare(
const u8 *zPattern, /* The glob pattern */
const u8 *zString, /* The string to compare against the glob */
const struct compareInfo *pInfo, /* Information about how to do the compare */
- u32 matchOther /* The escape char (LIKE) or '[' (GLOB) */
+ u32 matchOther /* The escape char (LIKE) or '[' (GLOB) */
){
u32 c, c2; /* Next pattern and input string chars */
u32 matchOne = pInfo->matchOne; /* "?" or "_" */
@@ -120878,31 +120878,31 @@ static int patternCompare(
while( (c=Utf8Read(zPattern)) == matchAll
|| (c == matchOne && matchOne!=0) ){
if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
- return SQLITE_NOWILDCARDMATCH;
+ return SQLITE_NOWILDCARDMATCH;
}
}
if( c==0 ){
- return SQLITE_MATCH; /* "*" at the end of the pattern matches */
+ return SQLITE_MATCH; /* "*" at the end of the pattern matches */
}else if( c==matchOther ){
- if( pInfo->matchSet==0 ){
+ if( pInfo->matchSet==0 ){
c = sqlite3Utf8Read(&zPattern);
- if( c==0 ) return SQLITE_NOWILDCARDMATCH;
+ if( c==0 ) return SQLITE_NOWILDCARDMATCH;
}else{
/* "[...]" immediately follows the "*". We have to do a slow
** recursive search in this case, but it is an unusual case. */
assert( matchOther<0x80 ); /* '[' is a single-byte character */
- while( *zString ){
- int bMatch = patternCompare(&zPattern[-1],zString,pInfo,matchOther);
- if( bMatch!=SQLITE_NOMATCH ) return bMatch;
+ while( *zString ){
+ int bMatch = patternCompare(&zPattern[-1],zString,pInfo,matchOther);
+ if( bMatch!=SQLITE_NOMATCH ) return bMatch;
SQLITE_SKIP_UTF8(zString);
}
- return SQLITE_NOWILDCARDMATCH;
+ return SQLITE_NOWILDCARDMATCH;
}
}
/* At this point variable c contains the first character of the
** pattern string past the "*". Search in the input string for the
- ** first matching character and recursively continue the match from
+ ** first matching character and recursively continue the match from
** that point.
**
** For a case-insensitive search, set variable cx to be the same as
@@ -120910,44 +120910,44 @@ static int patternCompare(
** c or cx.
*/
if( c<=0x80 ){
- char zStop[3];
- int bMatch;
+ char zStop[3];
+ int bMatch;
if( noCase ){
- zStop[0] = sqlite3Toupper(c);
- zStop[1] = sqlite3Tolower(c);
- zStop[2] = 0;
+ zStop[0] = sqlite3Toupper(c);
+ zStop[1] = sqlite3Tolower(c);
+ zStop[2] = 0;
}else{
- zStop[0] = c;
- zStop[1] = 0;
+ zStop[0] = c;
+ zStop[1] = 0;
}
- while(1){
- zString += strcspn((const char*)zString, zStop);
- if( zString[0]==0 ) break;
- zString++;
- bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
- if( bMatch!=SQLITE_NOMATCH ) return bMatch;
+ while(1){
+ zString += strcspn((const char*)zString, zStop);
+ if( zString[0]==0 ) break;
+ zString++;
+ bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
+ if( bMatch!=SQLITE_NOMATCH ) return bMatch;
}
}else{
- int bMatch;
+ int bMatch;
while( (c2 = Utf8Read(zString))!=0 ){
if( c2!=c ) continue;
- bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
- if( bMatch!=SQLITE_NOMATCH ) return bMatch;
+ bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
+ if( bMatch!=SQLITE_NOMATCH ) return bMatch;
}
}
- return SQLITE_NOWILDCARDMATCH;
+ return SQLITE_NOWILDCARDMATCH;
}
if( c==matchOther ){
- if( pInfo->matchSet==0 ){
+ if( pInfo->matchSet==0 ){
c = sqlite3Utf8Read(&zPattern);
- if( c==0 ) return SQLITE_NOMATCH;
+ if( c==0 ) return SQLITE_NOMATCH;
zEscaped = zPattern;
}else{
u32 prior_c = 0;
int seen = 0;
int invert = 0;
c = sqlite3Utf8Read(&zString);
- if( c==0 ) return SQLITE_NOMATCH;
+ if( c==0 ) return SQLITE_NOMATCH;
c2 = sqlite3Utf8Read(&zPattern);
if( c2=='^' ){
invert = 1;
@@ -120971,39 +120971,39 @@ static int patternCompare(
c2 = sqlite3Utf8Read(&zPattern);
}
if( c2==0 || (seen ^ invert)==0 ){
- return SQLITE_NOMATCH;
+ return SQLITE_NOMATCH;
}
continue;
}
}
c2 = Utf8Read(zString);
if( c==c2 ) continue;
- if( noCase && sqlite3Tolower(c)==sqlite3Tolower(c2) && c<0x80 && c2<0x80 ){
+ if( noCase && sqlite3Tolower(c)==sqlite3Tolower(c2) && c<0x80 && c2<0x80 ){
continue;
}
if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
- return SQLITE_NOMATCH;
+ return SQLITE_NOMATCH;
}
- return *zString==0 ? SQLITE_MATCH : SQLITE_NOMATCH;
+ return *zString==0 ? SQLITE_MATCH : SQLITE_NOMATCH;
+}
+
+/*
+** The sqlite3_strglob() interface. Return 0 on a match (like strcmp()) and
+** non-zero if there is no match.
+*/
+SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){
+ return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[');
}
/*
-** The sqlite3_strglob() interface. Return 0 on a match (like strcmp()) and
-** non-zero if there is no match.
+** The sqlite3_strlike() interface. Return 0 on a match and non-zero for
+** a miss - like strcmp().
*/
-SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){
- return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[');
+SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
+ return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc);
}
/*
-** The sqlite3_strlike() interface. Return 0 on a match and non-zero for
-** a miss - like strcmp().
-*/
-SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
- return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc);
-}
-
-/*
** Count the number of times that the LIKE operator (or GLOB which is
** just a variation of LIKE) gets called. This is used for testing
** only.
@@ -121031,23 +121031,23 @@ static void likeFunc(
sqlite3_value **argv
){
const unsigned char *zA, *zB;
- u32 escape;
+ u32 escape;
int nPat;
sqlite3 *db = sqlite3_context_db_handle(context);
- struct compareInfo *pInfo = sqlite3_user_data(context);
+ struct compareInfo *pInfo = sqlite3_user_data(context);
struct compareInfo backupInfo;
-#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
- if( sqlite3_value_type(argv[0])==SQLITE_BLOB
- || sqlite3_value_type(argv[1])==SQLITE_BLOB
- ){
-#ifdef SQLITE_TEST
- sqlite3_like_count++;
-#endif
- sqlite3_result_int(context, 0);
- return;
- }
-#endif
+#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ if( sqlite3_value_type(argv[0])==SQLITE_BLOB
+ || sqlite3_value_type(argv[1])==SQLITE_BLOB
+ ){
+#ifdef SQLITE_TEST
+ sqlite3_like_count++;
+#endif
+ sqlite3_result_int(context, 0);
+ return;
+ }
+#endif
/* Limit the length of the LIKE or GLOB pattern to avoid problems
** of deep recursion and N*N behavior in patternCompare().
@@ -121077,8 +121077,8 @@ static void likeFunc(
if( escape==pInfo->matchAll ) pInfo->matchAll = 0;
if( escape==pInfo->matchOne ) pInfo->matchOne = 0;
}
- }else{
- escape = pInfo->matchSet;
+ }else{
+ escape = pInfo->matchSet;
}
zB = sqlite3_value_text(argv[0]);
zA = sqlite3_value_text(argv[1]);
@@ -121086,8 +121086,8 @@ static void likeFunc(
#ifdef SQLITE_TEST
sqlite3_like_count++;
#endif
- sqlite3_result_int(context,
- patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
+ sqlite3_result_int(context,
+ patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
}
}
@@ -121572,26 +121572,26 @@ static void trimFunc(
}
-#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
-/*
-** The "unknown" function is automatically substituted in place of
-** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN
-** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used.
-** When the "sqlite3" command-line shell is built using this functionality,
-** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries
-** involving application-defined functions to be examined in a generic
-** sqlite3 shell.
-*/
-static void unknownFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- /* no-op */
-}
-#endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/
-
-
+#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
+/*
+** The "unknown" function is automatically substituted in place of
+** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN
+** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used.
+** When the "sqlite3" command-line shell is built using this functionality,
+** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries
+** involving application-defined functions to be examined in a generic
+** sqlite3 shell.
+*/
+static void unknownFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ /* no-op */
+}
+#endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/
+
+
/* IMP: R-25361-16150 This function is omitted from SQLite by default. It
** is only available if the SQLITE_SOUNDEX compile-time option is used
** when SQLite is built.
@@ -121662,14 +121662,14 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
sqlite3 *db = sqlite3_context_db_handle(context);
char *zErrMsg = 0;
- /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc
- ** flag is set. See the sqlite3_enable_load_extension() API.
- */
- if( (db->flags & SQLITE_LoadExtFunc)==0 ){
- sqlite3_result_error(context, "not authorized", -1);
- return;
- }
-
+ /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc
+ ** flag is set. See the sqlite3_enable_load_extension() API.
+ */
+ if( (db->flags & SQLITE_LoadExtFunc)==0 ){
+ sqlite3_result_error(context, "not authorized", -1);
+ return;
+ }
+
if( argc==2 ){
zProc = (const char *)sqlite3_value_text(argv[1]);
}else{
@@ -122069,11 +122069,11 @@ static void groupConcatValue(sqlite3_context *context){
** of the built-in functions above are part of the global function set.
** This routine only deals with those that are not global.
*/
-SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
+SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
int rc = sqlite3_overload_function(db, "MATCH", 2);
assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
if( rc==SQLITE_NOMEM ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
}
}
@@ -122101,15 +122101,15 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive)
/*
** pExpr points to an expression which implements a function. If
** it is appropriate to apply the LIKE optimization to that function
-** then set aWc[0] through aWc[2] to the wildcard characters and the
+** then set aWc[0] through aWc[2] to the wildcard characters and the
** escape character and then return TRUE. If the function is not a
-** LIKE-style function then return FALSE.
+** LIKE-style function then return FALSE.
+**
+** The expression "a LIKE b ESCAPE c" is only considered a valid LIKE
+** operator if c is a string literal that is exactly one byte in length.
+** That one byte is stored in aWc[3]. aWc[3] is set to zero if there is
+** no ESCAPE clause.
**
-** The expression "a LIKE b ESCAPE c" is only considered a valid LIKE
-** operator if c is a string literal that is exactly one byte in length.
-** That one byte is stored in aWc[3]. aWc[3] is set to zero if there is
-** no ESCAPE clause.
-**
** *pIsNocase is set to true if uppercase and lowercase are equivalent for
** the function (default for LIKE). If the function makes the distinction
** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to
@@ -122117,16 +122117,16 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive)
*/
SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
FuncDef *pDef;
- int nExpr;
+ int nExpr;
assert( pExpr!=0 );
assert( pExpr->op==TK_FUNCTION );
assert( ExprUseXList(pExpr) );
if( !pExpr->x.pList ){
return 0;
}
- nExpr = pExpr->x.pList->nExpr;
+ nExpr = pExpr->x.pList->nExpr;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0);
+ pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0);
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
if( pDef==0 ) return 0;
#endif
@@ -122143,19 +122143,19 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas
assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
- if( nExpr<3 ){
- aWc[3] = 0;
- }else{
- Expr *pEscape = pExpr->x.pList->a[2].pExpr;
- char *zEscape;
- if( pEscape->op!=TK_STRING ) return 0;
+ if( nExpr<3 ){
+ aWc[3] = 0;
+ }else{
+ Expr *pEscape = pExpr->x.pList->a[2].pExpr;
+ char *zEscape;
+ if( pEscape->op!=TK_STRING ) return 0;
assert( !ExprHasProperty(pEscape, EP_IntValue) );
- zEscape = pEscape->u.zToken;
- if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
+ zEscape = pEscape->u.zToken;
+ if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
if( zEscape[0]==aWc[0] ) return 0;
if( zEscape[0]==aWc[1] ) return 0;
- aWc[3] = zEscape[0];
- }
+ aWc[3] = zEscape[0];
+ }
*pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0;
return 1;
@@ -122363,7 +122363,7 @@ static void signFunc(
**
** After this routine runs
*/
-SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
+SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
/*
** The following array holds FuncDef structures for all of the functions
** defined in this file.
@@ -122371,10 +122371,10 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
** The array cannot be constant since changes are made to the
** FuncDef.pHash elements at start-time. The elements of this array
** are read-only after initialization is complete.
- **
- ** For peak efficiency, put the most frequently used function last.
+ **
+ ** For peak efficiency, put the most frequently used function last.
*/
- static FuncDef aBuiltinFunc[] = {
+ static FuncDef aBuiltinFunc[] = {
/***** Functions only available with SQLITE_TESTCTRL_INTERNAL_FUNCTIONS *****/
#if !defined(SQLITE_UNTESTABLE)
TEST_FUNC(implies_nonnull_row, 2, INLINEFUNC_implies_nonnull_row, 0),
@@ -122383,27 +122383,27 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
TEST_FUNC(affinity, 1, INLINEFUNC_affinity, 0),
#endif /* !defined(SQLITE_UNTESTABLE) */
/***** Regular functions *****/
-#ifdef SQLITE_SOUNDEX
- FUNCTION(soundex, 1, 0, 0, soundexFunc ),
-#endif
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
+#ifdef SQLITE_SOUNDEX
+ FUNCTION(soundex, 1, 0, 0, soundexFunc ),
+#endif
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
SFUNCTION(load_extension, 1, 0, 0, loadExt ),
SFUNCTION(load_extension, 2, 0, 0, loadExt ),
-#endif
-#if SQLITE_USER_AUTHENTICATION
- FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
-#endif
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
- DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
- DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
+#endif
+#if SQLITE_USER_AUTHENTICATION
+ FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
+#endif
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
+ DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
+#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
- FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET|
- SQLITE_FUNC_TYPEOF),
-#endif
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+ FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET|
+ SQLITE_FUNC_TYPEOF),
+#endif
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
@@ -122436,8 +122436,8 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
VFUNCTION(random, 0, 0, 0, randomFunc ),
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
- DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
- DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
+ DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
+ DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
FUNCTION(quote, 1, 0, 0, quoteFunc ),
VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
@@ -122445,8 +122445,8 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
VFUNCTION(total_changes, 0, 0, 0, total_changes ),
FUNCTION(replace, 3, 0, 0, replaceFunc ),
FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
- FUNCTION(substr, 2, 0, 0, substrFunc ),
- FUNCTION(substr, 3, 0, 0, substrFunc ),
+ FUNCTION(substr, 2, 0, 0, substrFunc ),
+ FUNCTION(substr, 3, 0, 0, substrFunc ),
FUNCTION(substring, 2, 0, 0, substrFunc ),
FUNCTION(substring, 3, 0, 0, substrFunc ),
WAGGREGATE(sum, 1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0),
@@ -122463,18 +122463,18 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
-#ifdef SQLITE_CASE_SENSITIVE_LIKE
+#ifdef SQLITE_CASE_SENSITIVE_LIKE
LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
-#else
+#else
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
-#endif
-#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
- FUNCTION(unknown, -1, 0, 0, unknownFunc ),
-#endif
- FUNCTION(coalesce, 1, 0, 0, 0 ),
- FUNCTION(coalesce, 0, 0, 0, 0 ),
+#endif
+#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
+ FUNCTION(unknown, -1, 0, 0, unknownFunc ),
+#endif
+ FUNCTION(coalesce, 1, 0, 0, 0 ),
+ FUNCTION(coalesce, 0, 0, 0, 0 ),
#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
MFUNCTION(ceil, 1, xCeil, ceilingFunc ),
MFUNCTION(ceiling, 1, xCeil, ceilingFunc ),
@@ -122519,25 +122519,25 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
sqlite3AlterFunctions();
#endif
sqlite3WindowFunctions();
- sqlite3RegisterDateTimeFunctions();
- sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));
-
-#if 0 /* Enable to print out how the built-in functions are hashed */
- {
- int i;
- FuncDef *p;
- for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
- printf("FUNC-HASH %02d:", i);
- for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){
- int n = sqlite3Strlen30(p->zName);
- int h = p->zName[0] + n;
+ sqlite3RegisterDateTimeFunctions();
+ sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));
+
+#if 0 /* Enable to print out how the built-in functions are hashed */
+ {
+ int i;
+ FuncDef *p;
+ for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
+ printf("FUNC-HASH %02d:", i);
+ for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){
+ int n = sqlite3Strlen30(p->zName);
+ int h = p->zName[0] + n;
assert( p->funcFlags & SQLITE_FUNC_BUILTIN );
- printf(" %s(%d)", p->zName, h);
- }
- printf("\n");
- }
- }
-#endif
+ printf(" %s(%d)", p->zName, h);
+ }
+ printf("\n");
+ }
+ }
+#endif
}
/************** End of func.c ************************************************/
@@ -122765,7 +122765,7 @@ SQLITE_PRIVATE int sqlite3FkLocateIndex(
}
}else if( paiCol ){
assert( nCol>1 );
- aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int));
+ aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int));
if( !aiCol ) return 1;
*paiCol = aiCol;
}
@@ -122795,16 +122795,16 @@ SQLITE_PRIVATE int sqlite3FkLocateIndex(
int i, j;
for(i=0; i<nCol; i++){
i16 iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
- const char *zDfltColl; /* Def. collation for column */
+ const char *zDfltColl; /* Def. collation for column */
char *zIdxCol; /* Name of indexed column */
- if( iCol<0 ) break; /* No foreign keys against expression indexes */
-
+ if( iCol<0 ) break; /* No foreign keys against expression indexes */
+
/* If the index uses a collation sequence that is different from
** the default collation sequence for the column, this index is
** unusable. Bail out early in this case. */
zDfltColl = sqlite3ColumnColl(&pParent->aCol[iCol]);
- if( !zDfltColl ) zDfltColl = sqlite3StrBINARY;
+ if( !zDfltColl ) zDfltColl = sqlite3StrBINARY;
if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break;
zIdxCol = pParent->aCol[iCol].zCnName;
@@ -122927,7 +122927,7 @@ static void fkLookupParent(
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v);
- sqlite3VdbeGoto(v, iOk);
+ sqlite3VdbeGoto(v, iOk);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
sqlite3VdbeJumpHere(v, iMustBeInt);
sqlite3ReleaseTempReg(pParse, regTemp);
@@ -122962,7 +122962,7 @@ static void fkLookupParent(
int iParent = 1+regData;
iParent += sqlite3TableColumnToStorage(pIdx->pTable,
pIdx->aiColumn[i]);
- assert( pIdx->aiColumn[i]>=0 );
+ assert( pIdx->aiColumn[i]>=0 );
assert( aiCol[i]!=pTab->iPKey );
if( pIdx->aiColumn[i]==pTab->iPKey ){
/* The parent key is a composite key that includes the IPK column */
@@ -122971,11 +122971,11 @@ static void fkLookupParent(
sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
}
- sqlite3VdbeGoto(v, iOk);
+ sqlite3VdbeGoto(v, iOk);
}
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
- sqlite3IndexAffinityStr(pParse->db,pIdx), nCol);
+ sqlite3IndexAffinityStr(pParse->db,pIdx), nCol);
sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, regRec);
@@ -123143,7 +123143,7 @@ static void fkScanChildren(
assert( iCol>=0 );
zCol = pFKey->pFrom->aCol[iCol].zCnName;
pRight = sqlite3Expr(db, TK_ID, zCol);
- pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
+ pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
}
@@ -123168,19 +123168,19 @@ static void fkScanChildren(
if( HasRowid(pTab) ){
pLeft = exprTableRegister(pParse, pTab, regData, -1);
pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1);
- pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
+ pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
}else{
Expr *pEq, *pAll = 0;
assert( pIdx!=0 );
for(i=0; i<pIdx->nKeyCol; i++){
i16 iCol = pIdx->aiColumn[i];
- assert( iCol>=0 );
+ assert( iCol>=0 );
pLeft = exprTableRegister(pParse, pTab, regData, iCol);
pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zCnName);
pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
pAll = sqlite3ExprAnd(pParse, pAll, pEq);
}
- pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
+ pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
}
pWhere = sqlite3ExprAnd(pParse, pWhere, pNe);
}
@@ -123194,12 +123194,12 @@ static void fkScanChildren(
/* Create VDBE to loop through the entries in pSrc that match the WHERE
** clause. For each row found, increment either the deferred or immediate
** foreign key constraint counter. */
- if( pParse->nErr==0 ){
- pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
- sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
- if( pWInfo ){
- sqlite3WhereEnd(pWInfo);
- }
+ if( pParse->nErr==0 ){
+ pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
+ sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
+ if( pWInfo ){
+ sqlite3WhereEnd(pWInfo);
+ }
}
/* Clean up the WHERE clause constructed above. */
@@ -123306,7 +123306,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
}
pParse->disableTriggers = 1;
- sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0);
+ sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0);
pParse->disableTriggers = 0;
/* If the DELETE has generated immediate foreign key constraint
@@ -123456,7 +123456,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
if( !IsOrdinaryTable(pTab) ) return;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- zDb = db->aDb[iDb].zDbSName;
+ zDb = db->aDb[iDb].zDbSName;
/* Loop through all the foreign key constraints for which pTab is the
** child table (the table that the foreign key definition is part of). */
@@ -123520,7 +123520,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
if( aiCol[i]==pTab->iPKey ){
aiCol[i] = -1;
}
- assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
+ assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
#ifndef SQLITE_OMIT_AUTHORIZATION
/* Request permission to read the parent key columns. If the
** authorization callback returns SQLITE_IGNORE, behave as if any
@@ -123594,7 +123594,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
SrcItem *pItem = pSrc->a;
pItem->pTab = pFKey->pFrom;
pItem->zName = pFKey->pFrom->zName;
- pItem->pTab->nTabRef++;
+ pItem->pTab->nTabRef++;
pItem->iCursor = pParse->nTab++;
if( regNew!=0 ){
@@ -123652,10 +123652,10 @@ SQLITE_PRIVATE u32 sqlite3FkOldmask(
Index *pIdx = 0;
sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
if( pIdx ){
- for(i=0; i<pIdx->nKeyCol; i++){
- assert( pIdx->aiColumn[i]>=0 );
- mask |= COLUMN_MASK(pIdx->aiColumn[i]);
- }
+ for(i=0; i<pIdx->nKeyCol; i++){
+ assert( pIdx->aiColumn[i]>=0 );
+ mask |= COLUMN_MASK(pIdx->aiColumn[i]);
+ }
}
}
}
@@ -123675,17 +123675,17 @@ SQLITE_PRIVATE u32 sqlite3FkOldmask(
**
** If any foreign key processing will be required, this function returns
** non-zero. If there is no foreign key related processing, this function
-** returns zero.
-**
-** For an UPDATE, this function returns 2 if:
-**
+** returns zero.
+**
+** For an UPDATE, this function returns 2 if:
+**
** * There are any FKs for which pTab is the child and the parent table
** and any FK processing at all is required (even of a different FK), or
**
-** * the UPDATE modifies one or more parent keys for which the action is
-** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL).
-**
-** Or, assuming some other foreign key processing is required, 1.
+** * the UPDATE modifies one or more parent keys for which the action is
+** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL).
+**
+** Or, assuming some other foreign key processing is required, 1.
*/
SQLITE_PRIVATE int sqlite3FkRequired(
Parse *pParse, /* Parse context */
@@ -123708,18 +123708,18 @@ SQLITE_PRIVATE int sqlite3FkRequired(
/* Check if any child key columns are being modified. */
for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){
- if( fkChildIsModified(pTab, p, aChange, chngRowid) ){
+ if( fkChildIsModified(pTab, p, aChange, chngRowid) ){
if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2;
bHaveFK = 1;
- }
+ }
}
/* Check if any parent key columns are being modified. */
for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
- if( fkParentIsModified(pTab, p, aChange, chngRowid) ){
- if( p->aAction[1]!=OE_None ) return 2;
+ if( fkParentIsModified(pTab, p, aChange, chngRowid) ){
+ if( p->aAction[1]!=OE_None ) return 2;
bHaveFK = 1;
- }
+ }
}
}
}
@@ -123767,9 +123767,9 @@ static Trigger *fkActionTrigger(
int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */
action = pFKey->aAction[iAction];
- if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){
- return 0;
- }
+ if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){
+ return 0;
+ }
pTrigger = pFKey->apTrigger[iAction];
if( action!=OE_None && !pTrigger ){
@@ -123798,8 +123798,8 @@ static Trigger *fkActionTrigger(
iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iFromCol>=0 );
assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
- assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
- sqlite3TokenInit(&tToCol,
+ assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
+ sqlite3TokenInit(&tToCol,
pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zCnName);
sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zCnName);
@@ -123810,9 +123810,9 @@ static Trigger *fkActionTrigger(
pEq = sqlite3PExpr(pParse, TK_EQ,
sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
- );
+ );
pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
/* For ON UPDATE, construct the next term of the WHEN clause.
@@ -123824,11 +123824,11 @@ static Trigger *fkActionTrigger(
pEq = sqlite3PExpr(pParse, TK_IS,
sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
- );
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
+ );
pWhen = sqlite3ExprAnd(pParse, pWhen, pEq);
}
@@ -123837,7 +123837,7 @@ static Trigger *fkActionTrigger(
if( action==OE_Cascade ){
pNew = sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0));
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0));
}else if( action==OE_SetDflt ){
Column *pCol = pFKey->pFrom->aCol + iFromCol;
Expr *pDflt;
@@ -123851,10 +123851,10 @@ static Trigger *fkActionTrigger(
if( pDflt ){
pNew = sqlite3ExprDup(db, pDflt, 0);
}else{
- pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
+ pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
}
}else{
- pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
+ pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
}
pList = sqlite3ExprListAppend(pParse, pList, pNew);
sqlite3ExprListSetName(pParse, pList, &tFromCol, 0);
@@ -123879,7 +123879,7 @@ static Trigger *fkActionTrigger(
sqlite3ExprListAppend(pParse, 0, pRaise),
sqlite3SrcListAppend(pParse, 0, &tFrom, 0),
pWhere,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0
);
pWhere = 0;
}
@@ -123901,7 +123901,7 @@ static Trigger *fkActionTrigger(
pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
if( pWhen ){
- pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0);
+ pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0);
pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
}
}
@@ -124092,7 +124092,7 @@ SQLITE_PRIVATE void sqlite3OpenTable(
** is managed along with the rest of the Index structure. It will be
** released when sqlite3DeleteIndex() is called.
*/
-SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
+SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
if( !pIdx->zColAff ){
/* The first time a column affinity string for a particular index is
** required, it is allocated and populated here. It is then stored as
@@ -124106,21 +124106,21 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
Table *pTab = pIdx->pTable;
pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1);
if( !pIdx->zColAff ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
return 0;
}
for(n=0; n<pIdx->nColumn; n++){
i16 x = pIdx->aiColumn[n];
char aff;
- if( x>=0 ){
+ if( x>=0 ){
aff = pTab->aCol[x].affinity;
- }else if( x==XN_ROWID ){
+ }else if( x==XN_ROWID ){
aff = SQLITE_AFF_INTEGER;
- }else{
- assert( x==XN_EXPR );
- assert( pIdx->aColExpr!=0 );
- aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
- }
+ }else{
+ assert( x==XN_EXPR );
+ assert( pIdx->aColExpr!=0 );
+ aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
+ }
if( aff<SQLITE_AFF_BLOB ) aff = SQLITE_AFF_BLOB;
if( aff>SQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC;
pIdx->zColAff[n] = aff;
@@ -124198,7 +124198,7 @@ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
sqlite3 *db = sqlite3VdbeDb(v);
zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
if( !zColAff ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
return;
}
@@ -124389,9 +124389,9 @@ SQLITE_PRIVATE void sqlite3ComputeGeneratedColumns(
/*
** Locate or create an AutoincInfo structure associated with table pTab
** which is in database iDb. Return the register number for the register
-** that holds the maximum rowid. Return zero if pTab is not an AUTOINCREMENT
-** table. (Also return zero when doing a VACUUM since we do not want to
-** update the AUTOINCREMENT counters during a VACUUM.)
+** that holds the maximum rowid. Return zero if pTab is not an AUTOINCREMENT
+** table. (Also return zero when doing a VACUUM since we do not want to
+** update the AUTOINCREMENT counters during a VACUUM.)
**
** There is at most one AutoincInfo structure per table even if the
** same table is autoincremented multiple times due to inserts within
@@ -124416,9 +124416,9 @@ static int autoIncBegin(
){
int memId = 0; /* Register holding maximum rowid */
assert( pParse->db->aDb[iDb].pSchema!=0 );
- if( (pTab->tabFlags & TF_Autoincrement)!=0
- && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0
- ){
+ if( (pTab->tabFlags & TF_Autoincrement)!=0
+ && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0
+ ){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
AutoincInfo *pInfo;
Table *pSeqTab = pParse->db->aDb[iDb].pSchema->pSeqTab;
@@ -124439,7 +124439,7 @@ static int autoIncBegin(
pInfo = pToplevel->pAinc;
while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
if( pInfo==0 ){
- pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo));
+ pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo));
sqlite3ParserAddCleanup(pToplevel, sqlite3DbFree, pInfo);
testcase( pParse->earlyCleanup );
if( pParse->db->mallocFailed ) return 0;
@@ -124470,41 +124470,41 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
/* This routine is never called during trigger-generation. It is
** only called from the top-level */
assert( pParse->pTriggerTab==0 );
- assert( sqlite3IsToplevel(pParse) );
+ assert( sqlite3IsToplevel(pParse) );
assert( v ); /* We failed long ago if this is not so */
for(p = pParse->pAinc; p; p = p->pNext){
- static const int iLn = VDBE_OFFSET_LINENO(2);
- static const VdbeOpList autoInc[] = {
- /* 0 */ {OP_Null, 0, 0, 0},
+ static const int iLn = VDBE_OFFSET_LINENO(2);
+ static const VdbeOpList autoInc[] = {
+ /* 0 */ {OP_Null, 0, 0, 0},
/* 1 */ {OP_Rewind, 0, 10, 0},
- /* 2 */ {OP_Column, 0, 0, 0},
+ /* 2 */ {OP_Column, 0, 0, 0},
/* 3 */ {OP_Ne, 0, 9, 0},
- /* 4 */ {OP_Rowid, 0, 0, 0},
- /* 5 */ {OP_Column, 0, 1, 0},
+ /* 4 */ {OP_Rowid, 0, 0, 0},
+ /* 5 */ {OP_Column, 0, 1, 0},
/* 6 */ {OP_AddImm, 0, 0, 0},
/* 7 */ {OP_Copy, 0, 0, 0},
/* 8 */ {OP_Goto, 0, 11, 0},
/* 9 */ {OP_Next, 0, 2, 0},
/* 10 */ {OP_Integer, 0, 0, 0},
/* 11 */ {OP_Close, 0, 0, 0}
- };
- VdbeOp *aOp;
+ };
+ VdbeOp *aOp;
pDb = &db->aDb[p->iDb];
memId = p->regCtr;
assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
- sqlite3VdbeLoadString(v, memId-1, p->pTab->zName);
- aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn);
- if( aOp==0 ) break;
- aOp[0].p2 = memId;
+ sqlite3VdbeLoadString(v, memId-1, p->pTab->zName);
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn);
+ if( aOp==0 ) break;
+ aOp[0].p2 = memId;
aOp[0].p3 = memId+2;
- aOp[2].p3 = memId;
- aOp[3].p1 = memId-1;
- aOp[3].p3 = memId;
- aOp[3].p5 = SQLITE_JUMPIFNULL;
- aOp[4].p2 = memId+1;
- aOp[5].p3 = memId;
+ aOp[2].p3 = memId;
+ aOp[3].p1 = memId-1;
+ aOp[3].p3 = memId;
+ aOp[3].p5 = SQLITE_JUMPIFNULL;
+ aOp[4].p2 = memId+1;
+ aOp[5].p3 = memId;
aOp[6].p1 = memId;
aOp[7].p2 = memId+2;
aOp[7].p1 = memId;
@@ -124516,10 +124516,10 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
/*
** Update the maximum rowid for an autoincrement calculation.
**
-** This routine should be called when the regRowid register holds a
+** This routine should be called when the regRowid register holds a
** new rowid that is about to be inserted. If that new rowid is
** larger than the maximum rowid in the memId memory cell, then the
-** memory cell is updated.
+** memory cell is updated.
*/
static void autoIncStep(Parse *pParse, int memId, int regRowid){
if( memId>0 ){
@@ -124534,22 +124534,22 @@ static void autoIncStep(Parse *pParse, int memId, int regRowid){
** table (either directly or through triggers) needs to call this
** routine just before the "exit" code.
*/
-static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){
+static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){
AutoincInfo *p;
Vdbe *v = pParse->pVdbe;
sqlite3 *db = pParse->db;
assert( v );
for(p = pParse->pAinc; p; p = p->pNext){
- static const int iLn = VDBE_OFFSET_LINENO(2);
- static const VdbeOpList autoIncEnd[] = {
- /* 0 */ {OP_NotNull, 0, 2, 0},
- /* 1 */ {OP_NewRowid, 0, 0, 0},
- /* 2 */ {OP_MakeRecord, 0, 2, 0},
- /* 3 */ {OP_Insert, 0, 0, 0},
- /* 4 */ {OP_Close, 0, 0, 0}
- };
- VdbeOp *aOp;
+ static const int iLn = VDBE_OFFSET_LINENO(2);
+ static const VdbeOpList autoIncEnd[] = {
+ /* 0 */ {OP_NotNull, 0, 2, 0},
+ /* 1 */ {OP_NewRowid, 0, 0, 0},
+ /* 2 */ {OP_MakeRecord, 0, 2, 0},
+ /* 3 */ {OP_Insert, 0, 0, 0},
+ /* 4 */ {OP_Close, 0, 0, 0}
+ };
+ VdbeOp *aOp;
Db *pDb = &db->aDb[p->iDb];
int iRec;
int memId = p->regCtr;
@@ -124559,21 +124559,21 @@ static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){
sqlite3VdbeAddOp3(v, OP_Le, memId+2, sqlite3VdbeCurrentAddr(v)+7, memId);
VdbeCoverage(v);
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
- aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn);
- if( aOp==0 ) break;
- aOp[0].p1 = memId+1;
- aOp[1].p2 = memId+1;
- aOp[2].p1 = memId-1;
- aOp[2].p3 = iRec;
- aOp[3].p2 = iRec;
- aOp[3].p3 = memId+1;
- aOp[3].p5 = OPFLAG_APPEND;
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn);
+ if( aOp==0 ) break;
+ aOp[0].p1 = memId+1;
+ aOp[1].p2 = memId+1;
+ aOp[2].p1 = memId-1;
+ aOp[2].p3 = iRec;
+ aOp[3].p2 = iRec;
+ aOp[3].p3 = memId+1;
+ aOp[3].p5 = OPFLAG_APPEND;
sqlite3ReleaseTempReg(pParse, iRec);
}
}
-SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
- if( pParse->pAinc ) autoIncrementEnd(pParse);
-}
+SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
+ if( pParse->pAinc ) autoIncrementEnd(pParse);
+}
#else
/*
** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines
@@ -124700,7 +124700,7 @@ SQLITE_PRIVATE void sqlite3Insert(
){
sqlite3 *db; /* The main database structure */
Table *pTab; /* The table to insert into. aka TABLE */
- int i, j; /* Loop counters */
+ int i, j; /* Loop counters */
Vdbe *v; /* Generate code into this virtual machine */
Index *pIdx; /* For looping over indices of the table */
int nColumn; /* Number of columns in the data */
@@ -124740,7 +124740,7 @@ SQLITE_PRIVATE void sqlite3Insert(
if( pParse->nErr || db->mallocFailed ){
goto insert_cleanup;
}
- dest.iSDParm = 0; /* Suppress a harmless compiler warning */
+ dest.iSDParm = 0; /* Suppress a harmless compiler warning */
/* If the Select object is really just a simple VALUES() list with a
** single row (the common case) then keep that one row of values
@@ -124762,8 +124762,8 @@ SQLITE_PRIVATE void sqlite3Insert(
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb<db->nDb );
- if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0,
- db->aDb[iDb].zDbSName) ){
+ if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0,
+ db->aDb[iDb].zDbSName) ){
goto insert_cleanup;
}
withoutRowid = !HasRowid(pTab);
@@ -124916,7 +124916,7 @@ SQLITE_PRIVATE void sqlite3Insert(
rc = sqlite3Select(pParse, pSelect, &dest);
regFromSelect = dest.iSdst;
if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
- sqlite3VdbeEndCoroutine(v, regYield);
+ sqlite3VdbeEndCoroutine(v, regYield);
sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
assert( pSelect->pEList );
nColumn = pSelect->pEList->nExpr;
@@ -124957,7 +124957,7 @@ SQLITE_PRIVATE void sqlite3Insert(
sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
- sqlite3VdbeGoto(v, addrL);
+ sqlite3VdbeGoto(v, addrL);
sqlite3VdbeJumpHere(v, addrL);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempReg(pParse, regTempRowid);
@@ -124971,13 +124971,13 @@ SQLITE_PRIVATE void sqlite3Insert(
sNC.pParse = pParse;
srcTab = -1;
assert( useTempTable==0 );
- if( pList ){
- nColumn = pList->nExpr;
- if( sqlite3ResolveExprListNames(&sNC, pList) ){
+ if( pList ){
+ nColumn = pList->nExpr;
+ if( sqlite3ResolveExprListNames(&sNC, pList) ){
goto insert_cleanup;
}
- }else{
- nColumn = 0;
+ }else{
+ nColumn = 0;
}
}
@@ -125038,16 +125038,16 @@ SQLITE_PRIVATE void sqlite3Insert(
/* If this is not a view, open the table and and all indices */
if( !isView ){
int nIdx;
- nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
+ nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
&iDataCur, &iIdxCur);
aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2));
if( aRegIdx==0 ){
goto insert_cleanup;
}
- for(i=0, pIdx=pTab->pIndex; i<nIdx; pIdx=pIdx->pNext, i++){
- assert( pIdx );
+ for(i=0, pIdx=pTab->pIndex; i<nIdx; pIdx=pIdx->pNext, i++){
+ assert( pIdx );
aRegIdx[i] = ++pParse->nMem;
- pParse->nMem += pIdx->nColumn;
+ pParse->nMem += pIdx->nColumn;
}
aRegIdx[i] = ++pParse->nMem; /* Register to store the table record */
}
@@ -125212,7 +125212,7 @@ SQLITE_PRIVATE void sqlite3Insert(
if( ipkColumn<0 ){
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
}else{
- int addr1;
+ int addr1;
assert( !withoutRowid );
if( useTempTable ){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols);
@@ -125220,9 +125220,9 @@ SQLITE_PRIVATE void sqlite3Insert(
assert( pSelect==0 ); /* Otherwise useTempTable is true */
sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
}
- addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
+ addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
- sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v);
}
@@ -125282,14 +125282,14 @@ SQLITE_PRIVATE void sqlite3Insert(
** to generate a unique primary key value.
*/
if( !appendFlag ){
- int addr1;
+ int addr1;
if( !IsVirtual(pTab) ){
- addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
+ addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
- sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeJumpHere(v, addr1);
}else{
- addr1 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v);
+ addr1 = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v);
}
sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v);
}
@@ -125325,24 +125325,24 @@ SQLITE_PRIVATE void sqlite3Insert(
#endif
{
int isReplace = 0;/* Set to true if constraints may cause a replace */
- int bUseSeek; /* True to use OPFLAG_SEEKRESULT */
+ int bUseSeek; /* True to use OPFLAG_SEEKRESULT */
sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert
);
sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
-
- /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE
- ** constraints or (b) there are no triggers and this table is not a
- ** parent table in a foreign key constraint. It is safe to set the
- ** flag in the second case as if any REPLACE constraint is hit, an
+
+ /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE
+ ** constraints or (b) there are no triggers and this table is not a
+ ** parent table in a foreign key constraint. It is safe to set the
+ ** flag in the second case as if any REPLACE constraint is hit, an
** OP_Delete or OP_IdxDelete instruction will be executed on each
- ** cursor that is disturbed. And these instructions both clear the
- ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT
- ** functionality. */
+ ** cursor that is disturbed. And these instructions both clear the
+ ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT
+ ** functionality. */
bUseSeek = (isReplace==0 || !sqlite3VdbeHasSubProgram(v));
sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
- regIns, aRegIdx, 0, appendFlag, bUseSeek
- );
+ regIns, aRegIdx, 0, appendFlag, bUseSeek
+ );
}
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
}else if( pParse->bReturning ){
@@ -125374,7 +125374,7 @@ SQLITE_PRIVATE void sqlite3Insert(
sqlite3VdbeJumpHere(v, addrInsTop);
sqlite3VdbeAddOp1(v, OP_Close, srcTab);
}else if( pSelect ){
- sqlite3VdbeGoto(v, addrCont);
+ sqlite3VdbeGoto(v, addrCont);
#ifdef SQLITE_DEBUG
/* If we are jumping back to an OP_Yield that is preceded by an
** OP_ReleaseReg, set the p5 flag on the OP_Goto so that the
@@ -125434,67 +125434,67 @@ insert_cleanup:
/*
** Meanings of bits in of pWalker->eCode for
** sqlite3ExprReferencesUpdatedColumn()
-*/
-#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */
-#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */
-
+*/
+#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */
+#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */
+
/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn().
* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this
** expression node references any of the
-** columns that are being modifed by an UPDATE statement.
-*/
-static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
- if( pExpr->op==TK_COLUMN ){
- assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 );
- if( pExpr->iColumn>=0 ){
- if( pWalker->u.aiCol[pExpr->iColumn]>=0 ){
- pWalker->eCode |= CKCNSTRNT_COLUMN;
- }
- }else{
- pWalker->eCode |= CKCNSTRNT_ROWID;
- }
- }
- return WRC_Continue;
-}
-
-/*
-** pExpr is a CHECK constraint on a row that is being UPDATE-ed. The
-** only columns that are modified by the UPDATE are those for which
-** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
-**
+** columns that are being modifed by an UPDATE statement.
+*/
+static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
+ if( pExpr->op==TK_COLUMN ){
+ assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 );
+ if( pExpr->iColumn>=0 ){
+ if( pWalker->u.aiCol[pExpr->iColumn]>=0 ){
+ pWalker->eCode |= CKCNSTRNT_COLUMN;
+ }
+ }else{
+ pWalker->eCode |= CKCNSTRNT_ROWID;
+ }
+ }
+ return WRC_Continue;
+}
+
+/*
+** pExpr is a CHECK constraint on a row that is being UPDATE-ed. The
+** only columns that are modified by the UPDATE are those for which
+** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
+**
** Return true if CHECK constraint pExpr uses any of the
-** changing columns (or the rowid if it is changing). In other words,
+** changing columns (or the rowid if it is changing). In other words,
** return true if this CHECK constraint must be validated for
-** the new row in the UPDATE statement.
+** the new row in the UPDATE statement.
**
** 2018-09-15: pExpr might also be an expression for an index-on-expressions.
** The operation of this routine is the same - return true if an only if
** the expression uses one or more of columns identified by the second and
** third arguments.
-*/
+*/
SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(
Expr *pExpr, /* The expression to be checked */
int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */
int chngRowid /* True if UPDATE changes the rowid */
){
- Walker w;
- memset(&w, 0, sizeof(w));
- w.eCode = 0;
- w.xExprCallback = checkConstraintExprNode;
- w.u.aiCol = aiChng;
- sqlite3WalkExpr(&w, pExpr);
- if( !chngRowid ){
- testcase( (w.eCode & CKCNSTRNT_ROWID)!=0 );
- w.eCode &= ~CKCNSTRNT_ROWID;
- }
- testcase( w.eCode==0 );
- testcase( w.eCode==CKCNSTRNT_COLUMN );
- testcase( w.eCode==CKCNSTRNT_ROWID );
- testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
+ Walker w;
+ memset(&w, 0, sizeof(w));
+ w.eCode = 0;
+ w.xExprCallback = checkConstraintExprNode;
+ w.u.aiCol = aiChng;
+ sqlite3WalkExpr(&w, pExpr);
+ if( !chngRowid ){
+ testcase( (w.eCode & CKCNSTRNT_ROWID)!=0 );
+ w.eCode &= ~CKCNSTRNT_ROWID;
+ }
+ testcase( w.eCode==0 );
+ testcase( w.eCode==CKCNSTRNT_COLUMN );
+ testcase( w.eCode==CKCNSTRNT_ROWID );
+ testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
return w.eCode!=0;
-}
-
-/*
+}
+
+/*
** The sqlite3GenerateConstraintChecks() routine usually wants to visit
** the indexes of a table in the order provided in the Table->pIndex list.
** However, sometimes (rarely - when there is an upsert) it wants to visit
@@ -125660,7 +125660,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
u8 pkChng, /* Non-zero if the rowid or PRIMARY KEY changed */
u8 overrideError, /* Override onError to this if not OE_Default */
int ignoreDest, /* Jump to this label on an OE_Ignore resolution */
- int *pbMayReplace, /* OUT: Set to true if constraint may cause a replace */
+ int *pbMayReplace, /* OUT: Set to true if constraint may cause a replace */
int *aiChng, /* column i is unchanged if aiChng[i]<0 */
Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */
){
@@ -125819,12 +125819,12 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
#ifndef SQLITE_OMIT_CHECK
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
ExprList *pCheck = pTab->pCheck;
- pParse->iSelfTab = -(regNewData+1);
+ pParse->iSelfTab = -(regNewData+1);
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
for(i=0; i<pCheck->nExpr; i++){
- int allOk;
+ int allOk;
Expr *pCopy;
- Expr *pExpr = pCheck->a[i].pExpr;
+ Expr *pExpr = pCheck->a[i].pExpr;
if( aiChng
&& !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
){
@@ -125844,7 +125844,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
sqlite3ExprDelete(db, pCopy);
if( onError==OE_Ignore ){
- sqlite3VdbeGoto(v, ignoreDest);
+ sqlite3VdbeGoto(v, ignoreDest);
}else{
char *zName = pCheck->a[i].zEName;
assert( zName!=0 || pParse->db->mallocFailed );
@@ -125855,7 +125855,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
sqlite3VdbeResolveLabel(v, allOk);
}
- pParse->iSelfTab = 0;
+ pParse->iSelfTab = 0;
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
@@ -126038,7 +126038,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
if( isUpdate ){
- /* pkChng!=0 does not mean that the rowid has changed, only that
+ /* pkChng!=0 does not mean that the rowid has changed, only that
** it might have changed. Skip the conflict logic below if the rowid
** is unchanged. */
sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
@@ -126093,11 +126093,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
if( regTrigCnt ){
sqlite3MultiWrite(pParse);
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
- regNewData, 1, 0, OE_Replace, 1, -1);
+ regNewData, 1, 0, OE_Replace, 1, -1);
sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */
nReplaceTrig++;
- }else{
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ }else{
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
assert( HasRowid(pTab) );
/* This OP_Delete opcode fires the pre-update-hook only. It does
** not modify the b-tree. It is more efficient to let the coming
@@ -126105,11 +126105,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
** existing entry and then insert a new one. */
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP);
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
-#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
- if( pTab->pIndex ){
- sqlite3MultiWrite(pParse);
- sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1);
- }
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+ if( pTab->pIndex ){
+ sqlite3MultiWrite(pParse);
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1);
+ }
}
seenReplace = 1;
break;
@@ -126122,7 +126122,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
#endif
case OE_Ignore: {
testcase( onError==OE_Ignore );
- sqlite3VdbeGoto(v, ignoreDest);
+ sqlite3VdbeGoto(v, ignoreDest);
break;
}
}
@@ -126171,24 +126171,24 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
/* Skip partial indices for which the WHERE clause is not true */
if( pIdx->pPartIdxWhere ){
sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
- pParse->iSelfTab = -(regNewData+1);
+ pParse->iSelfTab = -(regNewData+1);
sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
SQLITE_JUMPIFNULL);
- pParse->iSelfTab = 0;
+ pParse->iSelfTab = 0;
}
/* Create a record for this index entry as it should appear after
** the insert or update. Store that record in the aRegIdx[ix] register
*/
- regIdx = aRegIdx[ix]+1;
+ regIdx = aRegIdx[ix]+1;
for(i=0; i<pIdx->nColumn; i++){
int iField = pIdx->aiColumn[i];
int x;
- if( iField==XN_EXPR ){
- pParse->iSelfTab = -(regNewData+1);
- sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
- pParse->iSelfTab = 0;
- VdbeComment((v, "%s column %d", pIdx->zName, i));
+ if( iField==XN_EXPR ){
+ pParse->iSelfTab = -(regNewData+1);
+ sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
+ pParse->iSelfTab = 0;
+ VdbeComment((v, "%s column %d", pIdx->zName, i));
}else if( iField==XN_ROWID || iField==pTab->iPKey ){
x = regNewData;
sqlite3VdbeAddOp2(v, OP_IntCopy, x, regIdx+i);
@@ -126202,11 +126202,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
VdbeComment((v, "for %s", pIdx->zName));
-#ifdef SQLITE_ENABLE_NULL_TRIM
+#ifdef SQLITE_ENABLE_NULL_TRIM
if( pIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
sqlite3SetMakeRecordP5(v, pIdx->pTable);
}
-#endif
+#endif
sqlite3VdbeReleaseRegisters(pParse, regIdx, pIdx->nColumn, 0, 0);
/* In an UPDATE operation, if this index is the PRIMARY KEY index
@@ -126229,7 +126229,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}else if( onError==OE_Default ){
onError = OE_Abort;
}
-
+
/* Figure out if the upsert clause applies to this index */
if( pUpsertClause ){
if( pUpsertClause->isDoUpdate==0 ){
@@ -126239,31 +126239,31 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
}
- /* Collision detection may be omitted if all of the following are true:
- ** (1) The conflict resolution algorithm is REPLACE
- ** (2) The table is a WITHOUT ROWID table
- ** (3) There are no secondary indexes on the table
- ** (4) No delete triggers need to be fired if there is a conflict
- ** (5) No FK constraint counters need to be updated if a conflict occurs.
+ /* Collision detection may be omitted if all of the following are true:
+ ** (1) The conflict resolution algorithm is REPLACE
+ ** (2) The table is a WITHOUT ROWID table
+ ** (3) There are no secondary indexes on the table
+ ** (4) No delete triggers need to be fired if there is a conflict
+ ** (5) No FK constraint counters need to be updated if a conflict occurs.
**
** This is not possible for ENABLE_PREUPDATE_HOOK builds, as the row
** must be explicitly deleted in order to ensure any pre-update hook
** is invoked. */
assert( IsOrdinaryTable(pTab) );
#ifndef SQLITE_ENABLE_PREUPDATE_HOOK
- if( (ix==0 && pIdx->pNext==0) /* Condition 3 */
- && pPk==pIdx /* Condition 2 */
- && onError==OE_Replace /* Condition 1 */
- && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */
- 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0))
- && ( 0==(db->flags&SQLITE_ForeignKeys) || /* Condition 5 */
+ if( (ix==0 && pIdx->pNext==0) /* Condition 3 */
+ && pPk==pIdx /* Condition 2 */
+ && onError==OE_Replace /* Condition 1 */
+ && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */
+ 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0))
+ && ( 0==(db->flags&SQLITE_ForeignKeys) || /* Condition 5 */
(0==pTab->u.tab.pFKey && 0==sqlite3FkReferences(pTab)))
- ){
- sqlite3VdbeResolveLabel(v, addrUniqueOk);
- continue;
- }
+ ){
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ continue;
+ }
#endif /* ifndef SQLITE_ENABLE_PREUPDATE_HOOK */
-
+
/* Check to see if the new index entry will be unique */
sqlite3VdbeVerifyAbortable(v, onError);
addrConflictCk =
@@ -126288,7 +126288,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
** store it in registers regR..regR+nPk-1 */
if( pIdx!=pPk ){
for(i=0; i<pPk->nKeyCol; i++){
- assert( pPk->aiColumn[i]>=0 );
+ assert( pPk->aiColumn[i]>=0 );
x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]);
sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
VdbeComment((v, "%s.%s", pTab->zName,
@@ -126310,7 +126310,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
for(i=0; i<pPk->nKeyCol; i++){
char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
x = pPk->aiColumn[i];
- assert( x>=0 );
+ assert( x>=0 );
if( i==(pPk->nKeyCol-1) ){
addrJump = addrUniqueOk;
op = OP_Eq;
@@ -126348,7 +126348,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
#endif
case OE_Ignore: {
testcase( onError==OE_Ignore );
- sqlite3VdbeGoto(v, ignoreDest);
+ sqlite3VdbeGoto(v, ignoreDest);
break;
}
default: {
@@ -126367,8 +126367,8 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
sqlite3VdbeAddOp1(v, OP_CursorLock, iDataCur);
}
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
- regR, nPkField, 0, OE_Replace,
- (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur);
+ regR, nPkField, 0, OE_Replace,
+ (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur);
if( pTrigger && isUpdate ){
sqlite3VdbeAddOp1(v, OP_CursorUnlock, iDataCur);
}
@@ -126478,29 +126478,29 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}
-#ifdef SQLITE_ENABLE_NULL_TRIM
-/*
-** Change the P5 operand on the last opcode (which should be an OP_MakeRecord)
-** to be the number of columns in table pTab that must not be NULL-trimmed.
-**
-** Or if no columns of pTab may be NULL-trimmed, leave P5 at zero.
-*/
-SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){
- u16 i;
-
- /* Records with omitted columns are only allowed for schema format
- ** version 2 and later (SQLite version 3.1.4, 2005-02-20). */
- if( pTab->pSchema->file_format<2 ) return;
-
- for(i=pTab->nCol-1; i>0; i--){
+#ifdef SQLITE_ENABLE_NULL_TRIM
+/*
+** Change the P5 operand on the last opcode (which should be an OP_MakeRecord)
+** to be the number of columns in table pTab that must not be NULL-trimmed.
+**
+** Or if no columns of pTab may be NULL-trimmed, leave P5 at zero.
+*/
+SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){
+ u16 i;
+
+ /* Records with omitted columns are only allowed for schema format
+ ** version 2 and later (SQLite version 3.1.4, 2005-02-20). */
+ if( pTab->pSchema->file_format<2 ) return;
+
+ for(i=pTab->nCol-1; i>0; i--){
if( pTab->aCol[i].iDflt!=0 ) break;
- if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break;
- }
- sqlite3VdbeChangeP5(v, i+1);
-}
-#endif
-
-/*
+ if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break;
+ }
+ sqlite3VdbeChangeP5(v, i+1);
+}
+#endif
+
+/*
** Table pTab is a WITHOUT ROWID table that is being written to. The cursor
** number is iCur, and register regData contains the new record for the
** PK index. This function adds code to invoke the pre-update hook,
@@ -126542,7 +126542,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
int iIdxCur, /* First index cursor */
int regNewData, /* Range of content */
int *aRegIdx, /* Register used by each index. 0 for unused indices */
- int update_flags, /* True for UPDATE, False for INSERT */
+ int update_flags, /* True for UPDATE, False for INSERT */
int appendBias, /* True if this is likely to be an append */
int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
@@ -126551,11 +126551,11 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
u8 pik_flags; /* flag values passed to the btree insert */
int i; /* Loop counter */
- assert( update_flags==0
- || update_flags==OPFLAG_ISUPDATE
- || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
- );
-
+ assert( update_flags==0
+ || update_flags==OPFLAG_ISUPDATE
+ || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
+ );
+
v = pParse->pVdbe;
assert( v!=0 );
assert( !IsView(pTab) ); /* This table is not a VIEW */
@@ -126569,25 +126569,25 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
}
- pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0);
+ pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0);
if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
pik_flags |= OPFLAG_NCHANGE;
- pik_flags |= (update_flags & OPFLAG_SAVEPOSITION);
- if( update_flags==0 ){
+ pik_flags |= (update_flags & OPFLAG_SAVEPOSITION);
+ if( update_flags==0 ){
codeWithoutRowidPreupdate(pParse, pTab, iIdxCur+i, aRegIdx[i]);
- }
+ }
}
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i],
- aRegIdx[i]+1,
- pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn);
- sqlite3VdbeChangeP5(v, pik_flags);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i],
+ aRegIdx[i]+1,
+ pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn);
+ sqlite3VdbeChangeP5(v, pik_flags);
}
if( !HasRowid(pTab) ) return;
if( pParse->nested ){
pik_flags = 0;
}else{
pik_flags = OPFLAG_NCHANGE;
- pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID);
+ pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID);
}
if( appendBias ){
pik_flags |= OPFLAG_APPEND;
@@ -126597,7 +126597,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
}
sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData);
if( !pParse->nested ){
- sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
sqlite3VdbeChangeP5(v, pik_flags);
}
@@ -126627,7 +126627,7 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
Parse *pParse, /* Parsing context */
Table *pTab, /* Table to be opened */
int op, /* OP_OpenRead or OP_OpenWrite */
- u8 p5, /* P5 value for OP_Open* opcodes (except on WITHOUT ROWID) */
+ u8 p5, /* P5 value for OP_Open* opcodes (except on WITHOUT ROWID) */
int iBase, /* Use this for the table cursor, if there is one */
u8 *aToOpen, /* If not NULL: boolean for each table and index */
int *piDataCur, /* Write the database source cursor number here */
@@ -126640,7 +126640,7 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
Vdbe *v;
assert( op==OP_OpenRead || op==OP_OpenWrite );
- assert( op==OP_OpenWrite || p5==0 );
+ assert( op==OP_OpenWrite || p5==0 );
if( IsVirtual(pTab) ){
/* This routine is a no-op for virtual tables. Leave the output
** variables *piDataCur and *piIdxCur set to illegal cursor numbers
@@ -126663,14 +126663,14 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
int iIdxCur = iBase++;
assert( pIdx->pSchema==pTab->pSchema );
- if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
- if( piDataCur ) *piDataCur = iIdxCur;
- p5 = 0;
+ if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
+ if( piDataCur ) *piDataCur = iIdxCur;
+ p5 = 0;
}
if( aToOpen==0 || aToOpen[i+1] ){
sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
- sqlite3VdbeChangeP5(v, p5);
+ sqlite3VdbeChangeP5(v, p5);
VdbeComment((v, "%s", pIdx->zName));
}
}
@@ -126716,21 +126716,21 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
return 0; /* Different columns indexed */
}
- if( pSrc->aiColumn[i]==XN_EXPR ){
- assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 );
- if( sqlite3ExprCompare(0, pSrc->aColExpr->a[i].pExpr,
- pDest->aColExpr->a[i].pExpr, -1)!=0 ){
- return 0; /* Different expressions in the index */
- }
- }
+ if( pSrc->aiColumn[i]==XN_EXPR ){
+ assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 );
+ if( sqlite3ExprCompare(0, pSrc->aColExpr->a[i].pExpr,
+ pDest->aColExpr->a[i].pExpr, -1)!=0 ){
+ return 0; /* Different expressions in the index */
+ }
+ }
if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
return 0; /* Different sort orders */
}
- if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){
+ if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){
return 0; /* Different collating sequences */
}
}
- if( sqlite3ExprCompare(0, pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
+ if( sqlite3ExprCompare(0, pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
return 0; /* Different WHERE clauses */
}
@@ -126799,7 +126799,7 @@ static int xferOptimization(
return 0; /* tab1 must not have triggers */
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pDest) ){
+ if( IsVirtual(pDest) ){
return 0; /* tab1 must not be a virtual table */
}
#endif
@@ -126840,7 +126840,7 @@ static int xferOptimization(
return 0; /* The result set must have exactly one column */
}
assert( pEList->a[0].pExpr );
- if( pEList->a[0].pExpr->op!=TK_ASTERISK ){
+ if( pEList->a[0].pExpr->op!=TK_ASTERISK ){
return 0; /* The result set must be the special operator "*" */
}
@@ -126875,13 +126875,13 @@ static int xferOptimization(
for(i=0; i<pDest->nCol; i++){
Column *pDestCol = &pDest->aCol[i];
Column *pSrcCol = &pSrc->aCol[i];
-#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
+#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
if( (db->mDbFlags & DBFLAG_Vacuum)==0
&& (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN
- ){
- return 0; /* Neither table may have __hidden__ columns */
- }
-#endif
+ ){
+ return 0; /* Neither table may have __hidden__ columns */
+ }
+#endif
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/* Even if tables t1 and t2 have identical schemas, if they contain
** generated columns, then this statement is semantically incorrect:
@@ -126938,9 +126938,9 @@ static int xferOptimization(
if( (pDestExpr==0)!=(pSrcExpr==0)
|| (pDestExpr!=0 && strcmp(pDestExpr->u.zToken,
pSrcExpr->u.zToken)!=0)
- ){
- return 0; /* Default values must be the same for all columns */
- }
+ ){
+ return 0; /* Default values must be the same for all columns */
+ }
}
}
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
@@ -127001,15 +127001,15 @@ static int xferOptimization(
regRowid = sqlite3GetTempReg(pParse);
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
assert( HasRowid(pDest) || destHasUniqueIdx );
- if( (db->mDbFlags & DBFLAG_Vacuum)==0 && (
+ if( (db->mDbFlags & DBFLAG_Vacuum)==0 && (
(pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
|| destHasUniqueIdx /* (2) */
|| (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
)){
/* In some circumstances, we are able to run the xfer optimization
** only if the destination table is initially empty. Unless the
- ** DBFLAG_Vacuum flag is set, this block generates code to make
- ** that determination. If DBFLAG_Vacuum is set, then the destination
+ ** DBFLAG_Vacuum flag is set, this block generates code to make
+ ** that determination. If DBFLAG_Vacuum is set, then the destination
** table is always empty.
**
** Conditions under which the destination must be empty:
@@ -127024,11 +127024,11 @@ static int xferOptimization(
** (3) onError is something other than OE_Abort and OE_Rollback.
*/
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v);
- emptyDestTest = sqlite3VdbeAddOp0(v, OP_Goto);
+ emptyDestTest = sqlite3VdbeAddOp0(v, OP_Goto);
sqlite3VdbeJumpHere(v, addr1);
}
if( HasRowid(pSrc) ){
- u8 insFlags;
+ u8 insFlags;
sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
if( pDest->iPKey>=0 ){
@@ -127048,12 +127048,12 @@ static int xferOptimization(
assert( (pDest->tabFlags & TF_Autoincrement)==0 );
}
- if( db->mDbFlags & DBFLAG_Vacuum ){
- sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
+ if( db->mDbFlags & DBFLAG_Vacuum ){
+ sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT;
- }else{
+ }else{
insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND|OPFLAG_PREFORMAT;
- }
+ }
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){
sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
@@ -127067,7 +127067,7 @@ static int xferOptimization(
if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){
sqlite3VdbeChangeP4(v, -1, (char*)pDest, P4_TABLE);
}
- sqlite3VdbeChangeP5(v, insFlags);
+ sqlite3VdbeChangeP5(v, insFlags);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
@@ -127090,13 +127090,13 @@ static int xferOptimization(
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
- if( db->mDbFlags & DBFLAG_Vacuum ){
+ if( db->mDbFlags & DBFLAG_Vacuum ){
/* This INSERT command is part of a VACUUM operation, which guarantees
** that the destination table is empty. If all indexed columns use
** collation sequence BINARY, then it can also be assumed that the
** index will be populated by inserting keys in strictly sorted
** order. In this case, instead of seeking within the b-tree as part
- ** of every OP_IdxInsert opcode, an OP_SeekEnd is added before the
+ ** of every OP_IdxInsert opcode, an OP_SeekEnd is added before the
** OP_IdxInsert to seek to the point within the b-tree where each key
** should be inserted. This is faster.
**
@@ -127106,12 +127106,12 @@ static int xferOptimization(
** a VACUUM command. In that case keys may not be written in strictly
** sorted order. */
for(i=0; i<pSrcIdx->nColumn; i++){
- const char *zColl = pSrcIdx->azColl[i];
- if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
+ const char *zColl = pSrcIdx->azColl[i];
+ if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
}
if( i==pSrcIdx->nColumn ){
idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT;
- sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
+ sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc);
}
}else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
@@ -127126,8 +127126,8 @@ static int xferOptimization(
codeWithoutRowidPreupdate(pParse, pDest, iDest, regData);
}
}
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
- sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
+ sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
@@ -127137,7 +127137,7 @@ static int xferOptimization(
sqlite3ReleaseTempReg(pParse, regRowid);
sqlite3ReleaseTempReg(pParse, regData);
if( emptyDestTest ){
- sqlite3AutoincrementEnd(pParse);
+ sqlite3AutoincrementEnd(pParse);
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
sqlite3VdbeJumpHere(v, emptyDestTest);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
@@ -127179,7 +127179,7 @@ static int xferOptimization(
** argument to xCallback(). If xCallback=NULL then no callback
** is invoked, even for queries.
*/
-SQLITE_API int sqlite3_exec(
+SQLITE_API int sqlite3_exec(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
sqlite3_callback xCallback, /* Invoke this callback routine */
@@ -127224,7 +127224,7 @@ SQLITE_API int sqlite3_exec(
&& db->flags&SQLITE_NullCallback)) ){
if( !callbackIsInit ){
nCol = sqlite3_column_count(pStmt);
- azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*));
+ azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*));
if( azCols==0 ){
goto exec_out;
}
@@ -127241,11 +127241,11 @@ SQLITE_API int sqlite3_exec(
for(i=0; i<nCol; i++){
azVals[i] = (char *)sqlite3_column_text(pStmt, i);
if( !azVals[i] && sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
goto exec_out;
}
}
- azVals[i] = 0;
+ azVals[i] = 0;
}
if( xCallback(pArg, nCol, azVals, azCols) ){
/* EVIDENCE-OF: R-38229-40159 If the callback function to
@@ -127278,9 +127278,9 @@ exec_out:
rc = sqlite3ApiExit(db, rc);
if( rc!=SQLITE_OK && pzErrMsg ){
- *pzErrMsg = sqlite3DbStrDup(0, sqlite3_errmsg(db));
- if( *pzErrMsg==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ *pzErrMsg = sqlite3DbStrDup(0, sqlite3_errmsg(db));
+ if( *pzErrMsg==0 ){
+ rc = SQLITE_NOMEM_BKPT;
sqlite3Error(db, SQLITE_NOMEM);
}
}else if( pzErrMsg ){
@@ -127331,8 +127331,8 @@ exec_out:
** as extensions by SQLite should #include this file instead of
** sqlite3.h.
*/
-#ifndef SQLITE3EXT_H
-#define SQLITE3EXT_H
+#ifndef SQLITE3EXT_H
+#define SQLITE3EXT_H
/* #include "sqlite3.h" */
/*
@@ -127450,7 +127450,7 @@ struct sqlite3_api_routines {
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
const char*,const char*),void*);
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
- char * (*xsnprintf)(int,char*,const char*,...);
+ char * (*xsnprintf)(int,char*,const char*,...);
int (*step)(sqlite3_stmt*);
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
char const**,char const**,int*,int*,int*);
@@ -127562,7 +127562,7 @@ struct sqlite3_api_routines {
int (*uri_boolean)(const char*,const char*,int);
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
const char *(*uri_parameter)(const char*,const char*);
- char *(*xvsnprintf)(int,char*,const char*,va_list);
+ char *(*xvsnprintf)(int,char*,const char*,va_list);
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
/* Version 3.8.7 and later */
int (*auto_extension)(void(*)(void));
@@ -127586,31 +127586,31 @@ struct sqlite3_api_routines {
void (*value_free)(sqlite3_value*);
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
- /* Version 3.9.0 and later */
- unsigned int (*value_subtype)(sqlite3_value*);
- void (*result_subtype)(sqlite3_context*,unsigned int);
- /* Version 3.10.0 and later */
- int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
- int (*strlike)(const char*,const char*,unsigned int);
- int (*db_cacheflush)(sqlite3*);
- /* Version 3.12.0 and later */
- int (*system_errno)(sqlite3*);
- /* Version 3.14.0 and later */
- int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
- char *(*expanded_sql)(sqlite3_stmt*);
- /* Version 3.18.0 and later */
- void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
- /* Version 3.20.0 and later */
- int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
- sqlite3_stmt**,const char**);
- int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
- sqlite3_stmt**,const void**);
- int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
- void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
- void *(*value_pointer)(sqlite3_value*,const char*);
- int (*vtab_nochange)(sqlite3_context*);
- int (*value_nochange)(sqlite3_value*);
- const char *(*vtab_collation)(sqlite3_index_info*,int);
+ /* Version 3.9.0 and later */
+ unsigned int (*value_subtype)(sqlite3_value*);
+ void (*result_subtype)(sqlite3_context*,unsigned int);
+ /* Version 3.10.0 and later */
+ int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
+ int (*strlike)(const char*,const char*,unsigned int);
+ int (*db_cacheflush)(sqlite3*);
+ /* Version 3.12.0 and later */
+ int (*system_errno)(sqlite3*);
+ /* Version 3.14.0 and later */
+ int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
+ char *(*expanded_sql)(sqlite3_stmt*);
+ /* Version 3.18.0 and later */
+ void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
+ /* Version 3.20.0 and later */
+ int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
+ sqlite3_stmt**,const char**);
+ int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
+ sqlite3_stmt**,const void**);
+ int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
+ void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
+ void *(*value_pointer)(sqlite3_value*,const char*);
+ int (*vtab_nochange)(sqlite3_context*);
+ int (*value_nochange)(sqlite3_value*);
+ const char *(*vtab_collation)(sqlite3_index_info*,int);
/* Version 3.24.0 and later */
int (*keyword_count)(void);
int (*keyword_name)(int,const char**,int*);
@@ -127663,16 +127663,16 @@ struct sqlite3_api_routines {
};
/*
-** This is the function signature used for all extension entry points. It
-** is also defined in the file "loadext.c".
-*/
-typedef int (*sqlite3_loadext_entry)(
- sqlite3 *db, /* Handle to the database. */
- char **pzErrMsg, /* Used to set error string on failure. */
- const sqlite3_api_routines *pThunk /* Extension API function pointers. */
-);
-
-/*
+** This is the function signature used for all extension entry points. It
+** is also defined in the file "loadext.c".
+*/
+typedef int (*sqlite3_loadext_entry)(
+ sqlite3 *db, /* Handle to the database. */
+ char **pzErrMsg, /* Used to set error string on failure. */
+ const sqlite3_api_routines *pThunk /* Extension API function pointers. */
+);
+
+/*
** The following macros redefine the API routines so that they are
** redirected through the global sqlite3_api structure.
**
@@ -127683,7 +127683,7 @@ typedef int (*sqlite3_loadext_entry)(
** the API. So the redefinition macros are only valid if the
** SQLITE_CORE macros is undefined.
*/
-#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
@@ -127786,7 +127786,7 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
-#define sqlite3_snprintf sqlite3_api->xsnprintf
+#define sqlite3_snprintf sqlite3_api->xsnprintf
#define sqlite3_step sqlite3_api->step
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
@@ -127810,7 +127810,7 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
-#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
+#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
@@ -127886,7 +127886,7 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
#define sqlite3_uri_int64 sqlite3_api->uri_int64
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
-#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
+#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
/* Version 3.8.7 and later */
#define sqlite3_auto_extension sqlite3_api->auto_extension
@@ -127906,28 +127906,28 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_value_free sqlite3_api->value_free
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
-/* Version 3.9.0 and later */
-#define sqlite3_value_subtype sqlite3_api->value_subtype
-#define sqlite3_result_subtype sqlite3_api->result_subtype
-/* Version 3.10.0 and later */
-#define sqlite3_status64 sqlite3_api->status64
-#define sqlite3_strlike sqlite3_api->strlike
-#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
-/* Version 3.12.0 and later */
-#define sqlite3_system_errno sqlite3_api->system_errno
-/* Version 3.14.0 and later */
-#define sqlite3_trace_v2 sqlite3_api->trace_v2
-#define sqlite3_expanded_sql sqlite3_api->expanded_sql
-/* Version 3.18.0 and later */
-#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
-/* Version 3.20.0 and later */
-#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
-#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
-#define sqlite3_bind_pointer sqlite3_api->bind_pointer
-#define sqlite3_result_pointer sqlite3_api->result_pointer
-#define sqlite3_value_pointer sqlite3_api->value_pointer
-/* Version 3.22.0 and later */
-#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
+/* Version 3.9.0 and later */
+#define sqlite3_value_subtype sqlite3_api->value_subtype
+#define sqlite3_result_subtype sqlite3_api->result_subtype
+/* Version 3.10.0 and later */
+#define sqlite3_status64 sqlite3_api->status64
+#define sqlite3_strlike sqlite3_api->strlike
+#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
+/* Version 3.12.0 and later */
+#define sqlite3_system_errno sqlite3_api->system_errno
+/* Version 3.14.0 and later */
+#define sqlite3_trace_v2 sqlite3_api->trace_v2
+#define sqlite3_expanded_sql sqlite3_api->expanded_sql
+/* Version 3.18.0 and later */
+#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
+/* Version 3.20.0 and later */
+#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
+#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
+#define sqlite3_bind_pointer sqlite3_api->bind_pointer
+#define sqlite3_result_pointer sqlite3_api->result_pointer
+#define sqlite3_value_pointer sqlite3_api->value_pointer
+/* Version 3.22.0 and later */
+#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
#define sqlite3_value_nochange sqlite3_api->value_nochange
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
/* Version 3.24.0 and later */
@@ -127971,9 +127971,9 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_total_changes64 sqlite3_api->total_changes64
/* Version 3.37.0 and later */
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
-#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
-#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
/* This case when the file really is being compiled as a loadable
** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
@@ -127988,7 +127988,7 @@ typedef int (*sqlite3_loadext_entry)(
# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif
-#endif /* SQLITE3EXT_H */
+#endif /* SQLITE3EXT_H */
/************** End of sqlite3ext.h ******************************************/
/************** Continuing where we left off in loadext.c ********************/
@@ -128026,7 +128026,7 @@ typedef int (*sqlite3_loadext_entry)(
# define sqlite3_open16 0
# define sqlite3_prepare16 0
# define sqlite3_prepare16_v2 0
-# define sqlite3_prepare16_v3 0
+# define sqlite3_prepare16_v3 0
# define sqlite3_result_error16 0
# define sqlite3_result_text16 0
# define sqlite3_result_text16be 0
@@ -128066,7 +128066,7 @@ typedef int (*sqlite3_loadext_entry)(
# define sqlite3_enable_shared_cache 0
#endif
-#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED)
+#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED)
# define sqlite3_profile 0
# define sqlite3_trace 0
#endif
@@ -128086,10 +128086,10 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_blob_reopen 0
#endif
-#if defined(SQLITE_OMIT_TRACE)
-# define sqlite3_trace_v2 0
-#endif
-
+#if defined(SQLITE_OMIT_TRACE)
+# define sqlite3_trace_v2 0
+#endif
+
/*
** The following structure contains pointers to all SQLite API routines.
** A pointer to this structure is passed into extensions when they are
@@ -128386,30 +128386,30 @@ static const sqlite3_api_routines sqlite3Apis = {
(sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup,
sqlite3_value_free,
sqlite3_result_zeroblob64,
- sqlite3_bind_zeroblob64,
- /* Version 3.9.0 and later */
- sqlite3_value_subtype,
- sqlite3_result_subtype,
- /* Version 3.10.0 and later */
- sqlite3_status64,
- sqlite3_strlike,
- sqlite3_db_cacheflush,
- /* Version 3.12.0 and later */
- sqlite3_system_errno,
- /* Version 3.14.0 and later */
- sqlite3_trace_v2,
- sqlite3_expanded_sql,
- /* Version 3.18.0 and later */
- sqlite3_set_last_insert_rowid,
- /* Version 3.20.0 and later */
- sqlite3_prepare_v3,
- sqlite3_prepare16_v3,
- sqlite3_bind_pointer,
- sqlite3_result_pointer,
- sqlite3_value_pointer,
- /* Version 3.22.0 and later */
- sqlite3_vtab_nochange,
- sqlite3_value_nochange,
+ sqlite3_bind_zeroblob64,
+ /* Version 3.9.0 and later */
+ sqlite3_value_subtype,
+ sqlite3_result_subtype,
+ /* Version 3.10.0 and later */
+ sqlite3_status64,
+ sqlite3_strlike,
+ sqlite3_db_cacheflush,
+ /* Version 3.12.0 and later */
+ sqlite3_system_errno,
+ /* Version 3.14.0 and later */
+ sqlite3_trace_v2,
+ sqlite3_expanded_sql,
+ /* Version 3.18.0 and later */
+ sqlite3_set_last_insert_rowid,
+ /* Version 3.20.0 and later */
+ sqlite3_prepare_v3,
+ sqlite3_prepare16_v3,
+ sqlite3_bind_pointer,
+ sqlite3_result_pointer,
+ sqlite3_value_pointer,
+ /* Version 3.22.0 and later */
+ sqlite3_vtab_nochange,
+ sqlite3_value_nochange,
sqlite3_vtab_collation,
/* Version 3.24.0 and later */
sqlite3_keyword_count,
@@ -128490,14 +128490,14 @@ static int sqlite3LoadExtension(
){
sqlite3_vfs *pVfs = db->pVfs;
void *handle;
- sqlite3_loadext_entry xInit;
+ sqlite3_loadext_entry xInit;
char *zErrmsg = 0;
const char *zEntry;
char *zAltEntry = 0;
void **aHandle;
u64 nMsg = strlen(zFile);
int ii;
- int rc;
+ int rc;
/* Shared library endings to try if zFile cannot be loaded as written */
static const char *azEndings[] = {
@@ -128516,9 +128516,9 @@ static int sqlite3LoadExtension(
/* Ticket #1863. To avoid a creating security problems for older
** applications that relink against newer versions of SQLite, the
** ability to run load_extension is turned off by default. One
- ** must call either sqlite3_enable_load_extension(db) or
- ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0)
- ** to turn on extension loading.
+ ** must call either sqlite3_enable_load_extension(db) or
+ ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0)
+ ** to turn on extension loading.
*/
if( (db->flags & SQLITE_LoadExtension)==0 ){
if( pzErrMsg ){
@@ -128539,13 +128539,13 @@ static int sqlite3LoadExtension(
#if SQLITE_OS_UNIX || SQLITE_OS_WIN
for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
- if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
+ if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
handle = sqlite3OsDlOpen(pVfs, zAltFile);
sqlite3_free(zAltFile);
}
#endif
if( handle==0 ) goto extension_not_found;
- xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);
+ xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);
/* If no entry point was specified and the default legacy
** entry point name "sqlite3_extension_init" was not found, then
@@ -128564,7 +128564,7 @@ static int sqlite3LoadExtension(
zAltEntry = sqlite3_malloc64(ncFile+30);
if( zAltEntry==0 ){
sqlite3OsDlClose(pVfs, handle);
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(zAltEntry, "sqlite3_", 8);
for(iFile=ncFile-1; iFile>=0 && !DirSep(zFile[iFile]); iFile--){}
@@ -128577,7 +128577,7 @@ static int sqlite3LoadExtension(
}
memcpy(zAltEntry+iEntry, "_init", 6);
zEntry = zAltEntry;
- xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);
+ xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry);
}
if( xInit==0 ){
if( pzErrMsg ){
@@ -128595,9 +128595,9 @@ static int sqlite3LoadExtension(
return SQLITE_ERROR;
}
sqlite3_free(zAltEntry);
- rc = xInit(db, &zErrmsg, &sqlite3Apis);
- if( rc ){
- if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK;
+ rc = xInit(db, &zErrmsg, &sqlite3Apis);
+ if( rc ){
+ if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK;
if( pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
}
@@ -128609,7 +128609,7 @@ static int sqlite3LoadExtension(
/* Append the new shared library handle to the db->aExtension array. */
aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
if( aHandle==0 ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
if( db->nExtension>0 ){
memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
@@ -128633,7 +128633,7 @@ extension_not_found:
}
return SQLITE_ERROR;
}
-SQLITE_API int sqlite3_load_extension(
+SQLITE_API int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
@@ -128664,10 +128664,10 @@ SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){
** Enable or disable extension loading. Extension loading is disabled by
** default so as not to open security holes in older applications.
*/
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
+SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
sqlite3_mutex_enter(db->mutex);
if( onoff ){
- db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
+ db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
}else{
db->flags &= ~(u64)(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
}
@@ -128675,7 +128675,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
return SQLITE_OK;
}
-#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */
/*
** The following object holds the list of automatically loaded
@@ -128710,9 +128710,9 @@ static SQLITE_WSD struct sqlite3AutoExtList {
** Register a statically linked extension that is automatically
** loaded by every new database connection.
*/
-SQLITE_API int sqlite3_auto_extension(
- void (*xInit)(void)
-){
+SQLITE_API int sqlite3_auto_extension(
+ void (*xInit)(void)
+){
int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
@@ -128735,7 +128735,7 @@ SQLITE_API int sqlite3_auto_extension(
void (**aNew)(void);
aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
if( aNew==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}else{
wsdAutoext.aExt = aNew;
wsdAutoext.aExt[wsdAutoext.nExt] = xInit;
@@ -128757,9 +128757,9 @@ SQLITE_API int sqlite3_auto_extension(
** Return 1 if xInit was found on the list and removed. Return 0 if xInit
** was not on the list.
*/
-SQLITE_API int sqlite3_cancel_auto_extension(
- void (*xInit)(void)
-){
+SQLITE_API int sqlite3_cancel_auto_extension(
+ void (*xInit)(void)
+){
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
#endif
@@ -128782,7 +128782,7 @@ SQLITE_API int sqlite3_cancel_auto_extension(
/*
** Reset the automatic extension loading mechanism.
*/
-SQLITE_API void sqlite3_reset_auto_extension(void){
+SQLITE_API void sqlite3_reset_auto_extension(void){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize()==SQLITE_OK )
#endif
@@ -128808,7 +128808,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
u32 i;
int go = 1;
int rc;
- sqlite3_loadext_entry xInit;
+ sqlite3_loadext_entry xInit;
wsdAutoextInit;
if( wsdAutoext.nExt==0 ){
@@ -128820,21 +128820,21 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
#endif
-#ifdef SQLITE_OMIT_LOAD_EXTENSION
- const sqlite3_api_routines *pThunk = 0;
-#else
- const sqlite3_api_routines *pThunk = &sqlite3Apis;
-#endif
+#ifdef SQLITE_OMIT_LOAD_EXTENSION
+ const sqlite3_api_routines *pThunk = 0;
+#else
+ const sqlite3_api_routines *pThunk = &sqlite3Apis;
+#endif
sqlite3_mutex_enter(mutex);
if( i>=wsdAutoext.nExt ){
xInit = 0;
go = 0;
}else{
- xInit = (sqlite3_loadext_entry)wsdAutoext.aExt[i];
+ xInit = (sqlite3_loadext_entry)wsdAutoext.aExt[i];
}
sqlite3_mutex_leave(mutex);
zErrmsg = 0;
- if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){
+ if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){
sqlite3ErrorWithMsg(db, rc,
"automatic extension loading failed: %s", zErrmsg);
go = 0;
@@ -128882,8 +128882,8 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
** that script and rerun it.
*/
-
-/* The various pragma types */
+
+/* The various pragma types */
#define PragTyp_ACTIVATE_EXTENSIONS 0
#define PragTyp_ANALYSIS_LIMIT 1
#define PragTyp_HEADER_VALUE 2
@@ -128930,22 +128930,22 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
#define PragTyp_WAL_CHECKPOINT 43
#define PragTyp_LOCK_STATUS 44
#define PragTyp_STATS 45
-
-/* Property flags associated with various pragma. */
-#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
-#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
-#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
-#define PragFlg_ReadOnly 0x08 /* Read-only HEADER_VALUE */
-#define PragFlg_Result0 0x10 /* Acts as query when no argument */
-#define PragFlg_Result1 0x20 /* Acts as query when has one argument */
-#define PragFlg_SchemaOpt 0x40 /* Schema restricts name search if present */
-#define PragFlg_SchemaReq 0x80 /* Schema required - "main" is default */
-
-/* Names of columns for pragmas that return multi-column result
-** or that return single-column results where the name of the
-** result column is different from the name of the pragma
-*/
-static const char *const pragCName[] = {
+
+/* Property flags associated with various pragma. */
+#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
+#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
+#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
+#define PragFlg_ReadOnly 0x08 /* Read-only HEADER_VALUE */
+#define PragFlg_Result0 0x10 /* Acts as query when no argument */
+#define PragFlg_Result1 0x20 /* Acts as query when has one argument */
+#define PragFlg_SchemaOpt 0x40 /* Schema restricts name search if present */
+#define PragFlg_SchemaReq 0x80 /* Schema required - "main" is default */
+
+/* Names of columns for pragmas that return multi-column result
+** or that return single-column results where the name of the
+** result column is different from the name of the pragma
+*/
+static const char *const pragCName[] = {
/* 0 */ "id", /* Used by: foreign_key_list */
/* 1 */ "seq",
/* 2 */ "table",
@@ -129007,24 +129007,24 @@ static const char *const pragCName[] = {
/* 55 */ "cache_size", /* Used by: default_cache_size */
/* module_list pragma_list reuses 9 */
/* 56 */ "timeout", /* Used by: busy_timeout */
-};
-
-/* Definitions of all built-in pragmas */
-typedef struct PragmaName {
- const char *const zName; /* Name of pragma */
- u8 ePragTyp; /* PragTyp_XXX value */
- u8 mPragFlg; /* Zero or more PragFlg_XXX values */
- u8 iPragCName; /* Start of column names in pragCName[] */
- u8 nPragCName; /* Num of col names. 0 means use pragma name */
+};
+
+/* Definitions of all built-in pragmas */
+typedef struct PragmaName {
+ const char *const zName; /* Name of pragma */
+ u8 ePragTyp; /* PragTyp_XXX value */
+ u8 mPragFlg; /* Zero or more PragFlg_XXX values */
+ u8 iPragCName; /* Start of column names in pragCName[] */
+ u8 nPragCName; /* Num of col names. 0 means use pragma name */
u64 iArg; /* Extra argument */
-} PragmaName;
-static const PragmaName aPragmaName[] = {
+} PragmaName;
+static const PragmaName aPragmaName[] = {
#if defined(SQLITE_ENABLE_CEROD)
- {/* zName: */ "activate_extensions",
- /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
- /* ePragFlg: */ 0,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "activate_extensions",
+ /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
{/* zName: */ "analysis_limit",
/* ePragTyp: */ PragTyp_ANALYSIS_LIMIT,
@@ -129032,245 +129032,245 @@ static const PragmaName aPragmaName[] = {
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
- {/* zName: */ "application_id",
- /* ePragTyp: */ PragTyp_HEADER_VALUE,
- /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
- /* ColNames: */ 0, 0,
- /* iArg: */ BTREE_APPLICATION_ID },
+ {/* zName: */ "application_id",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_APPLICATION_ID },
#endif
#if !defined(SQLITE_OMIT_AUTOVACUUM)
- {/* zName: */ "auto_vacuum",
- /* ePragTyp: */ PragTyp_AUTO_VACUUM,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "auto_vacuum",
+ /* ePragTyp: */ PragTyp_AUTO_VACUUM,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
- {/* zName: */ "automatic_index",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_AutoIndex },
+ {/* zName: */ "automatic_index",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_AutoIndex },
#endif
#endif
- {/* zName: */ "busy_timeout",
- /* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
- /* ePragFlg: */ PragFlg_Result0,
+ {/* zName: */ "busy_timeout",
+ /* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
+ /* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 56, 1,
- /* iArg: */ 0 },
+ /* iArg: */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- {/* zName: */ "cache_size",
- /* ePragTyp: */ PragTyp_CACHE_SIZE,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "cache_size",
+ /* ePragTyp: */ PragTyp_CACHE_SIZE,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- {/* zName: */ "cache_spill",
- /* ePragTyp: */ PragTyp_CACHE_SPILL,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "cache_spill",
+ /* ePragTyp: */ PragTyp_CACHE_SPILL,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
- {/* zName: */ "case_sensitive_like",
- /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
- /* ePragFlg: */ PragFlg_NoColumns,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
-#endif
- {/* zName: */ "cell_size_check",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_CellSizeCk },
+ {/* zName: */ "case_sensitive_like",
+ /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
+ /* ePragFlg: */ PragFlg_NoColumns,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+ {/* zName: */ "cell_size_check",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_CellSizeCk },
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- {/* zName: */ "checkpoint_fullfsync",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_CkptFullFSync },
+ {/* zName: */ "checkpoint_fullfsync",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_CkptFullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
- {/* zName: */ "collation_list",
- /* ePragTyp: */ PragTyp_COLLATION_LIST,
- /* ePragFlg: */ PragFlg_Result0,
+ {/* zName: */ "collation_list",
+ /* ePragTyp: */ PragTyp_COLLATION_LIST,
+ /* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 38, 2,
- /* iArg: */ 0 },
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
- {/* zName: */ "compile_options",
- /* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
- /* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "compile_options",
+ /* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- {/* zName: */ "count_changes",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_CountRows },
+ {/* zName: */ "count_changes",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_CountRows },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
- {/* zName: */ "data_store_directory",
- /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
- /* ePragFlg: */ PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "data_store_directory",
+ /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
+ /* ePragFlg: */ PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
- {/* zName: */ "data_version",
- /* ePragTyp: */ PragTyp_HEADER_VALUE,
- /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0,
- /* ColNames: */ 0, 0,
- /* iArg: */ BTREE_DATA_VERSION },
+ {/* zName: */ "data_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_DATA_VERSION },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
- {/* zName: */ "database_list",
- /* ePragTyp: */ PragTyp_DATABASE_LIST,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
+ {/* zName: */ "database_list",
+ /* ePragTyp: */ PragTyp_DATABASE_LIST,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
/* ColNames: */ 47, 3,
- /* iArg: */ 0 },
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
- {/* zName: */ "default_cache_size",
- /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ {/* zName: */ "default_cache_size",
+ /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
/* ColNames: */ 55, 1,
- /* iArg: */ 0 },
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- {/* zName: */ "defer_foreign_keys",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_DeferFKs },
+ {/* zName: */ "defer_foreign_keys",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_DeferFKs },
#endif
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- {/* zName: */ "empty_result_callbacks",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_NullCallback },
+ {/* zName: */ "empty_result_callbacks",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_NullCallback },
#endif
#if !defined(SQLITE_OMIT_UTF16)
- {/* zName: */ "encoding",
- /* ePragTyp: */ PragTyp_ENCODING,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "encoding",
+ /* ePragTyp: */ PragTyp_ENCODING,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- {/* zName: */ "foreign_key_check",
- /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
+ {/* zName: */ "foreign_key_check",
+ /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 43, 4,
- /* iArg: */ 0 },
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
- {/* zName: */ "foreign_key_list",
- /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ {/* zName: */ "foreign_key_list",
+ /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 0, 8,
- /* iArg: */ 0 },
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- {/* zName: */ "foreign_keys",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_ForeignKeys },
+ {/* zName: */ "foreign_keys",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ForeignKeys },
#endif
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
- {/* zName: */ "freelist_count",
- /* ePragTyp: */ PragTyp_HEADER_VALUE,
- /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0,
- /* ColNames: */ 0, 0,
- /* iArg: */ BTREE_FREE_PAGE_COUNT },
+ {/* zName: */ "freelist_count",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_FREE_PAGE_COUNT },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- {/* zName: */ "full_column_names",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_FullColNames },
- {/* zName: */ "fullfsync",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_FullFSync },
-#endif
-#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ {/* zName: */ "full_column_names",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_FullColNames },
+ {/* zName: */ "fullfsync",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_FullFSync },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
- {/* zName: */ "function_list",
- /* ePragTyp: */ PragTyp_FUNCTION_LIST,
- /* ePragFlg: */ PragFlg_Result0,
+ {/* zName: */ "function_list",
+ /* ePragTyp: */ PragTyp_FUNCTION_LIST,
+ /* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 27, 6,
- /* iArg: */ 0 },
-#endif
-#endif
+ /* iArg: */ 0 },
+#endif
+#endif
{/* zName: */ "hard_heap_limit",
/* ePragTyp: */ PragTyp_HARD_HEAP_LIMIT,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 0, 0,
+ /* ColNames: */ 0, 0,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_CHECK)
- {/* zName: */ "ignore_check_constraints",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_IgnoreChecks },
+ {/* zName: */ "ignore_check_constraints",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_IgnoreChecks },
#endif
#endif
#if !defined(SQLITE_OMIT_AUTOVACUUM)
- {/* zName: */ "incremental_vacuum",
- /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_NoColumns,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "incremental_vacuum",
+ /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_NoColumns,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
- {/* zName: */ "index_info",
- /* ePragTyp: */ PragTyp_INDEX_INFO,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ {/* zName: */ "index_info",
+ /* ePragTyp: */ PragTyp_INDEX_INFO,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 21, 3,
- /* iArg: */ 0 },
- {/* zName: */ "index_list",
- /* ePragTyp: */ PragTyp_INDEX_LIST,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* iArg: */ 0 },
+ {/* zName: */ "index_list",
+ /* ePragTyp: */ PragTyp_INDEX_LIST,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 38, 5,
- /* iArg: */ 0 },
- {/* zName: */ "index_xinfo",
- /* ePragTyp: */ PragTyp_INDEX_INFO,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* iArg: */ 0 },
+ {/* zName: */ "index_xinfo",
+ /* ePragTyp: */ PragTyp_INDEX_INFO,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 21, 6,
- /* iArg: */ 1 },
+ /* iArg: */ 1 },
#endif
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
- {/* zName: */ "integrity_check",
- /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
+ {/* zName: */ "integrity_check",
+ /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- {/* zName: */ "journal_mode",
- /* ePragTyp: */ PragTyp_JOURNAL_MODE,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
- {/* zName: */ "journal_size_limit",
- /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "journal_mode",
+ /* ePragTyp: */ PragTyp_JOURNAL_MODE,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "journal_size_limit",
+ /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "legacy_alter_table",
@@ -129280,171 +129280,171 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ SQLITE_LegacyAlter },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
- {/* zName: */ "lock_proxy_file",
- /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
- /* ePragFlg: */ PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "lock_proxy_file",
+ /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
+ /* ePragFlg: */ PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
- {/* zName: */ "lock_status",
- /* ePragTyp: */ PragTyp_LOCK_STATUS,
- /* ePragFlg: */ PragFlg_Result0,
+ {/* zName: */ "lock_status",
+ /* ePragTyp: */ PragTyp_LOCK_STATUS,
+ /* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 53, 2,
- /* iArg: */ 0 },
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- {/* zName: */ "locking_mode",
- /* ePragTyp: */ PragTyp_LOCKING_MODE,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
- {/* zName: */ "max_page_count",
- /* ePragTyp: */ PragTyp_PAGE_COUNT,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
- {/* zName: */ "mmap_size",
- /* ePragTyp: */ PragTyp_MMAP_SIZE,
- /* ePragFlg: */ 0,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
-#endif
-#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
-#if !defined(SQLITE_OMIT_VIRTUALTABLE)
+ {/* zName: */ "locking_mode",
+ /* ePragTyp: */ PragTyp_LOCKING_MODE,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "max_page_count",
+ /* ePragTyp: */ PragTyp_PAGE_COUNT,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "mmap_size",
+ /* ePragTyp: */ PragTyp_MMAP_SIZE,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+#if !defined(SQLITE_OMIT_VIRTUALTABLE)
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
- {/* zName: */ "module_list",
- /* ePragTyp: */ PragTyp_MODULE_LIST,
- /* ePragFlg: */ PragFlg_Result0,
+ {/* zName: */ "module_list",
+ /* ePragTyp: */ PragTyp_MODULE_LIST,
+ /* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 9, 1,
- /* iArg: */ 0 },
-#endif
-#endif
-#endif
- {/* zName: */ "optimize",
- /* ePragTyp: */ PragTyp_OPTIMIZE,
- /* ePragFlg: */ PragFlg_Result1|PragFlg_NeedSchema,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
-#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- {/* zName: */ "page_count",
- /* ePragTyp: */ PragTyp_PAGE_COUNT,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
- {/* zName: */ "page_size",
- /* ePragTyp: */ PragTyp_PAGE_SIZE,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
-#endif
+ /* iArg: */ 0 },
+#endif
+#endif
+#endif
+ {/* zName: */ "optimize",
+ /* ePragTyp: */ PragTyp_OPTIMIZE,
+ /* ePragFlg: */ PragFlg_Result1|PragFlg_NeedSchema,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ {/* zName: */ "page_count",
+ /* ePragTyp: */ PragTyp_PAGE_COUNT,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "page_size",
+ /* ePragTyp: */ PragTyp_PAGE_SIZE,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if defined(SQLITE_DEBUG)
- {/* zName: */ "parser_trace",
+ {/* zName: */ "parser_trace",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
+ /* ColNames: */ 0, 0,
/* iArg: */ SQLITE_ParserTrace },
-#endif
+#endif
#endif
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
- {/* zName: */ "pragma_list",
- /* ePragTyp: */ PragTyp_PRAGMA_LIST,
- /* ePragFlg: */ PragFlg_Result0,
+ {/* zName: */ "pragma_list",
+ /* ePragTyp: */ PragTyp_PRAGMA_LIST,
+ /* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 9, 1,
- /* iArg: */ 0 },
-#endif
+ /* iArg: */ 0 },
+#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- {/* zName: */ "query_only",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_QueryOnly },
+ {/* zName: */ "query_only",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_QueryOnly },
#endif
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
- {/* zName: */ "quick_check",
- /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
+ {/* zName: */ "quick_check",
+ /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- {/* zName: */ "read_uncommitted",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_ReadUncommit },
- {/* zName: */ "recursive_triggers",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_RecTriggers },
- {/* zName: */ "reverse_unordered_selects",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_ReverseOrder },
+ {/* zName: */ "read_uncommitted",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ReadUncommit },
+ {/* zName: */ "recursive_triggers",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_RecTriggers },
+ {/* zName: */ "reverse_unordered_selects",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ReverseOrder },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
- {/* zName: */ "schema_version",
- /* ePragTyp: */ PragTyp_HEADER_VALUE,
- /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
- /* ColNames: */ 0, 0,
- /* iArg: */ BTREE_SCHEMA_VERSION },
+ {/* zName: */ "schema_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_SCHEMA_VERSION },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- {/* zName: */ "secure_delete",
- /* ePragTyp: */ PragTyp_SECURE_DELETE,
- /* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "secure_delete",
+ /* ePragTyp: */ PragTyp_SECURE_DELETE,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- {/* zName: */ "short_column_names",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_ShortColNames },
-#endif
- {/* zName: */ "shrink_memory",
- /* ePragTyp: */ PragTyp_SHRINK_MEMORY,
- /* ePragFlg: */ PragFlg_NoColumns,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
- {/* zName: */ "soft_heap_limit",
- /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
- /* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "short_column_names",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ShortColNames },
+#endif
+ {/* zName: */ "shrink_memory",
+ /* ePragTyp: */ PragTyp_SHRINK_MEMORY,
+ /* ePragFlg: */ PragFlg_NoColumns,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "soft_heap_limit",
+ /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if defined(SQLITE_DEBUG)
- {/* zName: */ "sql_trace",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_SqlTrace },
+ {/* zName: */ "sql_trace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_SqlTrace },
#endif
#endif
-#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
- {/* zName: */ "stats",
- /* ePragTyp: */ PragTyp_STATS,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
+ {/* zName: */ "stats",
+ /* ePragTyp: */ PragTyp_STATS,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
/* ColNames: */ 33, 5,
- /* iArg: */ 0 },
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- {/* zName: */ "synchronous",
- /* ePragTyp: */ PragTyp_SYNCHRONOUS,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "synchronous",
+ /* ePragTyp: */ PragTyp_SYNCHRONOUS,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
- {/* zName: */ "table_info",
- /* ePragTyp: */ PragTyp_TABLE_INFO,
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ {/* zName: */ "table_info",
+ /* ePragTyp: */ PragTyp_TABLE_INFO,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 8, 6,
- /* iArg: */ 0 },
+ /* iArg: */ 0 },
{/* zName: */ "table_list",
/* ePragTyp: */ PragTyp_TABLE_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1,
@@ -129457,22 +129457,22 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ 1 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- {/* zName: */ "temp_store",
- /* ePragTyp: */ PragTyp_TEMP_STORE,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
- {/* zName: */ "temp_store_directory",
- /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
- /* ePragFlg: */ PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
-#endif
- {/* zName: */ "threads",
- /* ePragTyp: */ PragTyp_THREADS,
- /* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ {/* zName: */ "temp_store",
+ /* ePragTyp: */ PragTyp_TEMP_STORE,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "temp_store_directory",
+ /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
+ /* ePragFlg: */ PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+ {/* zName: */ "threads",
+ /* ePragTyp: */ PragTyp_THREADS,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "trusted_schema",
/* ePragTyp: */ PragTyp_FLAG,
@@ -129481,58 +129481,58 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ SQLITE_TrustedSchema },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
- {/* zName: */ "user_version",
- /* ePragTyp: */ PragTyp_HEADER_VALUE,
- /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
- /* ColNames: */ 0, 0,
- /* iArg: */ BTREE_USER_VERSION },
+ {/* zName: */ "user_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_USER_VERSION },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if defined(SQLITE_DEBUG)
- {/* zName: */ "vdbe_addoptrace",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_VdbeAddopTrace },
- {/* zName: */ "vdbe_debug",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
- {/* zName: */ "vdbe_eqp",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_VdbeEQP },
- {/* zName: */ "vdbe_listing",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_VdbeListing },
- {/* zName: */ "vdbe_trace",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_VdbeTrace },
+ {/* zName: */ "vdbe_addoptrace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeAddopTrace },
+ {/* zName: */ "vdbe_debug",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
+ {/* zName: */ "vdbe_eqp",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeEQP },
+ {/* zName: */ "vdbe_listing",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeListing },
+ {/* zName: */ "vdbe_trace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeTrace },
#endif
#endif
#if !defined(SQLITE_OMIT_WAL)
- {/* zName: */ "wal_autocheckpoint",
- /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
- /* ePragFlg: */ 0,
- /* ColNames: */ 0, 0,
- /* iArg: */ 0 },
- {/* zName: */ "wal_checkpoint",
- /* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
- /* ePragFlg: */ PragFlg_NeedSchema,
+ {/* zName: */ "wal_autocheckpoint",
+ /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "wal_checkpoint",
+ /* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
+ /* ePragFlg: */ PragFlg_NeedSchema,
/* ColNames: */ 50, 3,
- /* iArg: */ 0 },
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- {/* zName: */ "writable_schema",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
- /* ColNames: */ 0, 0,
+ {/* zName: */ "writable_schema",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
@@ -129544,7 +129544,7 @@ static const PragmaName aPragmaName[] = {
/*
** Interpret the given string as a safety level. Return 0 for OFF,
** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or
-** unrecognized string argument. The FULL and EXTRA option is disallowed
+** unrecognized string argument. The FULL and EXTRA option is disallowed
** if the omitFull parameter it 1.
**
** Note that the values returned are one less that the values that
@@ -129553,21 +129553,21 @@ static const PragmaName aPragmaName[] = {
** and older scripts may have used numbers 0 for OFF and 1 for ON.
*/
static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){
- /* 123456789 123456789 123 */
- static const char zText[] = "onoffalseyestruextrafull";
- static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 15, 20};
- static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 5, 4};
- static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 3, 2};
- /* on no off false yes true extra full */
+ /* 123456789 123456789 123 */
+ static const char zText[] = "onoffalseyestruextrafull";
+ static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 15, 20};
+ static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 5, 4};
+ static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 3, 2};
+ /* on no off false yes true extra full */
int i, n;
if( sqlite3Isdigit(*z) ){
return (u8)sqlite3Atoi(z);
}
n = sqlite3Strlen30(z);
- for(i=0; i<ArraySize(iLength); i++){
- if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0
- && (!omitFull || iValue[i]<=1)
- ){
+ for(i=0; i<ArraySize(iLength); i++){
+ if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0
+ && (!omitFull || iValue[i]<=1)
+ ){
return iValue[i];
}
}
@@ -129676,42 +129676,42 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
#endif /* SQLITE_PAGER_PRAGMAS */
/*
-** Set result column names for a pragma.
-*/
-static void setPragmaResultColumnNames(
- Vdbe *v, /* The query under construction */
- const PragmaName *pPragma /* The pragma */
-){
- u8 n = pPragma->nPragCName;
- sqlite3VdbeSetNumCols(v, n==0 ? 1 : n);
- if( n==0 ){
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC);
- }else{
- int i, j;
- for(i=0, j=pPragma->iPragCName; i<n; i++, j++){
- sqlite3VdbeSetColName(v, i, COLNAME_NAME, pragCName[j], SQLITE_STATIC);
- }
- }
-}
-
-/*
+** Set result column names for a pragma.
+*/
+static void setPragmaResultColumnNames(
+ Vdbe *v, /* The query under construction */
+ const PragmaName *pPragma /* The pragma */
+){
+ u8 n = pPragma->nPragCName;
+ sqlite3VdbeSetNumCols(v, n==0 ? 1 : n);
+ if( n==0 ){
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC);
+ }else{
+ int i, j;
+ for(i=0, j=pPragma->iPragCName; i<n; i++, j++){
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, pragCName[j], SQLITE_STATIC);
+ }
+ }
+}
+
+/*
** Generate code to return a single integer value.
*/
-static void returnSingleInt(Vdbe *v, i64 value){
- sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8*)&value, P4_INT64);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
-}
-
-/*
-** Generate code to return a single text value.
-*/
-static void returnSingleText(
- Vdbe *v, /* Prepared statement under construction */
- const char *zValue /* Value to be returned */
-){
- if( zValue ){
- sqlite3VdbeLoadString(v, 1, (const char*)zValue);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+static void returnSingleInt(Vdbe *v, i64 value){
+ sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8*)&value, P4_INT64);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+}
+
+/*
+** Generate code to return a single text value.
+*/
+static void returnSingleText(
+ Vdbe *v, /* Prepared statement under construction */
+ const char *zValue /* Value to be returned */
+){
+ if( zValue ){
+ sqlite3VdbeLoadString(v, 1, (const char*)zValue);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
}
@@ -129789,26 +129789,26 @@ SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){
}
/*
-** Locate a pragma in the aPragmaName[] array.
-*/
-static const PragmaName *pragmaLocate(const char *zName){
- int upr, lwr, mid = 0, rc;
- lwr = 0;
- upr = ArraySize(aPragmaName)-1;
- while( lwr<=upr ){
- mid = (lwr+upr)/2;
- rc = sqlite3_stricmp(zName, aPragmaName[mid].zName);
- if( rc==0 ) break;
- if( rc<0 ){
- upr = mid - 1;
- }else{
- lwr = mid + 1;
- }
- }
- return lwr>upr ? 0 : &aPragmaName[mid];
-}
-
-/*
+** Locate a pragma in the aPragmaName[] array.
+*/
+static const PragmaName *pragmaLocate(const char *zName){
+ int upr, lwr, mid = 0, rc;
+ lwr = 0;
+ upr = ArraySize(aPragmaName)-1;
+ while( lwr<=upr ){
+ mid = (lwr+upr)/2;
+ rc = sqlite3_stricmp(zName, aPragmaName[mid].zName);
+ if( rc==0 ) break;
+ if( rc<0 ){
+ upr = mid - 1;
+ }else{
+ lwr = mid + 1;
+ }
+ }
+ return lwr>upr ? 0 : &aPragmaName[mid];
+}
+
+/*
** Create zero or more entries in the output for the SQL functions
** defined by FuncDef p.
*/
@@ -129858,27 +129858,27 @@ static void pragmaFunclistLine(
/*
-** Helper subroutine for PRAGMA integrity_check:
-**
-** Generate code to output a single-column result row with a value of the
-** string held in register 3. Decrement the result count in register 1
-** and halt if the maximum number of result rows have been issued.
-*/
-static int integrityCheckResultRow(Vdbe *v){
- int addr;
- sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
- addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
- VdbeCoverage(v);
- sqlite3VdbeAddOp0(v, OP_Halt);
- return addr;
-}
-
-/*
+** Helper subroutine for PRAGMA integrity_check:
+**
+** Generate code to output a single-column result row with a value of the
+** string held in register 3. Decrement the result count in register 1
+** and halt if the maximum number of result rows have been issued.
+*/
+static int integrityCheckResultRow(Vdbe *v){
+ int addr;
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
+ addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp0(v, OP_Halt);
+ return addr;
+}
+
+/*
** Process a pragma statement.
**
** Pragmas are of this form:
**
-** PRAGMA [schema.]id [= value]
+** PRAGMA [schema.]id [= value]
**
** The identifier might also be a string. The value is a string, and
** identifier, or a number. If minusFlag is true, then the value is
@@ -129890,8 +129890,8 @@ static int integrityCheckResultRow(Vdbe *v){
*/
SQLITE_PRIVATE void sqlite3Pragma(
Parse *pParse,
- Token *pId1, /* First part of [schema.]id field */
- Token *pId2, /* Second part of [schema.]id field, or NULL */
+ Token *pId1, /* First part of [schema.]id field */
+ Token *pId2, /* Second part of [schema.]id field, or NULL */
Token *pValue, /* Token for <value>, or NULL */
int minusFlag /* True if a '-' sign preceded <value> */
){
@@ -129905,13 +129905,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3 *db = pParse->db; /* The database connection */
Db *pDb; /* The specific database being pragmaed */
Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */
- const PragmaName *pPragma; /* The pragma */
+ const PragmaName *pPragma; /* The pragma */
if( v==0 ) return;
sqlite3VdbeRunOnlyOnce(v);
pParse->nMem = 2;
- /* Interpret the [schema.] part of the pragma statement. iDb is the
+ /* Interpret the [schema.] part of the pragma statement. iDb is the
** index of the database this pragma is being applied to in db.aDb[]. */
iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
if( iDb<0 ) return;
@@ -129933,7 +129933,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
assert( pId2 );
- zDb = pId2->n>0 ? pDb->zDbSName : 0;
+ zDb = pId2->n>0 ? pDb->zDbSName : 0;
if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
goto pragma_out;
}
@@ -129960,10 +129960,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
db->busyHandler.nBusy = 0;
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
if( rc==SQLITE_OK ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT);
- returnSingleText(v, aFcntl[0]);
- sqlite3_free(aFcntl[0]);
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT);
+ returnSingleText(v, aFcntl[0]);
+ sqlite3_free(aFcntl[0]);
goto pragma_out;
}
if( rc!=SQLITE_NOTFOUND ){
@@ -129977,7 +129977,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
/* Locate the pragma in the lookup table */
- pPragma = pragmaLocate(zLeft);
+ pPragma = pragmaLocate(zLeft);
if( pPragma==0 ){
/* IMP: R-43042-22504 No error messages are generated if an
** unknown pragma is issued. */
@@ -129985,24 +129985,24 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
/* Make sure the database schema is loaded if the pragma requires that */
- if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){
+ if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
}
- /* Register the result column names for pragmas that return results */
+ /* Register the result column names for pragmas that return results */
if( (pPragma->mPragFlg & PragFlg_NoColumns)==0
- && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0)
- ){
- setPragmaResultColumnNames(v, pPragma);
- }
-
+ && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0)
+ ){
+ setPragmaResultColumnNames(v, pPragma);
+ }
+
/* Jump to the appropriate pragma handler */
switch( pPragma->ePragTyp ){
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
/*
- ** PRAGMA [schema.]default_cache_size
- ** PRAGMA [schema.]default_cache_size=N
+ ** PRAGMA [schema.]default_cache_size
+ ** PRAGMA [schema.]default_cache_size=N
**
** The first form reports the current persistent setting for the
** page cache size. The value returned is the maximum number of
@@ -130029,20 +130029,20 @@ SQLITE_PRIVATE void sqlite3Pragma(
{ OP_Noop, 0, 0, 0},
{ OP_ResultRow, 1, 1, 0},
};
- VdbeOp *aOp;
+ VdbeOp *aOp;
sqlite3VdbeUsesBtree(v, iDb);
if( !zRight ){
pParse->nMem += 2;
- sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize));
- aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn);
- if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
- aOp[0].p1 = iDb;
- aOp[1].p1 = iDb;
- aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE;
+ sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize));
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn);
+ if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
+ aOp[0].p1 = iDb;
+ aOp[1].p1 = iDb;
+ aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE;
}else{
int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size);
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
pDb->pSchema->cache_size = size;
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
@@ -130053,8 +130053,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
/*
- ** PRAGMA [schema.]page_size
- ** PRAGMA [schema.]page_size=N
+ ** PRAGMA [schema.]page_size
+ ** PRAGMA [schema.]page_size=N
**
** The first form reports the current setting for the
** database page size in bytes. The second form sets the
@@ -130066,37 +130066,37 @@ SQLITE_PRIVATE void sqlite3Pragma(
assert( pBt!=0 );
if( !zRight ){
int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
- returnSingleInt(v, size);
+ returnSingleInt(v, size);
}else{
/* Malloc may fail when setting the page-size, as there is an internal
** buffer that the pager module resizes using sqlite3_realloc().
*/
db->nextPagesize = sqlite3Atoi(zRight);
if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,0,0) ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
}
}
break;
}
/*
- ** PRAGMA [schema.]secure_delete
- ** PRAGMA [schema.]secure_delete=ON/OFF/FAST
+ ** PRAGMA [schema.]secure_delete
+ ** PRAGMA [schema.]secure_delete=ON/OFF/FAST
**
** The first form reports the current setting for the
** secure_delete flag. The second form changes the secure_delete
- ** flag setting and reports the new value.
+ ** flag setting and reports the new value.
*/
case PragTyp_SECURE_DELETE: {
Btree *pBt = pDb->pBt;
int b = -1;
assert( pBt!=0 );
if( zRight ){
- if( sqlite3_stricmp(zRight, "fast")==0 ){
- b = 2;
- }else{
- b = sqlite3GetBoolean(zRight, 0);
- }
+ if( sqlite3_stricmp(zRight, "fast")==0 ){
+ b = 2;
+ }else{
+ b = sqlite3GetBoolean(zRight, 0);
+ }
}
if( pId2->n==0 && b>=0 ){
int ii;
@@ -130105,13 +130105,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
b = sqlite3BtreeSecureDelete(pBt, b);
- returnSingleInt(v, b);
+ returnSingleInt(v, b);
break;
}
/*
- ** PRAGMA [schema.]max_page_count
- ** PRAGMA [schema.]max_page_count=N
+ ** PRAGMA [schema.]max_page_count
+ ** PRAGMA [schema.]max_page_count=N
**
** The first form reports the current setting for the
** maximum number of pages in the database file. The
@@ -130122,7 +130122,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** change. The only purpose is to provide an easy way to test
** the sqlite3AbsInt32() function.
**
- ** PRAGMA [schema.]page_count
+ ** PRAGMA [schema.]page_count
**
** Return the number of pages in the specified database.
*/
@@ -130147,8 +130147,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
/*
- ** PRAGMA [schema.]locking_mode
- ** PRAGMA [schema.]locking_mode = (normal|exclusive)
+ ** PRAGMA [schema.]locking_mode
+ ** PRAGMA [schema.]locking_mode = (normal|exclusive)
*/
case PragTyp_LOCKING_MODE: {
const char *zRet = "normal";
@@ -130188,13 +130188,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){
zRet = "exclusive";
}
- returnSingleText(v, zRet);
+ returnSingleText(v, zRet);
break;
}
/*
- ** PRAGMA [schema.]journal_mode
- ** PRAGMA [schema.]journal_mode =
+ ** PRAGMA [schema.]journal_mode
+ ** PRAGMA [schema.]journal_mode =
** (delete|persist|off|truncate|memory|wal|off)
*/
case PragTyp_JOURNAL_MODE: {
@@ -130238,8 +130238,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
/*
- ** PRAGMA [schema.]journal_size_limit
- ** PRAGMA [schema.]journal_size_limit=N
+ ** PRAGMA [schema.]journal_size_limit
+ ** PRAGMA [schema.]journal_size_limit=N
**
** Get or set the size limit on rollback journal files.
*/
@@ -130251,15 +130251,15 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( iLimit<-1 ) iLimit = -1;
}
iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
- returnSingleInt(v, iLimit);
+ returnSingleInt(v, iLimit);
break;
}
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
/*
- ** PRAGMA [schema.]auto_vacuum
- ** PRAGMA [schema.]auto_vacuum=N
+ ** PRAGMA [schema.]auto_vacuum
+ ** PRAGMA [schema.]auto_vacuum=N
**
** Get or set the value of the database 'auto-vacuum' parameter.
** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL
@@ -130269,7 +130269,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
Btree *pBt = pDb->pBt;
assert( pBt!=0 );
if( !zRight ){
- returnSingleInt(v, sqlite3BtreeGetAutoVacuum(pBt));
+ returnSingleInt(v, sqlite3BtreeGetAutoVacuum(pBt));
}else{
int eAuto = getAutoVacuum(zRight);
assert( eAuto>=0 && eAuto<=2 );
@@ -130292,18 +130292,18 @@ SQLITE_PRIVATE void sqlite3Pragma(
{ OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
{ OP_If, 1, 0, 0}, /* 2 */
{ OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */
- { OP_SetCookie, 0, BTREE_INCR_VACUUM, 0}, /* 4 */
+ { OP_SetCookie, 0, BTREE_INCR_VACUUM, 0}, /* 4 */
};
- VdbeOp *aOp;
- int iAddr = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6));
- aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn);
- if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
- aOp[0].p1 = iDb;
- aOp[1].p1 = iDb;
- aOp[2].p2 = iAddr+4;
- aOp[4].p1 = iDb;
- aOp[4].p3 = eAuto - 1;
+ VdbeOp *aOp;
+ int iAddr = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6));
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn);
+ if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
+ aOp[0].p1 = iDb;
+ aOp[1].p1 = iDb;
+ aOp[2].p2 = iAddr+4;
+ aOp[4].p1 = iDb;
+ aOp[4].p3 = eAuto - 1;
sqlite3VdbeUsesBtree(v, iDb);
}
}
@@ -130312,7 +130312,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
#endif
/*
- ** PRAGMA [schema.]incremental_vacuum(N)
+ ** PRAGMA [schema.]incremental_vacuum(N)
**
** Do N steps of incremental vacuuming on a database.
*/
@@ -130335,8 +130335,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
- ** PRAGMA [schema.]cache_size
- ** PRAGMA [schema.]cache_size=N
+ ** PRAGMA [schema.]cache_size
+ ** PRAGMA [schema.]cache_size=N
**
** The first form reports the current local setting for the
** page cache size. The second form sets the local
@@ -130348,7 +130348,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
case PragTyp_CACHE_SIZE: {
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( !zRight ){
- returnSingleInt(v, pDb->pSchema->cache_size);
+ returnSingleInt(v, pDb->pSchema->cache_size);
}else{
int size = sqlite3Atoi(zRight);
pDb->pSchema->cache_size = size;
@@ -130358,51 +130358,51 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
/*
- ** PRAGMA [schema.]cache_spill
- ** PRAGMA cache_spill=BOOLEAN
- ** PRAGMA [schema.]cache_spill=N
+ ** PRAGMA [schema.]cache_spill
+ ** PRAGMA cache_spill=BOOLEAN
+ ** PRAGMA [schema.]cache_spill=N
**
- ** The first form reports the current local setting for the
- ** page cache spill size. The second form turns cache spill on
- ** or off. When turnning cache spill on, the size is set to the
- ** current cache_size. The third form sets a spill size that
- ** may be different form the cache size.
- ** If N is positive then that is the
- ** number of pages in the cache. If N is negative, then the
- ** number of pages is adjusted so that the cache uses -N kibibytes
- ** of memory.
- **
- ** If the number of cache_spill pages is less then the number of
- ** cache_size pages, no spilling occurs until the page count exceeds
- ** the number of cache_size pages.
- **
- ** The cache_spill=BOOLEAN setting applies to all attached schemas,
- ** not just the schema specified.
- */
- case PragTyp_CACHE_SPILL: {
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- if( !zRight ){
- returnSingleInt(v,
+ ** The first form reports the current local setting for the
+ ** page cache spill size. The second form turns cache spill on
+ ** or off. When turnning cache spill on, the size is set to the
+ ** current cache_size. The third form sets a spill size that
+ ** may be different form the cache size.
+ ** If N is positive then that is the
+ ** number of pages in the cache. If N is negative, then the
+ ** number of pages is adjusted so that the cache uses -N kibibytes
+ ** of memory.
+ **
+ ** If the number of cache_spill pages is less then the number of
+ ** cache_size pages, no spilling occurs until the page count exceeds
+ ** the number of cache_size pages.
+ **
+ ** The cache_spill=BOOLEAN setting applies to all attached schemas,
+ ** not just the schema specified.
+ */
+ case PragTyp_CACHE_SPILL: {
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ if( !zRight ){
+ returnSingleInt(v,
(db->flags & SQLITE_CacheSpill)==0 ? 0 :
- sqlite3BtreeSetSpillSize(pDb->pBt,0));
- }else{
- int size = 1;
- if( sqlite3GetInt32(zRight, &size) ){
- sqlite3BtreeSetSpillSize(pDb->pBt, size);
- }
- if( sqlite3GetBoolean(zRight, size!=0) ){
- db->flags |= SQLITE_CacheSpill;
- }else{
+ sqlite3BtreeSetSpillSize(pDb->pBt,0));
+ }else{
+ int size = 1;
+ if( sqlite3GetInt32(zRight, &size) ){
+ sqlite3BtreeSetSpillSize(pDb->pBt, size);
+ }
+ if( sqlite3GetBoolean(zRight, size!=0) ){
+ db->flags |= SQLITE_CacheSpill;
+ }else{
db->flags &= ~(u64)SQLITE_CacheSpill;
- }
- setAllPagerFlags(db);
- }
- break;
- }
-
- /*
- ** PRAGMA [schema.]mmap_size(N)
- **
+ }
+ setAllPagerFlags(db);
+ }
+ break;
+ }
+
+ /*
+ ** PRAGMA [schema.]mmap_size(N)
+ **
** Used to set mapping size limit. The mapping size limit is
** used to limit the aggregate size of all memory mapped regions of the
** database file. If this parameter is set to zero, then memory mapping
@@ -130436,7 +130436,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
rc = SQLITE_OK;
#endif
if( rc==SQLITE_OK ){
- returnSingleInt(v, sz);
+ returnSingleInt(v, sz);
}else if( rc!=SQLITE_NOTFOUND ){
pParse->nErr++;
pParse->rc = rc;
@@ -130457,7 +130457,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
case PragTyp_TEMP_STORE: {
if( !zRight ){
- returnSingleInt(v, db->temp_store);
+ returnSingleInt(v, db->temp_store);
}else{
changeTempStorage(pParse, zRight);
}
@@ -130476,7 +130476,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
case PragTyp_TEMP_STORE_DIRECTORY: {
if( !zRight ){
- returnSingleText(v, sqlite3_temp_directory);
+ returnSingleText(v, sqlite3_temp_directory);
}else{
#ifndef SQLITE_OMIT_WSD
if( zRight[0] ){
@@ -130520,7 +130520,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
case PragTyp_DATA_STORE_DIRECTORY: {
if( !zRight ){
- returnSingleText(v, sqlite3_data_directory);
+ returnSingleText(v, sqlite3_data_directory);
}else{
#ifndef SQLITE_OMIT_WSD
if( zRight[0] ){
@@ -130545,8 +130545,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
#if SQLITE_ENABLE_LOCKING_STYLE
/*
- ** PRAGMA [schema.]lock_proxy_file
- ** PRAGMA [schema.]lock_proxy_file = ":auto:"|"lock_file_path"
+ ** PRAGMA [schema.]lock_proxy_file
+ ** PRAGMA [schema.]lock_proxy_file = ":auto:"|"lock_file_path"
**
** Return or set the value of the lock_proxy_file flag. Changing
** the value sets a specific file to be used for database access locks.
@@ -130559,7 +130559,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3_file *pFile = sqlite3PagerFile(pPager);
sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE,
&proxy_file_path);
- returnSingleText(v, proxy_file_path);
+ returnSingleText(v, proxy_file_path);
}else{
Pager *pPager = sqlite3BtreePager(pDb->pBt);
sqlite3_file *pFile = sqlite3PagerFile(pPager);
@@ -130581,8 +130581,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
/*
- ** PRAGMA [schema.]synchronous
- ** PRAGMA [schema.]synchronous=OFF|ON|NORMAL|FULL|EXTRA
+ ** PRAGMA [schema.]synchronous
+ ** PRAGMA [schema.]synchronous=OFF|ON|NORMAL|FULL|EXTRA
**
** Return or set the local value of the synchronous flag. Changing
** the local value does not make changes to the disk file and the
@@ -130591,16 +130591,16 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
case PragTyp_SYNCHRONOUS: {
if( !zRight ){
- returnSingleInt(v, pDb->safety_level-1);
+ returnSingleInt(v, pDb->safety_level-1);
}else{
if( !db->autoCommit ){
sqlite3ErrorMsg(pParse,
"Safety level may not be changed inside a transaction");
- }else if( iDb!=1 ){
+ }else if( iDb!=1 ){
int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
if( iLevel==0 ) iLevel = 1;
pDb->safety_level = iLevel;
- pDb->bSyncSet = 1;
+ pDb->bSyncSet = 1;
setAllPagerFlags(db);
}
}
@@ -130611,8 +130611,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
case PragTyp_FLAG: {
if( zRight==0 ){
- setPragmaResultColumnNames(v, pPragma);
- returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
+ setPragmaResultColumnNames(v, pPragma);
+ returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
}else{
u64 mask = pPragma->iArg; /* Mask of bits to set or clear. */
if( db->autoCommit==0 ){
@@ -130646,7 +130646,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** compiler (eg. count_changes). So add an opcode to expire all
** compiled SQL statements after modifying a pragma value.
*/
- sqlite3VdbeAddOp0(v, OP_Expire);
+ sqlite3VdbeAddOp0(v, OP_Expire);
setAllPagerFlags(db);
}
break;
@@ -130665,12 +130665,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
** type: Column declaration type.
** notnull: True if 'NOT NULL' is part of column declaration
** dflt_value: The default value for the column, if any.
- ** pk: Non-zero for PK fields.
+ ** pk: Non-zero for PK fields.
*/
case PragTyp_TABLE_INFO: if( zRight ){
Table *pTab;
sqlite3CodeVerifyNamedSchema(pParse, zDb);
- pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
+ pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
if( pTab ){
int i, k;
int nHidden = 0;
@@ -130706,10 +130706,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
assert( pColExpr==0 || !ExprHasProperty(pColExpr, EP_IntValue)
|| isHidden>=2 );
sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
- i-nHidden,
+ i-nHidden,
pCol->zCnName,
- sqlite3ColumnType(pCol,""),
- pCol->notNull ? 1 : 0,
+ sqlite3ColumnType(pCol,""),
+ pCol->notNull ? 1 : 0,
(isHidden>=2 || pColExpr==0) ? 0 : pColExpr->u.zToken,
k,
isHidden);
@@ -130793,32 +130793,32 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
break;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
case PragTyp_STATS: {
Index *pIdx;
HashElem *i;
- pParse->nMem = 5;
+ pParse->nMem = 5;
sqlite3CodeVerifySchema(pParse, iDb);
for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
Table *pTab = sqliteHashData(i);
- sqlite3VdbeMultiLoad(v, 1, "ssiii",
+ sqlite3VdbeMultiLoad(v, 1, "ssiii",
sqlite3PreferredTableName(pTab->zName),
- 0,
- pTab->szTabRow,
- pTab->nRowLogEst,
- pTab->tabFlags);
+ 0,
+ pTab->szTabRow,
+ pTab->nRowLogEst,
+ pTab->tabFlags);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- sqlite3VdbeMultiLoad(v, 2, "siiiX",
- pIdx->zName,
- pIdx->szIdxRow,
- pIdx->aiRowLogEst[0],
- pIdx->hasStat1);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
+ sqlite3VdbeMultiLoad(v, 2, "siiiX",
+ pIdx->zName,
+ pIdx->szIdxRow,
+ pIdx->aiRowLogEst[0],
+ pIdx->hasStat1);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
}
}
}
break;
-#endif
+#endif
case PragTyp_INDEX_INFO: if( zRight ){
Index *pIdx;
@@ -130848,16 +130848,16 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
pTab = pIdx->pTable;
sqlite3CodeVerifySchema(pParse, iIdxDb);
- assert( pParse->nMem<=pPragma->nPragCName );
+ assert( pParse->nMem<=pPragma->nPragCName );
for(i=0; i<mx; i++){
i16 cnum = pIdx->aiColumn[i];
- sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum,
+ sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum,
cnum<0 ? 0 : pTab->aCol[cnum].zCnName);
if( pPragma->iArg ){
- sqlite3VdbeMultiLoad(v, 4, "isiX",
- pIdx->aSortOrder[i],
- pIdx->azColl[i],
- i<pIdx->nKeyCol);
+ sqlite3VdbeMultiLoad(v, 4, "isiX",
+ pIdx->aSortOrder[i],
+ pIdx->azColl[i],
+ i<pIdx->nKeyCol);
}
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem);
}
@@ -130876,12 +130876,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3CodeVerifySchema(pParse, iTabDb);
for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
const char *azOrigin[] = { "c", "u", "pk" };
- sqlite3VdbeMultiLoad(v, 1, "isisi",
- i,
- pIdx->zName,
- IsUniqueIndex(pIdx),
- azOrigin[pIdx->idxType],
- pIdx->pPartIdxWhere!=0);
+ sqlite3VdbeMultiLoad(v, 1, "isisi",
+ i,
+ pIdx->zName,
+ IsUniqueIndex(pIdx),
+ azOrigin[pIdx->idxType],
+ pIdx->pPartIdxWhere!=0);
}
}
}
@@ -130892,11 +130892,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
pParse->nMem = 3;
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pBt==0 ) continue;
- assert( db->aDb[i].zDbSName!=0 );
- sqlite3VdbeMultiLoad(v, 1, "iss",
- i,
- db->aDb[i].zDbSName,
- sqlite3BtreeGetFilename(db->aDb[i].pBt));
+ assert( db->aDb[i].zDbSName!=0 );
+ sqlite3VdbeMultiLoad(v, 1, "iss",
+ i,
+ db->aDb[i].zDbSName,
+ sqlite3BtreeGetFilename(db->aDb[i].pBt));
}
}
break;
@@ -130907,53 +130907,53 @@ SQLITE_PRIVATE void sqlite3Pragma(
pParse->nMem = 2;
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
- sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
+ sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
}
}
break;
-
+
#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
- case PragTyp_FUNCTION_LIST: {
- int i;
- HashElem *j;
- FuncDef *p;
+ case PragTyp_FUNCTION_LIST: {
+ int i;
+ HashElem *j;
+ FuncDef *p;
int showInternFunc = (db->mDbFlags & DBFLAG_InternalFunc)!=0;
pParse->nMem = 6;
- for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
- for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
+ for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
+ for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
assert( p->funcFlags & SQLITE_FUNC_BUILTIN );
pragmaFunclistLine(v, p, 1, showInternFunc);
- }
- }
- for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
- p = (FuncDef*)sqliteHashData(j);
+ }
+ }
+ for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
+ p = (FuncDef*)sqliteHashData(j);
assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 );
pragmaFunclistLine(v, p, 0, showInternFunc);
- }
- }
- break;
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- case PragTyp_MODULE_LIST: {
- HashElem *j;
- pParse->nMem = 1;
- for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){
- Module *pMod = (Module*)sqliteHashData(j);
- sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName);
- }
- }
- break;
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
- case PragTyp_PRAGMA_LIST: {
- int i;
- for(i=0; i<ArraySize(aPragmaName); i++){
- sqlite3VdbeMultiLoad(v, 1, "s", aPragmaName[i].zName);
- }
- }
- break;
-#endif /* SQLITE_INTROSPECTION_PRAGMAS */
-
+ }
+ }
+ break;
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ case PragTyp_MODULE_LIST: {
+ HashElem *j;
+ pParse->nMem = 1;
+ for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){
+ Module *pMod = (Module*)sqliteHashData(j);
+ sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName);
+ }
+ }
+ break;
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+ case PragTyp_PRAGMA_LIST: {
+ int i;
+ for(i=0; i<ArraySize(aPragmaName); i++){
+ sqlite3VdbeMultiLoad(v, 1, "s", aPragmaName[i].zName);
+ }
+ }
+ break;
+#endif /* SQLITE_INTROSPECTION_PRAGMAS */
+
#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
#ifndef SQLITE_OMIT_FOREIGN_KEY
@@ -130971,15 +130971,15 @@ SQLITE_PRIVATE void sqlite3Pragma(
while(pFK){
int j;
for(j=0; j<pFK->nCol; j++){
- sqlite3VdbeMultiLoad(v, 1, "iissssss",
- i,
- j,
- pFK->zTo,
+ sqlite3VdbeMultiLoad(v, 1, "iissssss",
+ i,
+ j,
+ pFK->zTo,
pTab->aCol[pFK->aCol[j].iFrom].zCnName,
- pFK->aCol[j].zCol,
- actionName(pFK->aAction[1]), /* ON UPDATE */
- actionName(pFK->aAction[0]), /* ON DELETE */
- "NONE");
+ pFK->aCol[j].zCol,
+ actionName(pFK->aAction[1]), /* ON UPDATE */
+ actionName(pFK->aAction[0]), /* ON DELETE */
+ "NONE");
}
++i;
pFK = pFK->pNextFrom;
@@ -131028,7 +131028,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
- sqlite3VdbeLoadString(v, regResult, pTab->zName);
+ sqlite3VdbeLoadString(v, regResult, pTab->zName);
assert( IsOrdinaryTable(pTab) );
for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
@@ -131062,39 +131062,39 @@ SQLITE_PRIVATE void sqlite3Pragma(
assert( x==0 || db->mallocFailed );
}
addrOk = sqlite3VdbeMakeLabel(pParse);
-
- /* Generate code to read the child key values into registers
+
+ /* Generate code to read the child key values into registers
** regRow..regRow+n. If any of the child key values are NULL, this
** row cannot cause an FK violation. Jump directly to addrOk in
- ** this case. */
+ ** this case. */
if( regRow+pFK->nCol>pParse->nMem ) pParse->nMem = regRow+pFK->nCol;
- for(j=0; j<pFK->nCol; j++){
- int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom;
- sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j);
- sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
- }
-
- /* Generate code to query the parent index for a matching parent
- ** key. If a match is found, jump to addrOk. */
- if( pIdx ){
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
- sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
- sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
- VdbeCoverage(v);
- }else if( pParent ){
- int jmp = sqlite3VdbeCurrentAddr(v)+2;
- sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
- sqlite3VdbeGoto(v, addrOk);
+ for(j=0; j<pFK->nCol; j++){
+ int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom;
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
+ }
+
+ /* Generate code to query the parent index for a matching parent
+ ** key. If a match is found, jump to addrOk. */
+ if( pIdx ){
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
+ sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
+ sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
+ VdbeCoverage(v);
+ }else if( pParent ){
+ int jmp = sqlite3VdbeCurrentAddr(v)+2;
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, addrOk);
assert( pFK->nCol==1 || db->mallocFailed );
- }
-
- /* Generate code to report an FK violation to the caller. */
- if( HasRowid(pTab) ){
- sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
+ }
+
+ /* Generate code to report an FK violation to the caller. */
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
}else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1);
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1);
}
- sqlite3VdbeMultiLoad(v, regResult+2, "siX", pFK->zTo, i-1);
+ sqlite3VdbeMultiLoad(v, regResult+2, "siX", pFK->zTo, i-1);
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
sqlite3VdbeResolveLabel(v, addrOk);
sqlite3DbFree(db, aiCols);
@@ -131124,17 +131124,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
#endif
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
- /* PRAGMA integrity_check
- ** PRAGMA integrity_check(N)
- ** PRAGMA quick_check
- ** PRAGMA quick_check(N)
- **
- ** Verify the integrity of the database.
- **
+ /* PRAGMA integrity_check
+ ** PRAGMA integrity_check(N)
+ ** PRAGMA quick_check
+ ** PRAGMA quick_check(N)
+ **
+ ** Verify the integrity of the database.
+ **
** The "quick_check" is reduced version of
** integrity_check designed to detect most database corruption
- ** without the overhead of cross-checking indexes. Quick_check
- ** is linear time wherease integrity_check is O(NlogN).
+ ** without the overhead of cross-checking indexes. Quick_check
+ ** is linear time wherease integrity_check is O(NlogN).
**
** The maximum nubmer of errors is 100 by default. A different default
** can be specified using a numeric parameter N.
@@ -131182,15 +131182,15 @@ SQLITE_PRIVATE void sqlite3Pragma(
iDb>=0 ? db->aDb[iDb].zDbSName : 0);
}
}
- sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */
+ sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */
/* Do an integrity check on each database file */
for(i=0; i<db->nDb; i++){
- HashElem *x; /* For looping over tables in the schema */
- Hash *pTbls; /* Set of all tables in the schema */
- int *aRoot; /* Array of root page numbers of all btrees */
- int cnt = 0; /* Number of entries in aRoot[] */
- int mxIdx = 0; /* Maximum number of indexes for any table */
+ HashElem *x; /* For looping over tables in the schema */
+ Hash *pTbls; /* Set of all tables in the schema */
+ int *aRoot; /* Array of root page numbers of all btrees */
+ int cnt = 0; /* Number of entries in aRoot[] */
+ int mxIdx = 0; /* Maximum number of indexes for any table */
if( OMIT_TEMPDB && i==1 ) continue;
if( iDb>=0 && i!=iDb ) continue;
@@ -131199,55 +131199,55 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Do an integrity check of the B-Tree
**
- ** Begin by finding the root pages numbers
+ ** Begin by finding the root pages numbers
** for all tables and indices in the database.
*/
assert( sqlite3SchemaMutexHeld(db, i, 0) );
pTbls = &db->aDb[i].pSchema->tblHash;
- for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
- Table *pTab = sqliteHashData(x); /* Current table */
- Index *pIdx; /* An index on pTab */
- int nIdx; /* Number of indexes on pTab */
+ for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+ Table *pTab = sqliteHashData(x); /* Current table */
+ Index *pIdx; /* An index on pTab */
+ int nIdx; /* Number of indexes on pTab */
if( pObjTab && pObjTab!=pTab ) continue;
- if( HasRowid(pTab) ) cnt++;
- for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
- if( nIdx>mxIdx ) mxIdx = nIdx;
- }
+ if( HasRowid(pTab) ) cnt++;
+ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
+ if( nIdx>mxIdx ) mxIdx = nIdx;
+ }
if( cnt==0 ) continue;
if( pObjTab ) cnt++;
- aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1));
- if( aRoot==0 ) break;
+ aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1));
+ if( aRoot==0 ) break;
cnt = 0;
if( pObjTab ) aRoot[++cnt] = 0;
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
Index *pIdx;
if( pObjTab && pObjTab!=pTab ) continue;
- if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum;
+ if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- aRoot[++cnt] = pIdx->tnum;
+ aRoot[++cnt] = pIdx->tnum;
}
}
- aRoot[0] = cnt;
+ aRoot[0] = cnt;
/* Make sure sufficient number of registers have been allocated */
- pParse->nMem = MAX( pParse->nMem, 8+mxIdx );
- sqlite3ClearTempRegCache(pParse);
+ pParse->nMem = MAX( pParse->nMem, 8+mxIdx );
+ sqlite3ClearTempRegCache(pParse);
/* Do the b-tree integrity checks */
- sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY);
+ sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY);
sqlite3VdbeChangeP5(v, (u8)i);
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
- sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName),
+ sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName),
P4_DYNAMIC);
- sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3);
- integrityCheckResultRow(v);
+ sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3);
+ integrityCheckResultRow(v);
sqlite3VdbeJumpHere(v, addr);
/* Make sure all the indices are constructed correctly.
*/
- for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+ for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
Index *pIdx, *pPk;
Index *pPrior = 0;
@@ -131259,17 +131259,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( !IsOrdinaryTable(pTab) ) continue;
if( pObjTab && pObjTab!=pTab ) continue;
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
- sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
1, 0, &iDataCur, &iIdxCur);
- /* reg[7] counts the number of entries in the table.
+ /* reg[7] counts the number of entries in the table.
** reg[8+i] counts the number of entries in the i-th index
- */
+ */
sqlite3VdbeAddOp2(v, OP_Integer, 0, 7);
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
}
- assert( pParse->nMem>=8+j );
- assert( sqlite3NoTempsInRange(pParse,1,7+j) );
+ assert( pParse->nMem>=8+j );
+ assert( sqlite3NoTempsInRange(pParse,1,7+j) );
sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
if( !isQuick ){
@@ -131319,118 +131319,118 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeJumpHere(v, jmp2);
}
}
- /* Verify CHECK constraints */
- if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
- ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
- if( db->mallocFailed==0 ){
+ /* Verify CHECK constraints */
+ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
+ ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
+ if( db->mallocFailed==0 ){
int addrCkFault = sqlite3VdbeMakeLabel(pParse);
int addrCkOk = sqlite3VdbeMakeLabel(pParse);
- char *zErr;
- int k;
- pParse->iSelfTab = iDataCur + 1;
- for(k=pCheck->nExpr-1; k>0; k--){
- sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
+ char *zErr;
+ int k;
+ pParse->iSelfTab = iDataCur + 1;
+ for(k=pCheck->nExpr-1; k>0; k--){
+ sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
}
sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
- SQLITE_JUMPIFNULL);
- sqlite3VdbeResolveLabel(v, addrCkFault);
- pParse->iSelfTab = 0;
- zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
- pTab->zName);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
- integrityCheckResultRow(v);
- sqlite3VdbeResolveLabel(v, addrCkOk);
+ SQLITE_JUMPIFNULL);
+ sqlite3VdbeResolveLabel(v, addrCkFault);
+ pParse->iSelfTab = 0;
+ zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
+ pTab->zName);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
+ integrityCheckResultRow(v);
+ sqlite3VdbeResolveLabel(v, addrCkOk);
}
- sqlite3ExprListDelete(db, pCheck);
+ sqlite3ExprListDelete(db, pCheck);
}
- if( !isQuick ){ /* Omit the remaining tests for quick_check */
- /* Validate index entries for the current row */
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- int jmp2, jmp3, jmp4, jmp5;
+ if( !isQuick ){ /* Omit the remaining tests for quick_check */
+ /* Validate index entries for the current row */
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ int jmp2, jmp3, jmp4, jmp5;
int ckUniq = sqlite3VdbeMakeLabel(pParse);
- if( pPk==pIdx ) continue;
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
- pPrior, r1);
- pPrior = pIdx;
- sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */
- /* Verify that an index entry exists for the current table row */
- jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
- pIdx->nColumn); VdbeCoverage(v);
- sqlite3VdbeLoadString(v, 3, "row ");
- sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
- sqlite3VdbeLoadString(v, 4, " missing from index ");
- sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
- jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
- sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
- jmp4 = integrityCheckResultRow(v);
- sqlite3VdbeJumpHere(v, jmp2);
- /* For UNIQUE indexes, verify that only one entry exists with the
- ** current key. The entry is unique if (1) any column is NULL
- ** or (2) the next entry has a different key */
- if( IsUniqueIndex(pIdx) ){
+ if( pPk==pIdx ) continue;
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
+ pPrior, r1);
+ pPrior = pIdx;
+ sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */
+ /* Verify that an index entry exists for the current table row */
+ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
+ pIdx->nColumn); VdbeCoverage(v);
+ sqlite3VdbeLoadString(v, 3, "row ");
+ sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
+ sqlite3VdbeLoadString(v, 4, " missing from index ");
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+ jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+ jmp4 = integrityCheckResultRow(v);
+ sqlite3VdbeJumpHere(v, jmp2);
+ /* For UNIQUE indexes, verify that only one entry exists with the
+ ** current key. The entry is unique if (1) any column is NULL
+ ** or (2) the next entry has a different key */
+ if( IsUniqueIndex(pIdx) ){
int uniqOk = sqlite3VdbeMakeLabel(pParse);
- int jmp6;
- int kk;
- for(kk=0; kk<pIdx->nKeyCol; kk++){
- int iCol = pIdx->aiColumn[kk];
- assert( iCol!=XN_ROWID && iCol<pTab->nCol );
- if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
- sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
- VdbeCoverage(v);
- }
- jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
- sqlite3VdbeGoto(v, uniqOk);
- sqlite3VdbeJumpHere(v, jmp6);
- sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
- pIdx->nKeyCol); VdbeCoverage(v);
- sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
- sqlite3VdbeGoto(v, jmp5);
- sqlite3VdbeResolveLabel(v, uniqOk);
- }
- sqlite3VdbeJumpHere(v, jmp4);
- sqlite3ResolvePartIdxLabel(pParse, jmp3);
- }
- }
+ int jmp6;
+ int kk;
+ for(kk=0; kk<pIdx->nKeyCol; kk++){
+ int iCol = pIdx->aiColumn[kk];
+ assert( iCol!=XN_ROWID && iCol<pTab->nCol );
+ if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
+ sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
+ VdbeCoverage(v);
+ }
+ jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, uniqOk);
+ sqlite3VdbeJumpHere(v, jmp6);
+ sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
+ pIdx->nKeyCol); VdbeCoverage(v);
+ sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
+ sqlite3VdbeGoto(v, jmp5);
+ sqlite3VdbeResolveLabel(v, uniqOk);
+ }
+ sqlite3VdbeJumpHere(v, jmp4);
+ sqlite3ResolvePartIdxLabel(pParse, jmp3);
+ }
+ }
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
- if( !isQuick ){
- sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- if( pPk==pIdx ) continue;
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
- addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
- sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
- sqlite3VdbeLoadString(v, 4, pIdx->zName);
- sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
- integrityCheckResultRow(v);
- sqlite3VdbeJumpHere(v, addr);
- }
- }
- }
- }
- {
- static const int iLn = VDBE_OFFSET_LINENO(2);
- static const VdbeOpList endCode[] = {
- { OP_AddImm, 1, 0, 0}, /* 0 */
- { OP_IfNotZero, 1, 4, 0}, /* 1 */
- { OP_String8, 0, 3, 0}, /* 2 */
- { OP_ResultRow, 3, 1, 0}, /* 3 */
- { OP_Halt, 0, 0, 0}, /* 4 */
- { OP_String8, 0, 3, 0}, /* 5 */
- { OP_Goto, 0, 3, 0}, /* 6 */
- };
- VdbeOp *aOp;
-
- aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
- if( aOp ){
- aOp[0].p2 = 1-mxErr;
- aOp[2].p4type = P4_STATIC;
- aOp[2].p4.z = "ok";
- aOp[5].p4type = P4_STATIC;
- aOp[5].p4.z = (char*)sqlite3ErrStr(SQLITE_CORRUPT);
- }
- sqlite3VdbeChangeP3(v, 0, sqlite3VdbeCurrentAddr(v)-2);
- }
+ if( !isQuick ){
+ sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ if( pPk==pIdx ) continue;
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
+ addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ sqlite3VdbeLoadString(v, 4, pIdx->zName);
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
+ integrityCheckResultRow(v);
+ sqlite3VdbeJumpHere(v, addr);
+ }
+ }
+ }
+ }
+ {
+ static const int iLn = VDBE_OFFSET_LINENO(2);
+ static const VdbeOpList endCode[] = {
+ { OP_AddImm, 1, 0, 0}, /* 0 */
+ { OP_IfNotZero, 1, 4, 0}, /* 1 */
+ { OP_String8, 0, 3, 0}, /* 2 */
+ { OP_ResultRow, 3, 1, 0}, /* 3 */
+ { OP_Halt, 0, 0, 0}, /* 4 */
+ { OP_String8, 0, 3, 0}, /* 5 */
+ { OP_Goto, 0, 3, 0}, /* 6 */
+ };
+ VdbeOp *aOp;
+
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
+ if( aOp ){
+ aOp[0].p2 = 1-mxErr;
+ aOp[2].p4type = P4_STATIC;
+ aOp[2].p4.z = "ok";
+ aOp[5].p4type = P4_STATIC;
+ aOp[5].p4.z = (char*)sqlite3ErrStr(SQLITE_CORRUPT);
+ }
+ sqlite3VdbeChangeP3(v, 0, sqlite3VdbeCurrentAddr(v)-2);
+ }
}
break;
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -131479,7 +131479,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 );
assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE );
assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE );
- returnSingleText(v, encnames[ENC(pParse->db)].zName);
+ returnSingleText(v, encnames[ENC(pParse->db)].zName);
}else{ /* "PRAGMA encoding = XXX" */
/* Only change the value of sqlite.enc if the database handle is not
** initialized. If the main database exists, the new sqlite.enc value
@@ -131506,19 +131506,19 @@ SQLITE_PRIVATE void sqlite3Pragma(
#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
/*
- ** PRAGMA [schema.]schema_version
- ** PRAGMA [schema.]schema_version = <integer>
+ ** PRAGMA [schema.]schema_version
+ ** PRAGMA [schema.]schema_version = <integer>
**
- ** PRAGMA [schema.]user_version
- ** PRAGMA [schema.]user_version = <integer>
+ ** PRAGMA [schema.]user_version
+ ** PRAGMA [schema.]user_version = <integer>
**
- ** PRAGMA [schema.]freelist_count
+ ** PRAGMA [schema.]freelist_count
**
- ** PRAGMA [schema.]data_version
+ ** PRAGMA [schema.]data_version
+ **
+ ** PRAGMA [schema.]application_id
+ ** PRAGMA [schema.]application_id = <integer>
**
- ** PRAGMA [schema.]application_id
- ** PRAGMA [schema.]application_id = <integer>
- **
** The pragma's schema_version and user_version are used to set or get
** the value of the schema-version and user-version, respectively. Both
** the schema-version and the user-version are 32-bit signed integers
@@ -131540,20 +131540,20 @@ SQLITE_PRIVATE void sqlite3Pragma(
case PragTyp_HEADER_VALUE: {
int iCookie = pPragma->iArg; /* Which cookie to read or write */
sqlite3VdbeUsesBtree(v, iDb);
- if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){
+ if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){
/* Write the specified cookie value */
static const VdbeOpList setCookie[] = {
{ OP_Transaction, 0, 1, 0}, /* 0 */
- { OP_SetCookie, 0, 0, 0}, /* 1 */
+ { OP_SetCookie, 0, 0, 0}, /* 1 */
};
- VdbeOp *aOp;
- sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie));
- aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0);
- if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
- aOp[0].p1 = iDb;
- aOp[1].p1 = iDb;
- aOp[1].p2 = iCookie;
- aOp[1].p3 = sqlite3Atoi(zRight);
+ VdbeOp *aOp;
+ sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie));
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0);
+ if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
+ aOp[0].p1 = iDb;
+ aOp[1].p1 = iDb;
+ aOp[1].p2 = iCookie;
+ aOp[1].p3 = sqlite3Atoi(zRight);
aOp[1].p5 = 1;
}else{
/* Read the specified cookie value */
@@ -131562,14 +131562,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
{ OP_ReadCookie, 0, 1, 0}, /* 1 */
{ OP_ResultRow, 1, 1, 0}
};
- VdbeOp *aOp;
- sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(readCookie));
- aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0);
- if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
- aOp[0].p1 = iDb;
- aOp[1].p1 = iDb;
- aOp[1].p3 = iCookie;
- sqlite3VdbeReusable(v);
+ VdbeOp *aOp;
+ sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(readCookie));
+ aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0);
+ if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
+ aOp[0].p1 = iDb;
+ aOp[1].p1 = iDb;
+ aOp[1].p3 = iCookie;
+ sqlite3VdbeReusable(v);
}
}
break;
@@ -131587,17 +131587,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
const char *zOpt;
pParse->nMem = 1;
while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){
- sqlite3VdbeLoadString(v, 1, zOpt);
+ sqlite3VdbeLoadString(v, 1, zOpt);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
- sqlite3VdbeReusable(v);
+ sqlite3VdbeReusable(v);
}
break;
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
#ifndef SQLITE_OMIT_WAL
/*
- ** PRAGMA [schema.]wal_checkpoint = passive|full|restart|truncate
+ ** PRAGMA [schema.]wal_checkpoint = passive|full|restart|truncate
**
** Checkpoint the database.
*/
@@ -131651,119 +131651,119 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
/*
- ** PRAGMA optimize
- ** PRAGMA optimize(MASK)
- ** PRAGMA schema.optimize
- ** PRAGMA schema.optimize(MASK)
- **
- ** Attempt to optimize the database. All schemas are optimized in the first
- ** two forms, and only the specified schema is optimized in the latter two.
- **
- ** The details of optimizations performed by this pragma are expected
- ** to change and improve over time. Applications should anticipate that
- ** this pragma will perform new optimizations in future releases.
- **
- ** The optional argument is a bitmask of optimizations to perform:
- **
- ** 0x0001 Debugging mode. Do not actually perform any optimizations
- ** but instead return one line of text for each optimization
- ** that would have been done. Off by default.
- **
- ** 0x0002 Run ANALYZE on tables that might benefit. On by default.
- ** See below for additional information.
- **
+ ** PRAGMA optimize
+ ** PRAGMA optimize(MASK)
+ ** PRAGMA schema.optimize
+ ** PRAGMA schema.optimize(MASK)
+ **
+ ** Attempt to optimize the database. All schemas are optimized in the first
+ ** two forms, and only the specified schema is optimized in the latter two.
+ **
+ ** The details of optimizations performed by this pragma are expected
+ ** to change and improve over time. Applications should anticipate that
+ ** this pragma will perform new optimizations in future releases.
+ **
+ ** The optional argument is a bitmask of optimizations to perform:
+ **
+ ** 0x0001 Debugging mode. Do not actually perform any optimizations
+ ** but instead return one line of text for each optimization
+ ** that would have been done. Off by default.
+ **
+ ** 0x0002 Run ANALYZE on tables that might benefit. On by default.
+ ** See below for additional information.
+ **
** 0x0004 (Not yet implemented) Record usage and performance
- ** information from the current session in the
- ** database file so that it will be available to "optimize"
- ** pragmas run by future database connections.
- **
- ** 0x0008 (Not yet implemented) Create indexes that might have
- ** been helpful to recent queries
- **
- ** The default MASK is and always shall be 0xfffe. 0xfffe means perform all
- ** of the optimizations listed above except Debug Mode, including new
- ** optimizations that have not yet been invented. If new optimizations are
+ ** information from the current session in the
+ ** database file so that it will be available to "optimize"
+ ** pragmas run by future database connections.
+ **
+ ** 0x0008 (Not yet implemented) Create indexes that might have
+ ** been helpful to recent queries
+ **
+ ** The default MASK is and always shall be 0xfffe. 0xfffe means perform all
+ ** of the optimizations listed above except Debug Mode, including new
+ ** optimizations that have not yet been invented. If new optimizations are
** ever added that should be off by default, those off-by-default
- ** optimizations will have bitmasks of 0x10000 or larger.
- **
- ** DETERMINATION OF WHEN TO RUN ANALYZE
- **
- ** In the current implementation, a table is analyzed if only if all of
- ** the following are true:
- **
- ** (1) MASK bit 0x02 is set.
- **
- ** (2) The query planner used sqlite_stat1-style statistics for one or
- ** more indexes of the table at some point during the lifetime of
- ** the current connection.
- **
- ** (3) One or more indexes of the table are currently unanalyzed OR
- ** the number of rows in the table has increased by 25 times or more
- ** since the last time ANALYZE was run.
- **
- ** The rules for when tables are analyzed are likely to change in
- ** future releases.
- */
- case PragTyp_OPTIMIZE: {
- int iDbLast; /* Loop termination point for the schema loop */
- int iTabCur; /* Cursor for a table whose size needs checking */
- HashElem *k; /* Loop over tables of a schema */
- Schema *pSchema; /* The current schema */
- Table *pTab; /* A table in the schema */
- Index *pIdx; /* An index of the table */
- LogEst szThreshold; /* Size threshold above which reanalysis is needd */
- char *zSubSql; /* SQL statement for the OP_SqlExec opcode */
- u32 opMask; /* Mask of operations to perform */
-
- if( zRight ){
- opMask = (u32)sqlite3Atoi(zRight);
- if( (opMask & 0x02)==0 ) break;
- }else{
- opMask = 0xfffe;
- }
- iTabCur = pParse->nTab++;
- for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){
- if( iDb==1 ) continue;
- sqlite3CodeVerifySchema(pParse, iDb);
- pSchema = db->aDb[iDb].pSchema;
- for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
- pTab = (Table*)sqliteHashData(k);
-
- /* If table pTab has not been used in a way that would benefit from
- ** having analysis statistics during the current session, then skip it.
- ** This also has the effect of skipping virtual tables and views */
- if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue;
-
- /* Reanalyze if the table is 25 times larger than the last analysis */
- szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 );
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( !pIdx->hasStat1 ){
- szThreshold = 0; /* Always analyze if any index lacks statistics */
- break;
- }
- }
- if( szThreshold ){
- sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
+ ** optimizations will have bitmasks of 0x10000 or larger.
+ **
+ ** DETERMINATION OF WHEN TO RUN ANALYZE
+ **
+ ** In the current implementation, a table is analyzed if only if all of
+ ** the following are true:
+ **
+ ** (1) MASK bit 0x02 is set.
+ **
+ ** (2) The query planner used sqlite_stat1-style statistics for one or
+ ** more indexes of the table at some point during the lifetime of
+ ** the current connection.
+ **
+ ** (3) One or more indexes of the table are currently unanalyzed OR
+ ** the number of rows in the table has increased by 25 times or more
+ ** since the last time ANALYZE was run.
+ **
+ ** The rules for when tables are analyzed are likely to change in
+ ** future releases.
+ */
+ case PragTyp_OPTIMIZE: {
+ int iDbLast; /* Loop termination point for the schema loop */
+ int iTabCur; /* Cursor for a table whose size needs checking */
+ HashElem *k; /* Loop over tables of a schema */
+ Schema *pSchema; /* The current schema */
+ Table *pTab; /* A table in the schema */
+ Index *pIdx; /* An index of the table */
+ LogEst szThreshold; /* Size threshold above which reanalysis is needd */
+ char *zSubSql; /* SQL statement for the OP_SqlExec opcode */
+ u32 opMask; /* Mask of operations to perform */
+
+ if( zRight ){
+ opMask = (u32)sqlite3Atoi(zRight);
+ if( (opMask & 0x02)==0 ) break;
+ }else{
+ opMask = 0xfffe;
+ }
+ iTabCur = pParse->nTab++;
+ for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){
+ if( iDb==1 ) continue;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ pSchema = db->aDb[iDb].pSchema;
+ for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
+ pTab = (Table*)sqliteHashData(k);
+
+ /* If table pTab has not been used in a way that would benefit from
+ ** having analysis statistics during the current session, then skip it.
+ ** This also has the effect of skipping virtual tables and views */
+ if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue;
+
+ /* Reanalyze if the table is 25 times larger than the last analysis */
+ szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 );
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( !pIdx->hasStat1 ){
+ szThreshold = 0; /* Always analyze if any index lacks statistics */
+ break;
+ }
+ }
+ if( szThreshold ){
+ sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur,
- sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold);
- VdbeCoverage(v);
- }
- zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"",
- db->aDb[iDb].zDbSName, pTab->zName);
- if( opMask & 0x01 ){
- int r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1);
- }else{
- sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC);
- }
- }
- }
- sqlite3VdbeAddOp0(v, OP_Expire);
- break;
- }
-
- /*
+ sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold);
+ VdbeCoverage(v);
+ }
+ zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"",
+ db->aDb[iDb].zDbSName, pTab->zName);
+ if( opMask & 0x01 ){
+ int r1 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1);
+ }else{
+ sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC);
+ }
+ }
+ }
+ sqlite3VdbeAddOp0(v, OP_Expire);
+ break;
+ }
+
+ /*
** PRAGMA busy_timeout
** PRAGMA busy_timeout = N
**
@@ -131777,7 +131777,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( zRight ){
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
}
- returnSingleInt(v, db->busyTimeout);
+ returnSingleInt(v, db->busyTimeout);
break;
}
@@ -131797,7 +131797,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
sqlite3_soft_heap_limit64(N);
}
- returnSingleInt(v, sqlite3_soft_heap_limit64(-1));
+ returnSingleInt(v, sqlite3_soft_heap_limit64(-1));
break;
}
@@ -131837,7 +131837,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
){
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
}
- returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
+ returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
break;
}
@@ -131874,7 +131874,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
Btree *pBt;
const char *zState = "unknown";
int j;
- if( db->aDb[i].zDbSName==0 ) continue;
+ if( db->aDb[i].zDbSName==0 ) continue;
pBt = db->aDb[i].pBt;
if( pBt==0 || sqlite3BtreePager(pBt)==0 ){
zState = "closed";
@@ -131882,7 +131882,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
zState = azLockName[j];
}
- sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState);
+ sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState);
}
break;
}
@@ -131899,330 +131899,330 @@ SQLITE_PRIVATE void sqlite3Pragma(
} /* End of the PRAGMA switch */
- /* The following block is a no-op unless SQLITE_DEBUG is defined. Its only
- ** purpose is to execute assert() statements to verify that if the
- ** PragFlg_NoColumns1 flag is set and the caller specified an argument
+ /* The following block is a no-op unless SQLITE_DEBUG is defined. Its only
+ ** purpose is to execute assert() statements to verify that if the
+ ** PragFlg_NoColumns1 flag is set and the caller specified an argument
** to the PRAGMA, the implementation has not added any OP_ResultRow
- ** instructions to the VM. */
- if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){
- sqlite3VdbeVerifyNoResultRow(v);
- }
-
+ ** instructions to the VM. */
+ if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){
+ sqlite3VdbeVerifyNoResultRow(v);
+ }
+
pragma_out:
sqlite3DbFree(db, zLeft);
sqlite3DbFree(db, zRight);
}
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/*****************************************************************************
-** Implementation of an eponymous virtual table that runs a pragma.
-**
-*/
-typedef struct PragmaVtab PragmaVtab;
-typedef struct PragmaVtabCursor PragmaVtabCursor;
-struct PragmaVtab {
- sqlite3_vtab base; /* Base class. Must be first */
- sqlite3 *db; /* The database connection to which it belongs */
- const PragmaName *pName; /* Name of the pragma */
- u8 nHidden; /* Number of hidden columns */
- u8 iHidden; /* Index of the first hidden column */
-};
-struct PragmaVtabCursor {
- sqlite3_vtab_cursor base; /* Base class. Must be first */
- sqlite3_stmt *pPragma; /* The pragma statement to run */
- sqlite_int64 iRowid; /* Current rowid */
- char *azArg[2]; /* Value of the argument and schema */
-};
-
-/*
-** Pragma virtual table module xConnect method.
-*/
-static int pragmaVtabConnect(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- const PragmaName *pPragma = (const PragmaName*)pAux;
- PragmaVtab *pTab = 0;
- int rc;
- int i, j;
- char cSep = '(';
- StrAccum acc;
- char zBuf[200];
-
- UNUSED_PARAMETER(argc);
- UNUSED_PARAMETER(argv);
- sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*****************************************************************************
+** Implementation of an eponymous virtual table that runs a pragma.
+**
+*/
+typedef struct PragmaVtab PragmaVtab;
+typedef struct PragmaVtabCursor PragmaVtabCursor;
+struct PragmaVtab {
+ sqlite3_vtab base; /* Base class. Must be first */
+ sqlite3 *db; /* The database connection to which it belongs */
+ const PragmaName *pName; /* Name of the pragma */
+ u8 nHidden; /* Number of hidden columns */
+ u8 iHidden; /* Index of the first hidden column */
+};
+struct PragmaVtabCursor {
+ sqlite3_vtab_cursor base; /* Base class. Must be first */
+ sqlite3_stmt *pPragma; /* The pragma statement to run */
+ sqlite_int64 iRowid; /* Current rowid */
+ char *azArg[2]; /* Value of the argument and schema */
+};
+
+/*
+** Pragma virtual table module xConnect method.
+*/
+static int pragmaVtabConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ const PragmaName *pPragma = (const PragmaName*)pAux;
+ PragmaVtab *pTab = 0;
+ int rc;
+ int i, j;
+ char cSep = '(';
+ StrAccum acc;
+ char zBuf[200];
+
+ UNUSED_PARAMETER(argc);
+ UNUSED_PARAMETER(argv);
+ sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
sqlite3_str_appendall(&acc, "CREATE TABLE x");
- for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
+ for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]);
- cSep = ',';
- }
- if( i==0 ){
+ cSep = ',';
+ }
+ if( i==0 ){
sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName);
- i++;
- }
- j = 0;
- if( pPragma->mPragFlg & PragFlg_Result1 ){
+ i++;
+ }
+ j = 0;
+ if( pPragma->mPragFlg & PragFlg_Result1 ){
sqlite3_str_appendall(&acc, ",arg HIDDEN");
- j++;
- }
- if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
+ j++;
+ }
+ if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
sqlite3_str_appendall(&acc, ",schema HIDDEN");
- j++;
- }
+ j++;
+ }
sqlite3_str_append(&acc, ")", 1);
- sqlite3StrAccumFinish(&acc);
- assert( strlen(zBuf) < sizeof(zBuf)-1 );
- rc = sqlite3_declare_vtab(db, zBuf);
- if( rc==SQLITE_OK ){
- pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab));
- if( pTab==0 ){
- rc = SQLITE_NOMEM;
- }else{
- memset(pTab, 0, sizeof(PragmaVtab));
- pTab->pName = pPragma;
- pTab->db = db;
- pTab->iHidden = i;
- pTab->nHidden = j;
- }
- }else{
- *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
- }
-
- *ppVtab = (sqlite3_vtab*)pTab;
- return rc;
-}
-
-/*
-** Pragma virtual table module xDisconnect method.
-*/
-static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){
- PragmaVtab *pTab = (PragmaVtab*)pVtab;
- sqlite3_free(pTab);
- return SQLITE_OK;
-}
-
-/* Figure out the best index to use to search a pragma virtual table.
-**
-** There are not really any index choices. But we want to encourage the
-** query planner to give == constraints on as many hidden parameters as
-** possible, and especially on the first hidden parameter. So return a
-** high cost if hidden parameters are unconstrained.
-*/
-static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
- PragmaVtab *pTab = (PragmaVtab*)tab;
- const struct sqlite3_index_constraint *pConstraint;
- int i, j;
- int seen[2];
-
- pIdxInfo->estimatedCost = (double)1;
- if( pTab->nHidden==0 ){ return SQLITE_OK; }
- pConstraint = pIdxInfo->aConstraint;
- seen[0] = 0;
- seen[1] = 0;
- for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
- if( pConstraint->usable==0 ) continue;
- if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
- if( pConstraint->iColumn < pTab->iHidden ) continue;
- j = pConstraint->iColumn - pTab->iHidden;
- assert( j < 2 );
- seen[j] = i+1;
- }
- if( seen[0]==0 ){
- pIdxInfo->estimatedCost = (double)2147483647;
- pIdxInfo->estimatedRows = 2147483647;
- return SQLITE_OK;
- }
- j = seen[0]-1;
- pIdxInfo->aConstraintUsage[j].argvIndex = 1;
- pIdxInfo->aConstraintUsage[j].omit = 1;
- if( seen[1]==0 ) return SQLITE_OK;
- pIdxInfo->estimatedCost = (double)20;
- pIdxInfo->estimatedRows = 20;
- j = seen[1]-1;
- pIdxInfo->aConstraintUsage[j].argvIndex = 2;
- pIdxInfo->aConstraintUsage[j].omit = 1;
- return SQLITE_OK;
-}
-
-/* Create a new cursor for the pragma virtual table */
-static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){
- PragmaVtabCursor *pCsr;
- pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr));
- if( pCsr==0 ) return SQLITE_NOMEM;
- memset(pCsr, 0, sizeof(PragmaVtabCursor));
- pCsr->base.pVtab = pVtab;
- *ppCursor = &pCsr->base;
- return SQLITE_OK;
-}
-
-/* Clear all content from pragma virtual table cursor. */
-static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){
- int i;
- sqlite3_finalize(pCsr->pPragma);
- pCsr->pPragma = 0;
- for(i=0; i<ArraySize(pCsr->azArg); i++){
- sqlite3_free(pCsr->azArg[i]);
- pCsr->azArg[i] = 0;
- }
-}
-
-/* Close a pragma virtual table cursor */
-static int pragmaVtabClose(sqlite3_vtab_cursor *cur){
- PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur;
- pragmaVtabCursorClear(pCsr);
- sqlite3_free(pCsr);
- return SQLITE_OK;
-}
-
-/* Advance the pragma virtual table cursor to the next row */
-static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){
- PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
- int rc = SQLITE_OK;
-
- /* Increment the xRowid value */
- pCsr->iRowid++;
- assert( pCsr->pPragma );
- if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){
- rc = sqlite3_finalize(pCsr->pPragma);
- pCsr->pPragma = 0;
- pragmaVtabCursorClear(pCsr);
- }
- return rc;
-}
-
-/*
-** Pragma virtual table module xFilter method.
-*/
-static int pragmaVtabFilter(
+ sqlite3StrAccumFinish(&acc);
+ assert( strlen(zBuf) < sizeof(zBuf)-1 );
+ rc = sqlite3_declare_vtab(db, zBuf);
+ if( rc==SQLITE_OK ){
+ pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab));
+ if( pTab==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(pTab, 0, sizeof(PragmaVtab));
+ pTab->pName = pPragma;
+ pTab->db = db;
+ pTab->iHidden = i;
+ pTab->nHidden = j;
+ }
+ }else{
+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ }
+
+ *ppVtab = (sqlite3_vtab*)pTab;
+ return rc;
+}
+
+/*
+** Pragma virtual table module xDisconnect method.
+*/
+static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){
+ PragmaVtab *pTab = (PragmaVtab*)pVtab;
+ sqlite3_free(pTab);
+ return SQLITE_OK;
+}
+
+/* Figure out the best index to use to search a pragma virtual table.
+**
+** There are not really any index choices. But we want to encourage the
+** query planner to give == constraints on as many hidden parameters as
+** possible, and especially on the first hidden parameter. So return a
+** high cost if hidden parameters are unconstrained.
+*/
+static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+ PragmaVtab *pTab = (PragmaVtab*)tab;
+ const struct sqlite3_index_constraint *pConstraint;
+ int i, j;
+ int seen[2];
+
+ pIdxInfo->estimatedCost = (double)1;
+ if( pTab->nHidden==0 ){ return SQLITE_OK; }
+ pConstraint = pIdxInfo->aConstraint;
+ seen[0] = 0;
+ seen[1] = 0;
+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+ if( pConstraint->usable==0 ) continue;
+ if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ if( pConstraint->iColumn < pTab->iHidden ) continue;
+ j = pConstraint->iColumn - pTab->iHidden;
+ assert( j < 2 );
+ seen[j] = i+1;
+ }
+ if( seen[0]==0 ){
+ pIdxInfo->estimatedCost = (double)2147483647;
+ pIdxInfo->estimatedRows = 2147483647;
+ return SQLITE_OK;
+ }
+ j = seen[0]-1;
+ pIdxInfo->aConstraintUsage[j].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[j].omit = 1;
+ if( seen[1]==0 ) return SQLITE_OK;
+ pIdxInfo->estimatedCost = (double)20;
+ pIdxInfo->estimatedRows = 20;
+ j = seen[1]-1;
+ pIdxInfo->aConstraintUsage[j].argvIndex = 2;
+ pIdxInfo->aConstraintUsage[j].omit = 1;
+ return SQLITE_OK;
+}
+
+/* Create a new cursor for the pragma virtual table */
+static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){
+ PragmaVtabCursor *pCsr;
+ pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr));
+ if( pCsr==0 ) return SQLITE_NOMEM;
+ memset(pCsr, 0, sizeof(PragmaVtabCursor));
+ pCsr->base.pVtab = pVtab;
+ *ppCursor = &pCsr->base;
+ return SQLITE_OK;
+}
+
+/* Clear all content from pragma virtual table cursor. */
+static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){
+ int i;
+ sqlite3_finalize(pCsr->pPragma);
+ pCsr->pPragma = 0;
+ for(i=0; i<ArraySize(pCsr->azArg); i++){
+ sqlite3_free(pCsr->azArg[i]);
+ pCsr->azArg[i] = 0;
+ }
+}
+
+/* Close a pragma virtual table cursor */
+static int pragmaVtabClose(sqlite3_vtab_cursor *cur){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur;
+ pragmaVtabCursorClear(pCsr);
+ sqlite3_free(pCsr);
+ return SQLITE_OK;
+}
+
+/* Advance the pragma virtual table cursor to the next row */
+static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ int rc = SQLITE_OK;
+
+ /* Increment the xRowid value */
+ pCsr->iRowid++;
+ assert( pCsr->pPragma );
+ if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){
+ rc = sqlite3_finalize(pCsr->pPragma);
+ pCsr->pPragma = 0;
+ pragmaVtabCursorClear(pCsr);
+ }
+ return rc;
+}
+
+/*
+** Pragma virtual table module xFilter method.
+*/
+static int pragmaVtabFilter(
sqlite3_vtab_cursor *pVtabCursor,
- int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv
-){
- PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
- PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
- int rc;
- int i, j;
- StrAccum acc;
- char *zSql;
-
- UNUSED_PARAMETER(idxNum);
- UNUSED_PARAMETER(idxStr);
- pragmaVtabCursorClear(pCsr);
- j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1;
- for(i=0; i<argc; i++, j++){
- const char *zText = (const char*)sqlite3_value_text(argv[i]);
- assert( j<ArraySize(pCsr->azArg) );
- assert( pCsr->azArg[j]==0 );
- if( zText ){
- pCsr->azArg[j] = sqlite3_mprintf("%s", zText);
- if( pCsr->azArg[j]==0 ){
- return SQLITE_NOMEM;
- }
- }
- }
- sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
+ int rc;
+ int i, j;
+ StrAccum acc;
+ char *zSql;
+
+ UNUSED_PARAMETER(idxNum);
+ UNUSED_PARAMETER(idxStr);
+ pragmaVtabCursorClear(pCsr);
+ j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1;
+ for(i=0; i<argc; i++, j++){
+ const char *zText = (const char*)sqlite3_value_text(argv[i]);
+ assert( j<ArraySize(pCsr->azArg) );
+ assert( pCsr->azArg[j]==0 );
+ if( zText ){
+ pCsr->azArg[j] = sqlite3_mprintf("%s", zText);
+ if( pCsr->azArg[j]==0 ){
+ return SQLITE_NOMEM;
+ }
+ }
+ }
+ sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
sqlite3_str_appendall(&acc, "PRAGMA ");
- if( pCsr->azArg[1] ){
+ if( pCsr->azArg[1] ){
sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]);
- }
+ }
sqlite3_str_appendall(&acc, pTab->pName->zName);
- if( pCsr->azArg[0] ){
+ if( pCsr->azArg[0] ){
sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]);
- }
- zSql = sqlite3StrAccumFinish(&acc);
- if( zSql==0 ) return SQLITE_NOMEM;
- rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0);
- sqlite3_free(zSql);
- if( rc!=SQLITE_OK ){
- pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
- return rc;
- }
- return pragmaVtabNext(pVtabCursor);
-}
-
-/*
-** Pragma virtual table module xEof method.
-*/
-static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){
- PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
- return (pCsr->pPragma==0);
-}
-
-/* The xColumn method simply returns the corresponding column from
+ }
+ zSql = sqlite3StrAccumFinish(&acc);
+ if( zSql==0 ) return SQLITE_NOMEM;
+ rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0);
+ sqlite3_free(zSql);
+ if( rc!=SQLITE_OK ){
+ pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
+ return rc;
+ }
+ return pragmaVtabNext(pVtabCursor);
+}
+
+/*
+** Pragma virtual table module xEof method.
+*/
+static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ return (pCsr->pPragma==0);
+}
+
+/* The xColumn method simply returns the corresponding column from
** the PRAGMA.
-*/
-static int pragmaVtabColumn(
+*/
+static int pragmaVtabColumn(
sqlite3_vtab_cursor *pVtabCursor,
sqlite3_context *ctx,
- int i
-){
- PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
- PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
- if( i<pTab->iHidden ){
- sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i));
- }else{
- sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT);
- }
- return SQLITE_OK;
-}
-
-/*
-** Pragma virtual table module xRowid method.
-*/
-static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){
- PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
- *p = pCsr->iRowid;
- return SQLITE_OK;
-}
-
-/* The pragma virtual table object */
-static const sqlite3_module pragmaVtabModule = {
- 0, /* iVersion */
- 0, /* xCreate - create a table */
- pragmaVtabConnect, /* xConnect - connect to an existing table */
- pragmaVtabBestIndex, /* xBestIndex - Determine search strategy */
- pragmaVtabDisconnect, /* xDisconnect - Disconnect from a table */
- 0, /* xDestroy - Drop a table */
- pragmaVtabOpen, /* xOpen - open a cursor */
- pragmaVtabClose, /* xClose - close a cursor */
- pragmaVtabFilter, /* xFilter - configure scan constraints */
- pragmaVtabNext, /* xNext - advance a cursor */
- pragmaVtabEof, /* xEof */
- pragmaVtabColumn, /* xColumn - read data */
- pragmaVtabRowid, /* xRowid - read data */
- 0, /* xUpdate - write data */
- 0, /* xBegin - begin transaction */
- 0, /* xSync - sync transaction */
- 0, /* xCommit - commit transaction */
- 0, /* xRollback - rollback transaction */
- 0, /* xFindFunction - function overloading */
- 0, /* xRename - rename the table */
- 0, /* xSavepoint */
- 0, /* xRelease */
+ int i
+){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
+ if( i<pTab->iHidden ){
+ sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i));
+ }else{
+ sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT);
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Pragma virtual table module xRowid method.
+*/
+static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ *p = pCsr->iRowid;
+ return SQLITE_OK;
+}
+
+/* The pragma virtual table object */
+static const sqlite3_module pragmaVtabModule = {
+ 0, /* iVersion */
+ 0, /* xCreate - create a table */
+ pragmaVtabConnect, /* xConnect - connect to an existing table */
+ pragmaVtabBestIndex, /* xBestIndex - Determine search strategy */
+ pragmaVtabDisconnect, /* xDisconnect - Disconnect from a table */
+ 0, /* xDestroy - Drop a table */
+ pragmaVtabOpen, /* xOpen - open a cursor */
+ pragmaVtabClose, /* xClose - close a cursor */
+ pragmaVtabFilter, /* xFilter - configure scan constraints */
+ pragmaVtabNext, /* xNext - advance a cursor */
+ pragmaVtabEof, /* xEof */
+ pragmaVtabColumn, /* xColumn - read data */
+ pragmaVtabRowid, /* xRowid - read data */
+ 0, /* xUpdate - write data */
+ 0, /* xBegin - begin transaction */
+ 0, /* xSync - sync transaction */
+ 0, /* xCommit - commit transaction */
+ 0, /* xRollback - rollback transaction */
+ 0, /* xFindFunction - function overloading */
+ 0, /* xRename - rename the table */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
0, /* xRollbackTo */
0 /* xShadowName */
-};
-
-/*
-** Check to see if zTabName is really the name of a pragma. If it is,
-** then register an eponymous virtual table for that pragma and return
-** a pointer to the Module object for the new virtual table.
-*/
-SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){
- const PragmaName *pName;
- assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 );
- pName = pragmaLocate(zName+7);
- if( pName==0 ) return 0;
- if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0;
- assert( sqlite3HashFind(&db->aModule, zName)==0 );
- return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0);
-}
-
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
+};
+
+/*
+** Check to see if zTabName is really the name of a pragma. If it is,
+** then register an eponymous virtual table for that pragma and return
+** a pointer to the Module object for the new virtual table.
+*/
+SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){
+ const PragmaName *pName;
+ assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 );
+ pName = pragmaLocate(zName+7);
+ if( pName==0 ) return 0;
+ if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0;
+ assert( sqlite3HashFind(&db->aModule, zName)==0 );
+ return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0);
+}
+
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
#endif /* SQLITE_OMIT_PRAGMA */
/************** End of pragma.c **********************************************/
@@ -132275,7 +132275,7 @@ static void corruptSchema(
}else{
char *z;
const char *zObj = azObj[1] ? azObj[1] : "?";
- z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
+ z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
*pData->pzErrMsg = z;
pData->rc = SQLITE_CORRUPT_BKPT;
@@ -132354,7 +132354,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
** schema.
*/
int rc;
- u8 saved_iDb = db->init.iDb;
+ u8 saved_iDb = db->init.iDb;
sqlite3_stmt *pStmt;
TESTONLY(int rcp); /* Return code from sqlite3_prepare() */
@@ -132373,7 +132373,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0);
rc = db->errCode;
assert( (rc&0xFF)==(rcp&0xFF) );
- db->init.iDb = saved_iDb;
+ db->init.iDb = saved_iDb;
/* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */
if( SQLITE_OK!=rc ){
if( db->init.orphanTrigger ){
@@ -132381,7 +132381,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
}else{
if( rc > pData->rc ) pData->rc = rc;
if( rc==SQLITE_NOMEM ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
}else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
corruptSchema(pData, argv, sqlite3_errmsg(db));
}
@@ -132444,19 +132444,19 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
assert( sqlite3_mutex_held(db->mutex) );
assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
- db->init.busy = 1;
+ db->init.busy = 1;
/* Construct the in-memory representation schema tables (sqlite_schema or
** sqlite_temp_schema) by invoking the parser directly. The appropriate
- ** table name will be inserted automatically by the parser so we can just
- ** use the abbreviation "x" here. The parser will also automatically tag
- ** the schema table as read-only. */
+ ** table name will be inserted automatically by the parser so we can just
+ ** use the abbreviation "x" here. The parser will also automatically tag
+ ** the schema table as read-only. */
azArg[0] = "table";
azArg[1] = zSchemaTabName = SCHEMA_TABLE(iDb);
azArg[2] = azArg[1];
azArg[3] = "1";
azArg[4] = "CREATE TABLE x(type text,name text,tbl_name text,"
- "rootpage int,sql text)";
+ "rootpage int,sql text)";
azArg[5] = 0;
initData.db = db;
initData.iDb = iDb;
@@ -132476,10 +132476,10 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
*/
pDb = &db->aDb[iDb];
if( pDb->pBt==0 ){
- assert( iDb==1 );
- DbSetProperty(db, 1, DB_SchemaLoaded);
- rc = SQLITE_OK;
- goto error_out;
+ assert( iDb==1 );
+ DbSetProperty(db, 1, DB_SchemaLoaded);
+ rc = SQLITE_OK;
+ goto error_out;
}
/* If there is not already a read-only (or read-write) transaction opened
@@ -132614,7 +132614,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
}
assert( pDb == &(db->aDb[iDb]) );
if( db->mallocFailed ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
sqlite3ResetAllSchemasOfConnection(db);
pDb = &db->aDb[iDb];
}else
@@ -132644,13 +132644,13 @@ initone_error_out:
sqlite3BtreeLeave(pDb->pBt);
error_out:
- if( rc ){
- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
- sqlite3OomFault(db);
- }
- sqlite3ResetOneSchema(db, iDb);
+ if( rc ){
+ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+ sqlite3OomFault(db);
+ }
+ sqlite3ResetOneSchema(db, iDb);
}
- db->init.busy = 0;
+ db->init.busy = 0;
return rc;
}
@@ -132665,30 +132665,30 @@ error_out:
*/
SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
int i, rc;
- int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange);
+ int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange);
assert( sqlite3_mutex_held(db->mutex) );
assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
assert( db->init.busy==0 );
ENC(db) = SCHEMA_ENC(db);
- assert( db->nDb>0 );
- /* Do the main schema first */
- if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){
+ assert( db->nDb>0 );
+ /* Do the main schema first */
+ if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){
rc = sqlite3InitOne(db, 0, pzErrMsg, 0);
- if( rc ) return rc;
+ if( rc ) return rc;
}
- /* All other schemas after the main schema. The "temp" schema must be last */
- for(i=db->nDb-1; i>0; i--){
+ /* All other schemas after the main schema. The "temp" schema must be last */
+ for(i=db->nDb-1; i>0; i--){
assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) );
- if( !DbHasProperty(db, i, DB_SchemaLoaded) ){
+ if( !DbHasProperty(db, i, DB_SchemaLoaded) ){
rc = sqlite3InitOne(db, i, pzErrMsg, 0);
- if( rc ) return rc;
+ if( rc ) return rc;
}
}
- if( commit_internal ){
+ if( commit_internal ){
sqlite3CommitInternalChanges(db);
}
- return SQLITE_OK;
+ return SQLITE_OK;
}
/*
@@ -132736,7 +132736,7 @@ static void schemaIsValid(Parse *pParse){
if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_NONE ){
rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
pParse->rc = SQLITE_NOMEM;
}
if( rc!=SQLITE_OK ) return;
@@ -132783,8 +132783,8 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
*/
assert( sqlite3_mutex_held(db->mutex) );
if( pSchema ){
- for(i=0; 1; i++){
- assert( i<db->nDb );
+ for(i=0; 1; i++){
+ assert( i<db->nDb );
if( db->aDb[i].pSchema==pSchema ){
break;
}
@@ -132798,23 +132798,23 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
** Free all memory allocations in the pParse object
*/
SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){
- sqlite3 *db = pParse->db;
+ sqlite3 *db = pParse->db;
while( pParse->pCleanup ){
ParseCleanup *pCleanup = pParse->pCleanup;
pParse->pCleanup = pCleanup->pNext;
pCleanup->xCleanup(db, pCleanup->pPtr);
sqlite3DbFreeNN(db, pCleanup);
}
- sqlite3DbFree(db, pParse->aLabel);
+ sqlite3DbFree(db, pParse->aLabel);
if( pParse->pConstExpr ){
sqlite3ExprListDelete(db, pParse->pConstExpr);
}
- if( db ){
- assert( db->lookaside.bDisable >= pParse->disableLookaside );
- db->lookaside.bDisable -= pParse->disableLookaside;
+ if( db ){
+ assert( db->lookaside.bDisable >= pParse->disableLookaside );
+ db->lookaside.bDisable -= pParse->disableLookaside;
db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
}
- pParse->disableLookaside = 0;
+ pParse->disableLookaside = 0;
}
/*
@@ -132873,7 +132873,7 @@ static int sqlite3Prepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
- u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
+ u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
Vdbe *pReprepare, /* VM being reprepared */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
@@ -132881,24 +132881,24 @@ static int sqlite3Prepare(
char *zErrMsg = 0; /* Error message */
int rc = SQLITE_OK; /* Result code */
int i; /* Loop counter */
- Parse sParse; /* Parsing context */
+ Parse sParse; /* Parsing context */
- memset(&sParse, 0, PARSE_HDR_SZ);
- memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
- sParse.pReprepare = pReprepare;
+ memset(&sParse, 0, PARSE_HDR_SZ);
+ memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
+ sParse.pReprepare = pReprepare;
assert( ppStmt && *ppStmt==0 );
- /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
+ /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
assert( sqlite3_mutex_held(db->mutex) );
- /* For a long-term use prepared statement avoid the use of
- ** lookaside memory.
- */
- if( prepFlags & SQLITE_PREPARE_PERSISTENT ){
- sParse.disableLookaside++;
+ /* For a long-term use prepared statement avoid the use of
+ ** lookaside memory.
+ */
+ if( prepFlags & SQLITE_PREPARE_PERSISTENT ){
+ sParse.disableLookaside++;
DisableLookaside;
- }
+ }
sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0;
-
+
/* Check to verify that it is possible to get a read lock on all
** database schemas. The inability to get a read lock indicates that
** some other database connection is holding a write-lock, which in
@@ -132940,7 +132940,7 @@ static int sqlite3Prepare(
sqlite3VtabUnlockList(db);
- sParse.db = db;
+ sParse.db = db;
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
char *zSqlCopy;
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
@@ -132953,23 +132953,23 @@ static int sqlite3Prepare(
}
zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
if( zSqlCopy ){
- sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
- sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
+ sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
+ sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
sqlite3DbFree(db, zSqlCopy);
}else{
- sParse.zTail = &zSql[nBytes];
+ sParse.zTail = &zSql[nBytes];
}
}else{
- sqlite3RunParser(&sParse, zSql, &zErrMsg);
+ sqlite3RunParser(&sParse, zSql, &zErrMsg);
}
- assert( 0==sParse.nQueryLoop );
+ assert( 0==sParse.nQueryLoop );
if( pzTail ){
- *pzTail = sParse.zTail;
+ *pzTail = sParse.zTail;
}
if( db->init.busy==0 ){
- sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags);
+ sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags);
}
if( db->mallocFailed ){
sParse.rc = SQLITE_NOMEM_BKPT;
@@ -132992,35 +132992,35 @@ static int sqlite3Prepare(
}
}else{
assert( zErrMsg==0 );
- *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
+ *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
rc = SQLITE_OK;
sqlite3ErrorClear(db);
}
/* Delete any TriggerPrg structures allocated while parsing this statement. */
- while( sParse.pTriggerPrg ){
- TriggerPrg *pT = sParse.pTriggerPrg;
- sParse.pTriggerPrg = pT->pNext;
+ while( sParse.pTriggerPrg ){
+ TriggerPrg *pT = sParse.pTriggerPrg;
+ sParse.pTriggerPrg = pT->pNext;
sqlite3DbFree(db, pT);
}
end_prepare:
- sqlite3ParserReset(&sParse);
+ sqlite3ParserReset(&sParse);
return rc;
}
static int sqlite3LockAndPrepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
- u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
+ u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
Vdbe *pOld, /* VM being reprepared */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
){
int rc;
- int cnt = 0;
+ int cnt = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
@@ -133031,18 +133031,18 @@ static int sqlite3LockAndPrepare(
}
sqlite3_mutex_enter(db->mutex);
sqlite3BtreeEnterAll(db);
- do{
- /* Make multiple attempts to compile the SQL, until it either succeeds
- ** or encounters a permanent error. A schema problem after one schema
- ** reset is considered a permanent error. */
- rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
- assert( rc==SQLITE_OK || *ppStmt==0 );
+ do{
+ /* Make multiple attempts to compile the SQL, until it either succeeds
+ ** or encounters a permanent error. A schema problem after one schema
+ ** reset is considered a permanent error. */
+ rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
+ assert( rc==SQLITE_OK || *ppStmt==0 );
if( rc==SQLITE_OK || db->mallocFailed ) break;
- }while( rc==SQLITE_ERROR_RETRY
- || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
+ }while( rc==SQLITE_ERROR_RETRY
+ || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
sqlite3BtreeLeaveAll(db);
- rc = sqlite3ApiExit(db, rc);
- assert( (rc&db->errMask)==rc );
+ rc = sqlite3ApiExit(db, rc);
+ assert( (rc&db->errMask)==rc );
db->busyHandler.nBusy = 0;
sqlite3_mutex_leave(db->mutex);
return rc;
@@ -133062,18 +133062,18 @@ SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){
sqlite3_stmt *pNew;
const char *zSql;
sqlite3 *db;
- u8 prepFlags;
+ u8 prepFlags;
assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) );
zSql = sqlite3_sql((sqlite3_stmt *)p);
assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */
db = sqlite3VdbeDb(p);
assert( sqlite3_mutex_held(db->mutex) );
- prepFlags = sqlite3VdbePrepareFlags(p);
- rc = sqlite3LockAndPrepare(db, zSql, -1, prepFlags, p, &pNew, 0);
+ prepFlags = sqlite3VdbePrepareFlags(p);
+ rc = sqlite3LockAndPrepare(db, zSql, -1, prepFlags, p, &pNew, 0);
if( rc ){
if( rc==SQLITE_NOMEM ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
}
assert( pNew==0 );
return rc;
@@ -133096,7 +133096,7 @@ SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){
** and the statement is automatically recompiled if an schema change
** occurs.
*/
-SQLITE_API int sqlite3_prepare(
+SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -133108,7 +133108,7 @@ SQLITE_API int sqlite3_prepare(
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
-SQLITE_API int sqlite3_prepare_v2(
+SQLITE_API int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -133116,38 +133116,38 @@ SQLITE_API int sqlite3_prepare_v2(
const char **pzTail /* OUT: End of parsed string */
){
int rc;
- /* EVIDENCE-OF: R-37923-12173 The sqlite3_prepare_v2() interface works
- ** exactly the same as sqlite3_prepare_v3() with a zero prepFlags
- ** parameter.
- **
- ** Proof in that the 5th parameter to sqlite3LockAndPrepare is 0 */
- rc = sqlite3LockAndPrepare(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,0,
- ppStmt,pzTail);
- assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );
- return rc;
-}
-SQLITE_API int sqlite3_prepare_v3(
- sqlite3 *db, /* Database handle. */
- const char *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const char **pzTail /* OUT: End of parsed string */
-){
- int rc;
- /* EVIDENCE-OF: R-56861-42673 sqlite3_prepare_v3() differs from
- ** sqlite3_prepare_v2() only in having the extra prepFlags parameter,
- ** which is a bit array consisting of zero or more of the
- ** SQLITE_PREPARE_* flags.
- **
- ** Proof by comparison to the implementation of sqlite3_prepare_v2()
- ** directly above. */
- rc = sqlite3LockAndPrepare(db,zSql,nBytes,
- SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK),
- 0,ppStmt,pzTail);
- assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );
- return rc;
-}
+ /* EVIDENCE-OF: R-37923-12173 The sqlite3_prepare_v2() interface works
+ ** exactly the same as sqlite3_prepare_v3() with a zero prepFlags
+ ** parameter.
+ **
+ ** Proof in that the 5th parameter to sqlite3LockAndPrepare is 0 */
+ rc = sqlite3LockAndPrepare(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,0,
+ ppStmt,pzTail);
+ assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );
+ return rc;
+}
+SQLITE_API int sqlite3_prepare_v3(
+ sqlite3 *db, /* Database handle. */
+ const char *zSql, /* UTF-8 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const char **pzTail /* OUT: End of parsed string */
+){
+ int rc;
+ /* EVIDENCE-OF: R-56861-42673 sqlite3_prepare_v3() differs from
+ ** sqlite3_prepare_v2() only in having the extra prepFlags parameter,
+ ** which is a bit array consisting of zero or more of the
+ ** SQLITE_PREPARE_* flags.
+ **
+ ** Proof by comparison to the implementation of sqlite3_prepare_v2()
+ ** directly above. */
+ rc = sqlite3LockAndPrepare(db,zSql,nBytes,
+ SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK),
+ 0,ppStmt,pzTail);
+ assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );
+ return rc;
+}
#ifndef SQLITE_OMIT_UTF16
@@ -133158,7 +133158,7 @@ static int sqlite3Prepare16(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-16 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
- u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
+ u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const void **pzTail /* OUT: End of parsed string */
){
@@ -133186,7 +133186,7 @@ static int sqlite3Prepare16(
sqlite3_mutex_enter(db->mutex);
zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
if( zSql8 ){
- rc = sqlite3LockAndPrepare(db, zSql8, -1, prepFlags, 0, ppStmt, &zTail8);
+ rc = sqlite3LockAndPrepare(db, zSql8, -1, prepFlags, 0, ppStmt, &zTail8);
}
if( zTail8 && pzTail ){
@@ -133212,7 +133212,7 @@ static int sqlite3Prepare16(
** and the statement is automatically recompiled if an schema change
** occurs.
*/
-SQLITE_API int sqlite3_prepare16(
+SQLITE_API int sqlite3_prepare16(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-16 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -133224,7 +133224,7 @@ SQLITE_API int sqlite3_prepare16(
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
-SQLITE_API int sqlite3_prepare16_v2(
+SQLITE_API int sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-16 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -133232,25 +133232,25 @@ SQLITE_API int sqlite3_prepare16_v2(
const void **pzTail /* OUT: End of parsed string */
){
int rc;
- rc = sqlite3Prepare16(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,ppStmt,pzTail);
+ rc = sqlite3Prepare16(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,ppStmt,pzTail);
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
-SQLITE_API int sqlite3_prepare16_v3(
+SQLITE_API int sqlite3_prepare16_v3(
sqlite3 *db, /* Database handle. */
- const void *zSql, /* UTF-16 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const void **pzTail /* OUT: End of parsed string */
-){
- int rc;
- rc = sqlite3Prepare16(db,zSql,nBytes,
- SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK),
- ppStmt,pzTail);
- assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
- return rc;
-}
+ const void *zSql, /* UTF-16 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const void **pzTail /* OUT: End of parsed string */
+){
+ int rc;
+ rc = sqlite3Prepare16(db,zSql,nBytes,
+ SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK),
+ ppStmt,pzTail);
+ assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
+ return rc;
+}
#endif /* SQLITE_OMIT_UTF16 */
@@ -133311,7 +133311,7 @@ struct SortCtx {
int regReturn; /* Register holding block-output return address */
int labelBkOut; /* Start label for the block-output subroutine */
int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */
- int labelDone; /* Jump here when done, ex: LIMIT reached */
+ int labelDone; /* Jump here when done, ex: LIMIT reached */
int labelOBLopt; /* Jump here when sorter is full */
u8 sortFlags; /* Zero or more SORTFLAG_* bits */
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
@@ -133353,7 +133353,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
sqlite3WindowUnlinkFromSelect(p->pWin);
}
#endif
- if( bFree ) sqlite3DbFreeNN(db, p);
+ if( bFree ) sqlite3DbFreeNN(db, p);
p = pPrior;
bFree = 1;
}
@@ -133366,7 +133366,7 @@ SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iPar
pDest->eDest = (u8)eDest;
pDest->iSDParm = iParm;
pDest->iSDParm2 = 0;
- pDest->zAffSdst = 0;
+ pDest->zAffSdst = 0;
pDest->iSdst = 0;
pDest->nSdst = 0;
}
@@ -133384,45 +133384,45 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
ExprList *pGroupBy, /* the GROUP BY clause */
Expr *pHaving, /* the HAVING clause */
ExprList *pOrderBy, /* the ORDER BY clause */
- u32 selFlags, /* Flag parameters, such as SF_Distinct */
- Expr *pLimit /* LIMIT value. NULL means not used */
+ u32 selFlags, /* Flag parameters, such as SF_Distinct */
+ Expr *pLimit /* LIMIT value. NULL means not used */
){
Select *pNew, *pAllocated;
Select standin;
pAllocated = pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) );
if( pNew==0 ){
- assert( pParse->db->mallocFailed );
+ assert( pParse->db->mallocFailed );
pNew = &standin;
}
if( pEList==0 ){
- pEList = sqlite3ExprListAppend(pParse, 0,
- sqlite3Expr(pParse->db,TK_ASTERISK,0));
+ pEList = sqlite3ExprListAppend(pParse, 0,
+ sqlite3Expr(pParse->db,TK_ASTERISK,0));
}
pNew->pEList = pEList;
- pNew->op = TK_SELECT;
- pNew->selFlags = selFlags;
- pNew->iLimit = 0;
- pNew->iOffset = 0;
+ pNew->op = TK_SELECT;
+ pNew->selFlags = selFlags;
+ pNew->iLimit = 0;
+ pNew->iOffset = 0;
pNew->selId = ++pParse->nSelect;
- pNew->addrOpenEphm[0] = -1;
- pNew->addrOpenEphm[1] = -1;
- pNew->nSelectRow = 0;
- if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc));
+ pNew->addrOpenEphm[0] = -1;
+ pNew->addrOpenEphm[1] = -1;
+ pNew->nSelectRow = 0;
+ if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc));
pNew->pSrc = pSrc;
pNew->pWhere = pWhere;
pNew->pGroupBy = pGroupBy;
pNew->pHaving = pHaving;
pNew->pOrderBy = pOrderBy;
- pNew->pPrior = 0;
- pNew->pNext = 0;
+ pNew->pPrior = 0;
+ pNew->pNext = 0;
pNew->pLimit = pLimit;
- pNew->pWith = 0;
+ pNew->pWith = 0;
#ifndef SQLITE_OMIT_WINDOWFUNC
pNew->pWin = 0;
pNew->pWinDefn = 0;
#endif
- if( pParse->db->mallocFailed ) {
- clearSelect(pParse->db, pNew, pNew!=&standin);
+ if( pParse->db->mallocFailed ) {
+ clearSelect(pParse->db, pNew, pNew!=&standin);
pAllocated = 0;
}else{
assert( pNew->pSrc!=0 || pParse->nErr>0 );
@@ -133435,7 +133435,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
** Delete the given Select structure and all of its substructures.
*/
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
- if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1);
+ if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1);
}
/*
@@ -133604,7 +133604,7 @@ static void addWhereTerm(
pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft);
pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);
- pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
+ pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
assert( pE2!=0 || pEq==0 ); /* Due to db->mallocFailed test
** in sqlite3DbMallocRawNN() called from
** sqlite3PExpr(). */
@@ -133719,13 +133719,13 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
Table *pRightTab = pRight->pTab;
int isOuter;
- if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
- isOuter = (pRight->fg.jointype & JT_OUTER)!=0;
+ if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
+ isOuter = (pRight->fg.jointype & JT_OUTER)!=0;
/* When the NATURAL keyword is present, add WHERE clause terms for
** every column that the two tables have in common.
*/
- if( pRight->fg.jointype & JT_NATURAL ){
+ if( pRight->fg.jointype & JT_NATURAL ){
if( pRight->pOn || pRight->pUsing ){
sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
"an ON or USING clause", 0);
@@ -133859,7 +133859,7 @@ static void pushOntoSorter(
SortCtx *pSort, /* Information about the ORDER BY clause */
Select *pSelect, /* The whole SELECT statement */
int regData, /* First register holding data to be sorted */
- int regOrigData, /* First register holding data before packing */
+ int regOrigData, /* First register holding data before packing */
int nData, /* Number of elements in the regData data array */
int nPrefixReg /* No. of reg prior to regData available for use */
){
@@ -133871,7 +133871,7 @@ static void pushOntoSorter(
int regRecord = 0; /* Assembled sorter record */
int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */
int op; /* Opcode to add sorter record to sorter */
- int iLimit; /* LIMIT counter */
+ int iLimit; /* LIMIT counter */
int iSkip = 0; /* End of the sorter insert loop */
assert( bSeq==0 || bSeq==1 );
@@ -133889,7 +133889,7 @@ static void pushOntoSorter(
** regOrigData is 0 to prevent this routine from trying to copy
** values that might not yet exist.
*/
- assert( nData==1 || regData==regOrigData || regOrigData==0 );
+ assert( nData==1 || regData==regOrigData || regOrigData==0 );
if( nPrefixReg ){
assert( nPrefixReg==nExpr+bSeq );
@@ -133898,15 +133898,15 @@ static void pushOntoSorter(
regBase = pParse->nMem + 1;
pParse->nMem += nBase;
}
- assert( pSelect->iOffset==0 || pSelect->iLimit!=0 );
- iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
+ assert( pSelect->iOffset==0 || pSelect->iLimit!=0 );
+ iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
pSort->labelDone = sqlite3VdbeMakeLabel(pParse);
- sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
- SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
+ sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
+ SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
if( bSeq ){
sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
}
- if( nPrefixReg==0 && nData>0 ){
+ if( nPrefixReg==0 && nData>0 ){
sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
}
if( nOBSat>0 ){
@@ -133934,9 +133934,9 @@ static void pushOntoSorter(
pKI = pOp->p4.pKeyInfo;
memset(pKI->aSortFlags, 0, pKI->nKeyField); /* Makes OP_Jump testable */
sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
- testcase( pKI->nAllField > pKI->nKeyField+2 );
+ testcase( pKI->nAllField > pKI->nKeyField+2 );
pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat,
- pKI->nAllField-pKI->nKeyField-1);
+ pKI->nAllField-pKI->nKeyField-1);
pOp = 0; /* Ensure pOp not used after sqltie3VdbeAddOp3() */
addrJmp = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
@@ -133944,10 +133944,10 @@ static void pushOntoSorter(
pSort->regReturn = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
- if( iLimit ){
- sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone);
- VdbeCoverage(v);
- }
+ if( iLimit ){
+ sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone);
+ VdbeCoverage(v);
+ }
sqlite3VdbeJumpHere(v, addrFirst);
sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat);
sqlite3VdbeJumpHere(v, addrJmp);
@@ -133985,8 +133985,8 @@ static void pushOntoSorter(
}else{
op = OP_IdxInsert;
}
- sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord,
- regBase+nOBSat, nBase-nOBSat);
+ sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord,
+ regBase+nOBSat, nBase-nOBSat);
if( iSkip ){
sqlite3VdbeChangeP2(v, iSkip,
pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v));
@@ -134002,8 +134002,8 @@ static void codeOffset(
int iContinue /* Jump here to skip the current record */
){
if( iOffset>0 ){
- sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v);
- VdbeComment((v, "OFFSET"));
+ sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v);
+ VdbeComment((v, "OFFSET"));
}
}
@@ -134251,15 +134251,15 @@ static void selectExprDefer(
** This routine generates the code for the inside of the inner loop
** of a SELECT.
**
-** If srcTab is negative, then the p->pEList expressions
+** If srcTab is negative, then the p->pEList expressions
** are evaluated in order to get the data for this row. If srcTab is
** zero or more, then data is pulled from srcTab and p->pEList is used only
-** to get the number of columns and the collation sequence for each column.
+** to get the number of columns and the collation sequence for each column.
*/
static void selectInnerLoop(
Parse *pParse, /* The parser context */
Select *p, /* The complete select statement being coded */
- int srcTab, /* Pull data from this table if non-negative */
+ int srcTab, /* Pull data from this table if non-negative */
SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */
DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */
SelectDest *pDest, /* How to dispose of the results */
@@ -134268,23 +134268,23 @@ static void selectInnerLoop(
){
Vdbe *v = pParse->pVdbe;
int i;
- int hasDistinct; /* True if the DISTINCT keyword is present */
+ int hasDistinct; /* True if the DISTINCT keyword is present */
int eDest = pDest->eDest; /* How to dispose of results */
int iParm = pDest->iSDParm; /* First argument to disposal method */
int nResultCol; /* Number of result columns */
int nPrefixReg = 0; /* Number of extra registers before regResult */
RowLoadInfo sRowLoadInfo; /* Info for deferred row loading */
- /* Usually, regResult is the first cell in an array of memory cells
- ** containing the current result row. In this case regOrig is set to the
- ** same value. However, if the results are being sent to the sorter, the
- ** values for any expressions that are also part of the sort-key are omitted
- ** from this array. In this case regOrig is set to zero. */
- int regResult; /* Start of memory holding current results */
- int regOrig; /* Start of memory holding full result (or 0) */
-
+ /* Usually, regResult is the first cell in an array of memory cells
+ ** containing the current result row. In this case regOrig is set to the
+ ** same value. However, if the results are being sent to the sorter, the
+ ** values for any expressions that are also part of the sort-key are omitted
+ ** from this array. In this case regOrig is set to zero. */
+ int regResult; /* Start of memory holding current results */
+ int regOrig; /* Start of memory holding full result (or 0) */
+
assert( v );
- assert( p->pEList!=0 );
+ assert( p->pEList!=0 );
hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
if( pSort && pSort->pOrderBy==0 ) pSort = 0;
if( pSort==0 && !hasDistinct ){
@@ -134294,7 +134294,7 @@ static void selectInnerLoop(
/* Pull the requested columns.
*/
- nResultCol = p->pEList->nExpr;
+ nResultCol = p->pEList->nExpr;
if( pDest->iSdst==0 ){
if( pSort ){
@@ -134313,7 +134313,7 @@ static void selectInnerLoop(
pParse->nMem += nResultCol;
}
pDest->nSdst = nResultCol;
- regOrig = regResult = pDest->iSdst;
+ regOrig = regResult = pDest->iSdst;
if( srcTab>=0 ){
for(i=0; i<nResultCol; i++){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
@@ -134333,21 +134333,21 @@ static void selectInnerLoop(
}else{
ecelFlags = 0;
}
- if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){
- /* For each expression in p->pEList that is a copy of an expression in
+ if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){
+ /* For each expression in p->pEList that is a copy of an expression in
** the ORDER BY clause (pSort->pOrderBy), set the associated
** iOrderByCol value to one more than the index of the ORDER BY
- ** expression within the sort-key that pushOntoSorter() will generate.
- ** This allows the p->pEList field to be omitted from the sorted record,
- ** saving space and CPU cycles. */
- ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF);
-
- for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){
- int j;
- if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){
- p->pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
- }
- }
+ ** expression within the sort-key that pushOntoSorter() will generate.
+ ** This allows the p->pEList field to be omitted from the sorted record,
+ ** saving space and CPU cycles. */
+ ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF);
+
+ for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){
+ int j;
+ if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){
+ p->pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
+ }
+ }
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
selectExprDefer(pParse, pSort, p->pEList, &pExtra);
if( pExtra && pParse->db->mallocFailed==0 ){
@@ -134385,7 +134385,7 @@ static void selectInnerLoop(
assert( eDest==SRT_Set || eDest==SRT_Mem
|| eDest==SRT_Coroutine || eDest==SRT_Output
|| eDest==SRT_Upfrom );
- }
+ }
sRowLoadInfo.regResult = regResult;
sRowLoadInfo.ecelFlags = ecelFlags;
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
@@ -134430,7 +134430,7 @@ static void selectInnerLoop(
int r1;
r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
sqlite3ReleaseTempReg(pParse, r1);
break;
}
@@ -134467,7 +134467,7 @@ static void selectInnerLoop(
int addr = sqlite3VdbeCurrentAddr(v) + 4;
sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0);
VdbeCoverage(v);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol);
assert( pSort==0 );
}
#endif
@@ -134520,14 +134520,14 @@ static void selectInnerLoop(
** ORDER BY in this case since the order of entries in the set
** does not matter. But there might be a LIMIT clause, in which
** case the order does matter */
- pushOntoSorter(
- pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
+ pushOntoSorter(
+ pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
}else{
int r1 = sqlite3GetTempReg(pParse);
- assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
+ assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol,
- r1, pDest->zAffSdst, nResultCol);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
+ r1, pDest->zAffSdst, nResultCol);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
sqlite3ReleaseTempReg(pParse, r1);
}
break;
@@ -134544,15 +134544,15 @@ static void selectInnerLoop(
/* If this is a scalar select that is part of an expression, then
** store the results in the appropriate memory cell or array of
- ** memory cells and break out of the scan loop.
+ ** memory cells and break out of the scan loop.
*/
case SRT_Mem: {
if( pSort ){
- assert( nResultCol<=pDest->nSdst );
- pushOntoSorter(
- pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
+ assert( nResultCol<=pDest->nSdst );
+ pushOntoSorter(
+ pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
}else{
- assert( nResultCol==pDest->nSdst );
+ assert( nResultCol==pDest->nSdst );
assert( regResult==iParm );
/* The LIMIT clause will jump out of the loop for us */
}
@@ -134565,8 +134565,8 @@ static void selectInnerLoop(
testcase( eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
if( pSort ){
- pushOntoSorter(pParse, pSort, p, regResult, regOrig, nResultCol,
- nPrefixReg);
+ pushOntoSorter(pParse, pSort, p, regResult, regOrig, nResultCol,
+ nPrefixReg);
}else if( eDest==SRT_Coroutine ){
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}else{
@@ -134614,7 +134614,7 @@ static void selectInnerLoop(
}
sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey);
sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2);
if( addrTest ) sqlite3VdbeJumpHere(v, addrTest);
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ReleaseTempRange(pParse, r2, nKey+2);
@@ -134651,18 +134651,18 @@ static void selectInnerLoop(
** X extra columns.
*/
SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
- int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*);
- KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
+ int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*);
+ KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
if( p ){
p->aSortFlags = (u8*)&p->aColl[N+X];
- p->nKeyField = (u16)N;
- p->nAllField = (u16)(N+X);
+ p->nKeyField = (u16)N;
+ p->nAllField = (u16)(N+X);
p->enc = ENC(db);
p->db = db;
p->nRef = 1;
- memset(&p[1], 0, nExtra);
+ memset(&p[1], 0, nExtra);
}else{
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
}
return p;
}
@@ -134674,7 +134674,7 @@ SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){
if( p ){
assert( p->nRef>0 );
p->nRef--;
- if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p);
+ if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p);
}
}
@@ -134730,7 +134730,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(
if( pInfo ){
assert( sqlite3KeyInfoIsWriteable(pInfo) );
for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
- pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr);
+ pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr);
pInfo->aSortFlags[i-iStart] = pItem->sortFlags;
}
}
@@ -134796,7 +134796,7 @@ static void generateSortTail(
SelectDest *pDest /* Write the sorted results here */
){
Vdbe *v = pParse->pVdbe; /* The prepared statement */
- int addrBreak = pSort->labelDone; /* Jump here to exit loop */
+ int addrBreak = pSort->labelDone; /* Jump here to exit loop */
int addrContinue = sqlite3VdbeMakeLabel(pParse);/* Jump here for next cycle */
int addr; /* Top of output loop. Jump for Next. */
int addrOnce = 0;
@@ -134806,7 +134806,7 @@ static void generateSortTail(
int iParm = pDest->iSDParm;
int regRow;
int regRowid;
- int iCol;
+ int iCol;
int nKey; /* Number of key columns in sorter record */
int iSortTab; /* Sorter cursor to read from */
int i;
@@ -134814,10 +134814,10 @@ static void generateSortTail(
int nRefKey = 0;
struct ExprList_item *aOutEx = p->pEList->a;
- assert( addrBreak<0 );
+ assert( addrBreak<0 );
if( pSort->labelBkOut ){
sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
- sqlite3VdbeGoto(v, addrBreak);
+ sqlite3VdbeGoto(v, addrBreak);
sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
}
@@ -134832,7 +134832,7 @@ static void generateSortTail(
#endif
iTab = pSort->iECursor;
- if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){
+ if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){
regRowid = 0;
regRow = pDest->iSdst;
}else{
@@ -134849,7 +134849,7 @@ static void generateSortTail(
int regSortOut = ++pParse->nMem;
iSortTab = pParse->nTab++;
if( pSort->labelBkOut ){
- addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut,
nKey+1+nColumn+nRefKey);
@@ -134898,7 +134898,7 @@ static void generateSortTail(
sqlite3VdbeAddOp4Int(v, OP_IdxLE, iCsr, iJmp+3, regKey, nKey);
sqlite3VdbeAddOp1(v, OP_NullRow, iCsr);
}
- }
+ }
sqlite3ReleaseTempRange(pParse, regKey, nRefKey);
}
#endif
@@ -134920,7 +134920,7 @@ static void generateSortTail(
}
}
switch( eDest ){
- case SRT_Table:
+ case SRT_Table:
case SRT_EphemTab: {
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq, regRow);
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
@@ -134930,10 +134930,10 @@ static void generateSortTail(
}
#ifndef SQLITE_OMIT_SUBQUERY
case SRT_Set: {
- assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) );
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid,
- pDest->zAffSdst, nColumn);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn);
+ assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) );
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid,
+ pDest->zAffSdst, nColumn);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn);
break;
}
case SRT_Mem: {
@@ -134965,11 +134965,11 @@ static void generateSortTail(
}
}
if( regRowid ){
- if( eDest==SRT_Set ){
- sqlite3ReleaseTempRange(pParse, regRow, nColumn);
- }else{
- sqlite3ReleaseTempReg(pParse, regRow);
- }
+ if( eDest==SRT_Set ){
+ sqlite3ReleaseTempRange(pParse, regRow, nColumn);
+ }else{
+ sqlite3ReleaseTempReg(pParse, regRow);
+ }
sqlite3ReleaseTempReg(pParse, regRowid);
}
/* The bottom of the loop
@@ -135009,19 +135009,19 @@ static void generateSortTail(
** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used.
*/
#ifdef SQLITE_ENABLE_COLUMN_METADATA
-# define columnType(A,B,C,D,E) columnTypeImpl(A,B,C,D,E)
+# define columnType(A,B,C,D,E) columnTypeImpl(A,B,C,D,E)
#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */
-# define columnType(A,B,C,D,E) columnTypeImpl(A,B)
+# define columnType(A,B,C,D,E) columnTypeImpl(A,B)
#endif
static const char *columnTypeImpl(
NameContext *pNC,
-#ifndef SQLITE_ENABLE_COLUMN_METADATA
- Expr *pExpr
-#else
+#ifndef SQLITE_ENABLE_COLUMN_METADATA
+ Expr *pExpr
+#else
Expr *pExpr,
const char **pzOrigDb,
const char **pzOrigTab,
- const char **pzOrigCol
+ const char **pzOrigCol
#endif
){
char const *zType = 0;
@@ -135032,8 +135032,8 @@ static const char *columnTypeImpl(
char const *zOrigCol = 0;
#endif
- assert( pExpr!=0 );
- assert( pNC->pSrcList!=0 );
+ assert( pExpr!=0 );
+ assert( pNC->pSrcList!=0 );
switch( pExpr->op ){
case TK_COLUMN: {
/* The expression is a column. Locate the table the column is being
@@ -135099,30 +135099,30 @@ static const char *columnTypeImpl(
sNC.pParse = pNC->pParse;
zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol);
}
- }else{
- /* A real table or a CTE table */
+ }else{
+ /* A real table or a CTE table */
assert( !pS );
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
if( iCol<0 ) iCol = pTab->iPKey;
- assert( iCol==XN_ROWID || (iCol>=0 && iCol<pTab->nCol) );
+ assert( iCol==XN_ROWID || (iCol>=0 && iCol<pTab->nCol) );
if( iCol<0 ){
zType = "INTEGER";
zOrigCol = "rowid";
}else{
zOrigCol = pTab->aCol[iCol].zCnName;
- zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
+ zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
}
zOrigTab = pTab->zName;
- if( pNC->pParse && pTab->pSchema ){
+ if( pNC->pParse && pTab->pSchema ){
int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
- zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName;
+ zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName;
}
#else
- assert( iCol==XN_ROWID || (iCol>=0 && iCol<pTab->nCol) );
+ assert( iCol==XN_ROWID || (iCol>=0 && iCol<pTab->nCol) );
if( iCol<0 ){
zType = "INTEGER";
}else{
- zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
+ zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
}
#endif
}
@@ -135175,7 +135175,7 @@ static void generateColumnTypes(
NameContext sNC;
sNC.pSrcList = pTabList;
sNC.pParse = pParse;
- sNC.pNext = 0;
+ sNC.pNext = 0;
for(i=0; i<pEList->nExpr; i++){
Expr *p = pEList->a[i].pExpr;
const char *zType;
@@ -135183,7 +135183,7 @@ static void generateColumnTypes(
const char *zOrigDb = 0;
const char *zOrigTab = 0;
const char *zOrigCol = 0;
- 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
@@ -135193,56 +135193,56 @@ static void generateColumnTypes(
sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT);
sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT);
#else
- zType = columnType(&sNC, p, 0, 0, 0);
+ zType = columnType(&sNC, p, 0, 0, 0);
#endif
sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
}
#endif /* !defined(SQLITE_OMIT_DECLTYPE) */
}
-
-/*
-** Compute the column names for a SELECT statement.
-**
-** The only guarantee that SQLite makes about column names is that if the
-** column has an AS clause assigning it a name, that will be the name used.
-** That is the only documented guarantee. However, countless applications
-** developed over the years have made baseless assumptions about column names
-** and will break if those assumptions changes. Hence, use extreme caution
-** when modifying this routine to avoid breaking legacy.
-**
-** See Also: sqlite3ColumnsFromExprList()
-**
-** The PRAGMA short_column_names and PRAGMA full_column_names settings are
-** deprecated. The default setting is short=ON, full=OFF. 99.9% of all
-** applications should operate this way. Nevertheless, we need to support the
-** other modes for legacy:
-**
-** short=OFF, full=OFF: Column name is the text of the expression has it
-** originally appears in the SELECT statement. In
-** other words, the zSpan of the result expression.
-**
-** short=ON, full=OFF: (This is the default setting). If the result
-** refers directly to a table column, then the
-** result column name is just the table column
-** name: COLUMN. Otherwise use zSpan.
-**
-** full=ON, short=ANY: If the result refers directly to a table column,
-** then the result column name with the table name
-** prefix, ex: TABLE.COLUMN. Otherwise use zSpan.
+
+/*
+** Compute the column names for a SELECT statement.
+**
+** The only guarantee that SQLite makes about column names is that if the
+** column has an AS clause assigning it a name, that will be the name used.
+** That is the only documented guarantee. However, countless applications
+** developed over the years have made baseless assumptions about column names
+** and will break if those assumptions changes. Hence, use extreme caution
+** when modifying this routine to avoid breaking legacy.
+**
+** See Also: sqlite3ColumnsFromExprList()
+**
+** The PRAGMA short_column_names and PRAGMA full_column_names settings are
+** deprecated. The default setting is short=ON, full=OFF. 99.9% of all
+** applications should operate this way. Nevertheless, we need to support the
+** other modes for legacy:
+**
+** short=OFF, full=OFF: Column name is the text of the expression has it
+** originally appears in the SELECT statement. In
+** other words, the zSpan of the result expression.
+**
+** short=ON, full=OFF: (This is the default setting). If the result
+** refers directly to a table column, then the
+** result column name is just the table column
+** name: COLUMN. Otherwise use zSpan.
+**
+** full=ON, short=ANY: If the result refers directly to a table column,
+** then the result column name with the table name
+** prefix, ex: TABLE.COLUMN. Otherwise use zSpan.
*/
SQLITE_PRIVATE void sqlite3GenerateColumnNames(
Parse *pParse, /* Parser context */
- Select *pSelect /* Generate column names for this SELECT statement */
+ Select *pSelect /* Generate column names for this SELECT statement */
){
Vdbe *v = pParse->pVdbe;
- int i;
- Table *pTab;
- SrcList *pTabList;
- ExprList *pEList;
+ int i;
+ Table *pTab;
+ SrcList *pTabList;
+ ExprList *pEList;
sqlite3 *db = pParse->db;
- int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */
- int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */
+ int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */
+ int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */
#ifndef SQLITE_OMIT_EXPLAIN
/* If this is an EXPLAIN, skip this step */
@@ -135252,33 +135252,33 @@ SQLITE_PRIVATE void sqlite3GenerateColumnNames(
#endif
if( pParse->colNamesSet ) return;
- /* Column names are determined by the left-most term of a compound select */
- while( pSelect->pPrior ) pSelect = pSelect->pPrior;
- SELECTTRACE(1,pParse,pSelect,("generating column names\n"));
- pTabList = pSelect->pSrc;
- pEList = pSelect->pEList;
- assert( v!=0 );
- assert( pTabList!=0 );
+ /* Column names are determined by the left-most term of a compound select */
+ while( pSelect->pPrior ) pSelect = pSelect->pPrior;
+ SELECTTRACE(1,pParse,pSelect,("generating column names\n"));
+ pTabList = pSelect->pSrc;
+ pEList = pSelect->pEList;
+ assert( v!=0 );
+ assert( pTabList!=0 );
pParse->colNamesSet = 1;
- fullName = (db->flags & SQLITE_FullColNames)!=0;
- srcName = (db->flags & SQLITE_ShortColNames)!=0 || fullName;
+ fullName = (db->flags & SQLITE_FullColNames)!=0;
+ srcName = (db->flags & SQLITE_ShortColNames)!=0 || fullName;
sqlite3VdbeSetNumCols(v, pEList->nExpr);
for(i=0; i<pEList->nExpr; i++){
- Expr *p = pEList->a[i].pExpr;
-
- assert( p!=0 );
- assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
+ Expr *p = pEList->a[i].pExpr;
+
+ assert( p!=0 );
+ assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
assert( p->op!=TK_COLUMN
|| (ExprUseYTab(p) && p->y.pTab!=0) ); /* Covering idx not yet coded */
if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){
- /* An AS clause always takes first priority */
+ /* An AS clause always takes first priority */
char *zName = pEList->a[i].zEName;
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
- }else if( srcName && p->op==TK_COLUMN ){
+ }else if( srcName && p->op==TK_COLUMN ){
char *zCol;
int iCol = p->iColumn;
pTab = p->y.pTab;
- assert( pTab!=0 );
+ assert( pTab!=0 );
if( iCol<0 ) iCol = pTab->iPKey;
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
if( iCol<0 ){
@@ -135286,7 +135286,7 @@ SQLITE_PRIVATE void sqlite3GenerateColumnNames(
}else{
zCol = pTab->aCol[iCol].zCnName;
}
- if( fullName ){
+ if( fullName ){
char *zName = 0;
zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol);
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC);
@@ -135314,17 +135314,17 @@ SQLITE_PRIVATE void sqlite3GenerateColumnNames(
**
** Return SQLITE_OK on success. If a memory allocation error occurs,
** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM.
-**
-** The only guarantee that SQLite makes about column names is that if the
-** column has an AS clause assigning it a name, that will be the name used.
-** That is the only documented guarantee. However, countless applications
-** developed over the years have made baseless assumptions about column names
-** and will break if those assumptions changes. Hence, use extreme caution
-** when modifying this routine to avoid breaking legacy.
-**
+**
+** The only guarantee that SQLite makes about column names is that if the
+** column has an AS clause assigning it a name, that will be the name used.
+** That is the only documented guarantee. However, countless applications
+** developed over the years have made baseless assumptions about column names
+** and will break if those assumptions changes. Hence, use extreme caution
+** when modifying this routine to avoid breaking legacy.
+**
** See Also: sqlite3GenerateColumnNames()
*/
-SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
+SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
Parse *pParse, /* Parsing context */
ExprList *pEList, /* Expr list from which to derive column names */
i16 *pnCol, /* Write the number of columns here */
@@ -135332,15 +135332,15 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
){
sqlite3 *db = pParse->db; /* Database connection */
int i, j; /* Loop counters */
- u32 cnt; /* Index added to make the name unique */
+ u32 cnt; /* Index added to make the name unique */
Column *aCol, *pCol; /* For looping over result columns */
int nCol; /* Number of columns in the result set */
char *zName; /* Column name */
int nName; /* Size of name in zName[] */
- Hash ht; /* Hash table of column names */
+ Hash ht; /* Hash table of column names */
Table *pTab;
- sqlite3HashInit(&ht);
+ sqlite3HashInit(&ht);
if( pEList ){
nCol = pEList->nExpr;
aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
@@ -135350,11 +135350,11 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
nCol = 0;
aCol = 0;
}
- assert( nCol==(i16)nCol );
+ assert( nCol==(i16)nCol );
*pnCol = nCol;
*paCol = aCol;
- for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
+ for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
/* Get an appropriate name for the column
*/
if( (zName = pEList->a[i].zEName)!=0 && pEList->a[i].eEName==ENAME_NAME ){
@@ -135375,39 +135375,39 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid";
}else if( pColExpr->op==TK_ID ){
assert( !ExprHasProperty(pColExpr, EP_IntValue) );
- zName = pColExpr->u.zToken;
+ zName = pColExpr->u.zToken;
}else{
/* Use the original text of the column expression as its name */
zName = pEList->a[i].zEName;
}
}
if( zName && !sqlite3IsTrueOrFalse(zName) ){
- zName = sqlite3DbStrDup(db, zName);
- }else{
- zName = sqlite3MPrintf(db,"column%d",i+1);
+ zName = sqlite3DbStrDup(db, zName);
+ }else{
+ zName = sqlite3MPrintf(db,"column%d",i+1);
}
/* Make sure the column name is unique. If the name is not unique,
** append an integer to the name so that it becomes unique.
*/
- cnt = 0;
- while( zName && sqlite3HashFind(&ht, zName)!=0 ){
- nName = sqlite3Strlen30(zName);
- if( nName>0 ){
- for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){}
- if( zName[j]==':' ) nName = j;
+ cnt = 0;
+ while( zName && sqlite3HashFind(&ht, zName)!=0 ){
+ nName = sqlite3Strlen30(zName);
+ if( nName>0 ){
+ for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){}
+ if( zName[j]==':' ) nName = j;
}
- zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt);
- if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
+ zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt);
+ if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
}
pCol->zCnName = zName;
pCol->hName = sqlite3StrIHash(zName);
- sqlite3ColumnPropertiesFromName(0, pCol);
- if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
- sqlite3OomFault(db);
- }
+ sqlite3ColumnPropertiesFromName(0, pCol);
+ if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
+ sqlite3OomFault(db);
+ }
}
- sqlite3HashClear(&ht);
+ sqlite3HashClear(&ht);
if( db->mallocFailed ){
for(j=0; j<i; j++){
sqlite3DbFree(db, aCol[j].zCnName);
@@ -135415,7 +135415,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
sqlite3DbFree(db, aCol);
*paCol = 0;
*pnCol = 0;
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
return SQLITE_OK;
}
@@ -135431,7 +135431,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
** This routine requires that all identifiers in the SELECT
** statement be resolved.
*/
-SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
+SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
Parse *pParse, /* Parsing contexts */
Table *pTab, /* Add column type information to this table */
Select *pSelect, /* SELECT used to determine types and collations */
@@ -135453,24 +135453,24 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
sNC.pSrcList = pSelect->pSrc;
a = pSelect->pEList->a;
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
- const char *zType;
+ const char *zType;
i64 n, m;
pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT);
p = a[i].pExpr;
- zType = columnType(&sNC, p, 0, 0, 0);
- /* pCol->szEst = ... // Column size est for SELECT tables never used */
- pCol->affinity = sqlite3ExprAffinity(p);
- if( zType ){
- m = sqlite3Strlen30(zType);
+ zType = columnType(&sNC, p, 0, 0, 0);
+ /* pCol->szEst = ... // Column size est for SELECT tables never used */
+ pCol->affinity = sqlite3ExprAffinity(p);
+ if( zType ){
+ m = sqlite3Strlen30(zType);
n = sqlite3Strlen30(pCol->zCnName);
pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
if( pCol->zCnName ){
memcpy(&pCol->zCnName[n+1], zType, m+1);
- pCol->colFlags |= COLFLAG_HASTYPE;
+ pCol->colFlags |= COLFLAG_HASTYPE;
}else{
testcase( pCol->colFlags & COLFLAG_HASTYPE );
pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
- }
+ }
}
if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
pColl = sqlite3ExprCollSeq(pParse, p);
@@ -135479,7 +135479,7 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
sqlite3ColumnSetColl(db, pCol, pColl->zName);
}
}
- pTab->szTabRow = 1; /* Any non-zero value works */
+ pTab->szTabRow = 1; /* Any non-zero value works */
}
/*
@@ -135502,10 +135502,10 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, c
if( pTab==0 ){
return 0;
}
- pTab->nTabRef = 1;
+ pTab->nTabRef = 1;
pTab->zName = 0;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
- sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
+ sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect, aff);
pTab->iPKey = -1;
if( db->mallocFailed ){
@@ -135520,21 +135520,21 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, c
** If an error occurs, return NULL and leave a message in pParse.
*/
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
- if( pParse->pVdbe ){
- return pParse->pVdbe;
+ if( pParse->pVdbe ){
+ return pParse->pVdbe;
}
- if( pParse->pToplevel==0
- && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
- ){
- pParse->okConstFactor = 1;
- }
- return sqlite3VdbeCreate(pParse);
+ if( pParse->pToplevel==0
+ && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
+ ){
+ pParse->okConstFactor = 1;
+ }
+ return sqlite3VdbeCreate(pParse);
}
/*
** Compute the iLimit and iOffset fields of the SELECT based on the
-** pLimit expressions. pLimit->pLeft and pLimit->pRight hold the expressions
+** pLimit expressions. pLimit->pLeft and pLimit->pRight hold the expressions
** that appear in the original SQL statement after the LIMIT and OFFSET
** keywords. Or NULL if those keywords are omitted. iLimit and iOffset
** are the integer memory register numbers for counters used to compute
@@ -135542,15 +135542,15 @@ SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
** iLimit and iOffset are negative.
**
** This routine changes the values of iLimit and iOffset only if
-** a limit or offset is defined by pLimit->pLeft and pLimit->pRight. iLimit
-** and iOffset should have been preset to appropriate default values (zero)
+** a limit or offset is defined by pLimit->pLeft and pLimit->pRight. iLimit
+** and iOffset should have been preset to appropriate default values (zero)
** prior to calling this routine.
**
** The iOffset register (if it exists) is initialized to the value
** of the OFFSET. The iLimit register is initialized to LIMIT. Register
** iOffset+1 is initialized to LIMIT+OFFSET.
**
-** Only if pLimit->pLeft!=0 do the limit registers get
+** Only if pLimit->pLeft!=0 do the limit registers get
** redefined. The UNION ALL operator uses this property to force
** the reuse of the same limit and offset registers across multiple
** SELECT statements.
@@ -135559,9 +135559,9 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
Vdbe *v = 0;
int iLimit = 0;
int iOffset;
- int n;
- Expr *pLimit = p->pLimit;
-
+ int n;
+ Expr *pLimit = p->pLimit;
+
if( p->iLimit ) return;
/*
@@ -135570,34 +135570,34 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
** The current implementation interprets "LIMIT 0" to mean
** no rows.
*/
- if( pLimit ){
- assert( pLimit->op==TK_LIMIT );
- assert( pLimit->pLeft!=0 );
+ if( pLimit ){
+ assert( pLimit->op==TK_LIMIT );
+ assert( pLimit->pLeft!=0 );
p->iLimit = iLimit = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
- if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){
+ if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){
sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
VdbeComment((v, "LIMIT counter"));
if( n==0 ){
- sqlite3VdbeGoto(v, iBreak);
- }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){
- p->nSelectRow = sqlite3LogEst((u64)n);
- p->selFlags |= SF_FixedLimit;
+ sqlite3VdbeGoto(v, iBreak);
+ }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){
+ p->nSelectRow = sqlite3LogEst((u64)n);
+ p->selFlags |= SF_FixedLimit;
}
}else{
- sqlite3ExprCode(pParse, pLimit->pLeft, iLimit);
+ sqlite3ExprCode(pParse, pLimit->pLeft, iLimit);
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
VdbeComment((v, "LIMIT counter"));
sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v);
}
- if( pLimit->pRight ){
+ if( pLimit->pRight ){
p->iOffset = iOffset = ++pParse->nMem;
pParse->nMem++; /* Allocate an extra register for limit+offset */
- sqlite3ExprCode(pParse, pLimit->pRight, iOffset);
+ sqlite3ExprCode(pParse, pLimit->pRight, iOffset);
sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
VdbeComment((v, "OFFSET counter"));
- sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
+ sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
VdbeComment((v, "LIMIT+OFFSET"));
}
}
@@ -135678,7 +135678,7 @@ static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
**
**
** There is exactly one reference to the recursive-table in the FROM clause
-** of recursive-query, marked with the SrcList->a[].fg.isRecursive flag.
+** of recursive-query, marked with the SrcList->a[].fg.isRecursive flag.
**
** The setup-query runs once to generate an initial set of rows that go
** into a Queue table. Rows are extracted from the Queue table one by
@@ -135725,7 +135725,7 @@ static void generateWithRecursiveQuery(
int i; /* Loop counter */
int rc; /* Result code */
ExprList *pOrderBy; /* The ORDER BY clause */
- Expr *pLimit; /* Saved LIMIT and OFFSET */
+ Expr *pLimit; /* Saved LIMIT and OFFSET */
int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -135740,18 +135740,18 @@ static void generateWithRecursiveQuery(
/* Process the LIMIT and OFFSET clauses, if they exist */
addrBreak = sqlite3VdbeMakeLabel(pParse);
- p->nSelectRow = 320; /* 4 billion rows */
+ p->nSelectRow = 320; /* 4 billion rows */
computeLimitRegisters(pParse, p, addrBreak);
pLimit = p->pLimit;
regLimit = p->iLimit;
regOffset = p->iOffset;
- p->pLimit = 0;
+ p->pLimit = 0;
p->iLimit = p->iOffset = 0;
pOrderBy = p->pOrderBy;
/* Locate the cursor number of the Current table */
for(i=0; ALWAYS(i<pSrc->nSrc); i++){
- if( pSrc->a[i].fg.isRecursive ){
+ if( pSrc->a[i].fg.isRecursive ){
iCurrent = pSrc->a[i].iCursor;
break;
}
@@ -135828,7 +135828,7 @@ static void generateWithRecursiveQuery(
/* Output the single row in Current */
addrCont = sqlite3VdbeMakeLabel(pParse);
codeOffset(v, regOffset, addrCont);
- selectInnerLoop(pParse, p, iCurrent,
+ selectInnerLoop(pParse, p, iCurrent,
0, 0, pDest, addrCont, addrBreak);
if( regLimit ){
sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak);
@@ -135846,7 +135846,7 @@ static void generateWithRecursiveQuery(
pFirstRec->pPrior = pSetup;
/* Keep running the loop until the Queue is empty */
- sqlite3VdbeGoto(v, addrTop);
+ sqlite3VdbeGoto(v, addrTop);
sqlite3VdbeResolveLabel(v, addrBreak);
end_of_recursive_query:
@@ -135871,14 +135871,14 @@ static int multiSelectOrderBy(
** on a VALUES clause.
**
** Because the Select object originates from a VALUES clause:
-** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1
+** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1
** (2) All terms are UNION ALL
** (3) There is no ORDER BY clause
-**
-** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
-** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
-** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
-** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
+**
+** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
+** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
+** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
+** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
*/
static int multiSelectValues(
Parse *pParse, /* Parsing context */
@@ -136095,7 +136095,7 @@ static int multiSelect(
p->addrOpenEphm[0] = addr;
findRightmost(p)->selFlags |= SF_UsesEphemeral;
assert( p->pEList );
- }
+ }
/* Code the SELECT statements to our left
@@ -136265,7 +136265,7 @@ static int multiSelect(
nCol = p->pEList->nExpr;
pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
if( !pKeyInfo ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto multi_select_end;
}
for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
@@ -136359,12 +136359,12 @@ static int generateOutputSubroutine(
/* Suppress duplicates for UNION, EXCEPT, and INTERSECT
*/
if( regPrev ){
- int addr1, addr2;
- addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
- addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
+ int addr1, addr2;
+ addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
+ addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
- sqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v);
- sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
}
@@ -136392,16 +136392,16 @@ static int generateOutputSubroutine(
}
#ifndef SQLITE_OMIT_SUBQUERY
- /* If we are creating a set for an "expr IN (SELECT ...)".
+ /* If we are creating a set for an "expr IN (SELECT ...)".
*/
case SRT_Set: {
int r1;
- testcase( pIn->nSdst>1 );
+ testcase( pIn->nSdst>1 );
r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst,
- r1, pDest->zAffSdst, pIn->nSdst);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1,
- pIn->iSdst, pIn->nSdst);
+ r1, pDest->zAffSdst, pIn->nSdst);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1,
+ pIn->iSdst, pIn->nSdst);
sqlite3ReleaseTempReg(pParse, r1);
break;
}
@@ -136578,7 +136578,7 @@ static int multiSelectOrderBy(
int savedOffset; /* Saved value of p->iOffset */
int labelCmpr; /* Label for the start of the merge algorithm */
int labelEnd; /* Label for the end of the overall SELECT stmt */
- int addr1; /* Jump instructions that get retargetted */
+ int addr1; /* Jump instructions that get retargetted */
int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */
KeyInfo *pKeyMerge; /* Comparison information for merging rows */
@@ -136619,10 +136619,10 @@ static int multiSelectOrderBy(
}
if( j==nOrderBy ){
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
- if( pNew==0 ) return SQLITE_NOMEM_BKPT;
+ if( pNew==0 ) return SQLITE_NOMEM_BKPT;
pNew->flags |= EP_IntValue;
pNew->u.iValue = i;
- p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
+ p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
}
}
@@ -136638,8 +136638,8 @@ static int multiSelectOrderBy(
aPermute = sqlite3DbMallocRawNN(db, sizeof(u32)*(nOrderBy + 1));
if( aPermute ){
struct ExprList_item *pItem;
- aPermute[0] = nOrderBy;
- for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){
+ aPermute[0] = nOrderBy;
+ for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){
assert( pItem!=0 );
assert( pItem->u.x.iOrderByCol>0 );
assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
@@ -136713,19 +136713,19 @@ static int multiSelectOrderBy(
** left of the compound operator - the "A" select.
*/
addrSelectA = sqlite3VdbeCurrentAddr(v) + 1;
- addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
+ addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
VdbeComment((v, "left SELECT"));
pPrior->iLimit = regLimitA;
ExplainQueryPlan((pParse, 1, "LEFT"));
sqlite3Select(pParse, pPrior, &destA);
- sqlite3VdbeEndCoroutine(v, regAddrA);
- sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeEndCoroutine(v, regAddrA);
+ sqlite3VdbeJumpHere(v, addr1);
/* Generate a coroutine to evaluate the SELECT statement on
** the right - the "B" select
*/
addrSelectB = sqlite3VdbeCurrentAddr(v) + 1;
- addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
+ addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
VdbeComment((v, "right SELECT"));
savedLimit = p->iLimit;
savedOffset = p->iOffset;
@@ -136735,7 +136735,7 @@ static int multiSelectOrderBy(
sqlite3Select(pParse, p, &destB);
p->iLimit = savedLimit;
p->iOffset = savedOffset;
- sqlite3VdbeEndCoroutine(v, regAddrB);
+ sqlite3VdbeEndCoroutine(v, regAddrB);
/* Generate a subroutine that outputs the current row of the A
** select as the next output row of the compound select.
@@ -136766,8 +136766,8 @@ static int multiSelectOrderBy(
addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
VdbeCoverage(v);
- sqlite3VdbeGoto(v, addrEofA);
- p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+ sqlite3VdbeGoto(v, addrEofA);
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
}
/* Generate a subroutine to run when the results from select B
@@ -136780,7 +136780,7 @@ static int multiSelectOrderBy(
VdbeNoopComment((v, "eof-B subroutine"));
addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v);
- sqlite3VdbeGoto(v, addrEofB);
+ sqlite3VdbeGoto(v, addrEofB);
}
/* Generate code to handle the case of A<B
@@ -136788,7 +136788,7 @@ static int multiSelectOrderBy(
VdbeNoopComment((v, "A-lt-B subroutine"));
addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
- sqlite3VdbeGoto(v, labelCmpr);
+ sqlite3VdbeGoto(v, labelCmpr);
/* Generate code to handle the case of A==B
*/
@@ -136801,7 +136801,7 @@ static int multiSelectOrderBy(
VdbeNoopComment((v, "A-eq-B subroutine"));
addrAeqB =
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
- sqlite3VdbeGoto(v, labelCmpr);
+ sqlite3VdbeGoto(v, labelCmpr);
}
/* Generate code to handle the case of A>B
@@ -136812,11 +136812,11 @@ static int multiSelectOrderBy(
sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
}
sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
- sqlite3VdbeGoto(v, labelCmpr);
+ sqlite3VdbeGoto(v, labelCmpr);
/* This code runs once to initialize everything.
*/
- sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
@@ -136852,24 +136852,24 @@ static int multiSelectOrderBy(
#endif
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
-
-/* An instance of the SubstContext object describes an substitution edit
-** to be performed on a parse tree.
-**
-** All references to columns in table iTable are to be replaced by corresponding
-** expressions in pEList.
-*/
-typedef struct SubstContext {
- Parse *pParse; /* The parsing context */
- int iTable; /* Replace references to this table */
- int iNewTable; /* New table number */
- int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
- ExprList *pEList; /* Replacement expressions */
-} SubstContext;
-
+
+/* An instance of the SubstContext object describes an substitution edit
+** to be performed on a parse tree.
+**
+** All references to columns in table iTable are to be replaced by corresponding
+** expressions in pEList.
+*/
+typedef struct SubstContext {
+ Parse *pParse; /* The parsing context */
+ int iTable; /* Replace references to this table */
+ int iNewTable; /* New table number */
+ int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
+ ExprList *pEList; /* Replacement expressions */
+} SubstContext;
+
/* Forward Declarations */
-static void substExprList(SubstContext*, ExprList*);
-static void substSelect(SubstContext*, Select*, int);
+static void substExprList(SubstContext*, ExprList*);
+static void substSelect(SubstContext*, Select*, int);
/*
** Scan through the expression pExpr. Replace every reference to
@@ -136885,15 +136885,15 @@ static void substSelect(SubstContext*, Select*, int);
** of the subquery rather the result set of the subquery.
*/
static Expr *substExpr(
- SubstContext *pSubst, /* Description of the substitution */
- Expr *pExpr /* Expr in which substitution occurs */
+ SubstContext *pSubst, /* Description of the substitution */
+ Expr *pExpr /* Expr in which substitution occurs */
){
if( pExpr==0 ) return 0;
- if( ExprHasProperty(pExpr, EP_FromJoin)
- && pExpr->iRightJoinTable==pSubst->iTable
- ){
- pExpr->iRightJoinTable = pSubst->iNewTable;
- }
+ if( ExprHasProperty(pExpr, EP_FromJoin)
+ && pExpr->iRightJoinTable==pSubst->iTable
+ ){
+ pExpr->iRightJoinTable = pSubst->iNewTable;
+ }
if( pExpr->op==TK_COLUMN
&& pExpr->iTable==pSubst->iTable
&& !ExprHasProperty(pExpr, EP_FixedCol)
@@ -136905,36 +136905,36 @@ static Expr *substExpr(
#endif
{
Expr *pNew;
- Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr;
- Expr ifNullRow;
- assert( pSubst->pEList!=0 && pExpr->iColumn<pSubst->pEList->nExpr );
+ Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr;
+ Expr ifNullRow;
+ assert( pSubst->pEList!=0 && pExpr->iColumn<pSubst->pEList->nExpr );
assert( pExpr->pRight==0 );
- if( sqlite3ExprIsVector(pCopy) ){
- sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
- }else{
- sqlite3 *db = pSubst->pParse->db;
- if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
- memset(&ifNullRow, 0, sizeof(ifNullRow));
- ifNullRow.op = TK_IF_NULL_ROW;
- ifNullRow.pLeft = pCopy;
- ifNullRow.iTable = pSubst->iNewTable;
+ if( sqlite3ExprIsVector(pCopy) ){
+ sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
+ }else{
+ sqlite3 *db = pSubst->pParse->db;
+ if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
+ memset(&ifNullRow, 0, sizeof(ifNullRow));
+ ifNullRow.op = TK_IF_NULL_ROW;
+ ifNullRow.pLeft = pCopy;
+ ifNullRow.iTable = pSubst->iNewTable;
ifNullRow.flags = EP_IfNullRow;
- pCopy = &ifNullRow;
- }
+ pCopy = &ifNullRow;
+ }
testcase( ExprHasProperty(pCopy, EP_Subquery) );
- pNew = sqlite3ExprDup(db, pCopy, 0);
+ pNew = sqlite3ExprDup(db, pCopy, 0);
if( db->mallocFailed ){
sqlite3ExprDelete(db, pNew);
return pExpr;
}
if( pSubst->isLeftJoin ){
- ExprSetProperty(pNew, EP_CanBeNull);
- }
+ ExprSetProperty(pNew, EP_CanBeNull);
+ }
if( ExprHasProperty(pExpr,EP_FromJoin) ){
sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable);
- }
- sqlite3ExprDelete(db, pExpr);
- pExpr = pNew;
+ }
+ sqlite3ExprDelete(db, pExpr);
+ pExpr = pNew;
/* Ensure that the expression now has an implicit collation sequence,
** just as it did when it was a column of a view or sub-query. */
@@ -136945,18 +136945,18 @@ static Expr *substExpr(
);
}
ExprClearProperty(pExpr, EP_Collate);
- }
+ }
}
}else{
- if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
- pExpr->iTable = pSubst->iNewTable;
- }
- pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
- pExpr->pRight = substExpr(pSubst, pExpr->pRight);
+ if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
+ pExpr->iTable = pSubst->iNewTable;
+ }
+ pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
+ pExpr->pRight = substExpr(pSubst, pExpr->pRight);
if( ExprUseXSelect(pExpr) ){
- substSelect(pSubst, pExpr->x.pSelect, 1);
+ substSelect(pSubst, pExpr->x.pSelect, 1);
}else{
- substExprList(pSubst, pExpr->x.pList);
+ substExprList(pSubst, pExpr->x.pList);
}
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(pExpr, EP_WinFunc) ){
@@ -136970,39 +136970,39 @@ static Expr *substExpr(
return pExpr;
}
static void substExprList(
- SubstContext *pSubst, /* Description of the substitution */
- ExprList *pList /* List to scan and in which to make substitutes */
+ SubstContext *pSubst, /* Description of the substitution */
+ ExprList *pList /* List to scan and in which to make substitutes */
){
int i;
if( pList==0 ) return;
for(i=0; i<pList->nExpr; i++){
- pList->a[i].pExpr = substExpr(pSubst, pList->a[i].pExpr);
+ pList->a[i].pExpr = substExpr(pSubst, pList->a[i].pExpr);
}
}
static void substSelect(
- SubstContext *pSubst, /* Description of the substitution */
- Select *p, /* SELECT statement in which to make substitutions */
- int doPrior /* Do substitutes on p->pPrior too */
+ SubstContext *pSubst, /* Description of the substitution */
+ Select *p, /* SELECT statement in which to make substitutions */
+ int doPrior /* Do substitutes on p->pPrior too */
){
SrcList *pSrc;
SrcItem *pItem;
int i;
if( !p ) return;
- do{
- substExprList(pSubst, p->pEList);
- substExprList(pSubst, p->pGroupBy);
- substExprList(pSubst, p->pOrderBy);
- p->pHaving = substExpr(pSubst, p->pHaving);
- p->pWhere = substExpr(pSubst, p->pWhere);
- pSrc = p->pSrc;
- assert( pSrc!=0 );
+ do{
+ substExprList(pSubst, p->pEList);
+ substExprList(pSubst, p->pGroupBy);
+ substExprList(pSubst, p->pOrderBy);
+ p->pHaving = substExpr(pSubst, p->pHaving);
+ p->pWhere = substExpr(pSubst, p->pWhere);
+ pSrc = p->pSrc;
+ assert( pSrc!=0 );
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- substSelect(pSubst, pItem->pSelect, 1);
- if( pItem->fg.isTabFunc ){
- substExprList(pSubst, pItem->u1.pFuncArg);
- }
+ substSelect(pSubst, pItem->pSelect, 1);
+ if( pItem->fg.isTabFunc ){
+ substExprList(pSubst, pItem->u1.pFuncArg);
+ }
}
- }while( doPrior && (p = p->pPrior)!=0 );
+ }while( doPrior && (p = p->pPrior)!=0 );
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
@@ -137162,73 +137162,73 @@ static void renumberCursors(
** exist on the table t1, a complete scan of the data might be
** avoided.
**
-** Flattening is subject to the following constraints:
+** Flattening is subject to the following constraints:
**
-** (**) We no longer attempt to flatten aggregate subqueries. Was:
-** The subquery and the outer query cannot both be aggregates.
+** (**) We no longer attempt to flatten aggregate subqueries. Was:
+** The subquery and the outer query cannot both be aggregates.
**
-** (**) We no longer attempt to flatten aggregate subqueries. Was:
-** (2) If the subquery is an aggregate then
-** (2a) the outer query must not be a join and
-** (2b) the outer query must not use subqueries
-** other than the one FROM-clause subquery that is a candidate
-** for flattening. (This is due to ticket [2f7170d73bf9abf80]
-** from 2015-02-09.)
+** (**) We no longer attempt to flatten aggregate subqueries. Was:
+** (2) If the subquery is an aggregate then
+** (2a) the outer query must not be a join and
+** (2b) the outer query must not use subqueries
+** other than the one FROM-clause subquery that is a candidate
+** for flattening. (This is due to ticket [2f7170d73bf9abf80]
+** from 2015-02-09.)
**
-** (3) If the subquery is the right operand of a LEFT JOIN then
-** (3a) the subquery may not be a join and
-** (3b) the FROM clause of the subquery may not contain a virtual
-** table and
-** (3c) the outer query may not be an aggregate.
+** (3) If the subquery is the right operand of a LEFT JOIN then
+** (3a) the subquery may not be a join and
+** (3b) the FROM clause of the subquery may not contain a virtual
+** table and
+** (3c) the outer query may not be an aggregate.
** (3d) the outer query may not be DISTINCT.
**
-** (4) The subquery can not be DISTINCT.
+** (4) The subquery can not be DISTINCT.
**
** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT
** sub-queries that were excluded from this optimization. Restriction
** (4) has since been expanded to exclude all DISTINCT subqueries.
**
-** (**) We no longer attempt to flatten aggregate subqueries. Was:
-** If the subquery is aggregate, the outer query may not be DISTINCT.
+** (**) We no longer attempt to flatten aggregate subqueries. Was:
+** If the subquery is aggregate, the outer query may not be DISTINCT.
**
-** (7) The subquery must have a FROM clause. TODO: For subqueries without
-** A FROM clause, consider adding a FROM clause with the special
+** (7) The subquery must have a FROM clause. TODO: For subqueries without
+** A FROM clause, consider adding a FROM clause with the special
** table sqlite_once that consists of a single row containing a
** single NULL.
**
-** (8) If the subquery uses LIMIT then the outer query may not be a join.
+** (8) If the subquery uses LIMIT then the outer query may not be a join.
**
-** (9) If the subquery uses LIMIT then the outer query may not be aggregate.
+** (9) If the subquery uses LIMIT then the outer query may not be aggregate.
**
** (**) Restriction (10) was removed from the code on 2005-02-05 but we
** accidently carried the comment forward until 2014-09-15. Original
** constraint: "If the subquery is aggregate then the outer query
-** may not use LIMIT."
+** may not use LIMIT."
**
-** (11) The subquery and the outer query may not both have ORDER BY clauses.
+** (11) The subquery and the outer query may not both have ORDER BY clauses.
**
** (**) Not implemented. Subsumed into restriction (3). Was previously
** a separate restriction deriving from ticket #350.
**
-** (13) The subquery and outer query may not both use LIMIT.
+** (13) The subquery and outer query may not both use LIMIT.
**
-** (14) The subquery may not use OFFSET.
+** (14) The subquery may not use OFFSET.
**
-** (15) If the outer query is part of a compound select, then the
-** subquery may not use LIMIT.
+** (15) If the outer query is part of a compound select, then the
+** subquery may not use LIMIT.
** (See ticket #2339 and ticket [02a8e81d44]).
**
-** (16) If the outer query is aggregate, then the subquery may not
-** use ORDER BY. (Ticket #2942) This used to not matter
+** (16) If the outer query is aggregate, then the subquery may not
+** use ORDER BY. (Ticket #2942) This used to not matter
** until we introduced the group_concat() function.
**
-** (17) If the subquery is a compound select, then
-** (17a) all compound operators must be a UNION ALL, and
-** (17b) no terms within the subquery compound may be aggregate
-** or DISTINCT, and
-** (17c) every term within the subquery compound must have a FROM clause
-** (17d) the outer query may not be
-** (17d1) aggregate, or
+** (17) If the subquery is a compound select, then
+** (17a) all compound operators must be a UNION ALL, and
+** (17b) no terms within the subquery compound may be aggregate
+** or DISTINCT, and
+** (17c) every term within the subquery compound must have a FROM clause
+** (17d) the outer query may not be
+** (17d1) aggregate, or
** (17d2) DISTINCT
** (17e) the subquery may not contain window functions, and
** (17f) the subquery must not be the RHS of a LEFT JOIN.
@@ -137250,7 +137250,7 @@ static void renumberCursors(
** ORDER BY clause of the parent must be copies of a term returned
** by the parent query.
**
-** (19) If the subquery uses LIMIT then the outer query may not
+** (19) If the subquery uses LIMIT then the outer query may not
** have a WHERE clause.
**
** (20) If the sub-query is a compound select, then it must not use
@@ -137259,17 +137259,17 @@ static void renumberCursors(
** appear as unmodified result columns in the outer query. But we
** have other optimizations in mind to deal with that case.
**
-** (21) If the subquery uses LIMIT then the outer query may not be
+** (21) If the subquery uses LIMIT then the outer query may not be
** DISTINCT. (See ticket [752e1646fc]).
**
-** (22) The subquery may not be a recursive CTE.
+** (22) The subquery may not be a recursive CTE.
**
** (23) If the outer query is a recursive CTE, then the sub-query may not be
** a compound query. This restriction is because transforming the
** parent to a compound query confuses the code that handles
** recursive queries in multiSelect().
**
-** (**) We no longer attempt to flatten aggregate subqueries. Was:
+** (**) We no longer attempt to flatten aggregate subqueries. Was:
** The subquery may not be an aggregate that uses the built-in min() or
** or max() functions. (Without this restriction, a query like:
** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
@@ -137282,7 +137282,7 @@ static void renumberCursors(
**
** 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.
+** uses aggregates.
**
** If flattening is not attempted, this routine is a no-op and returns 0.
** If flattening is attempted this routine returns 1.
@@ -137294,16 +137294,16 @@ static int flattenSubquery(
Parse *pParse, /* Parsing context */
Select *p, /* The parent or outer SELECT statement */
int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
- int isAgg /* True if outer SELECT uses aggregate functions */
+ int isAgg /* True if outer SELECT uses aggregate functions */
){
const char *zSavedAuthContext = pParse->zAuthContext;
- Select *pParent; /* Current UNION ALL term of the other query */
+ Select *pParent; /* Current UNION ALL term of the other query */
Select *pSub; /* The inner query or "subquery" */
Select *pSub1; /* Pointer to the rightmost select in sub-query */
SrcList *pSrc; /* The FROM clause of the outer query */
SrcList *pSubSrc; /* The FROM clause of the subquery */
int iParent; /* VDBE cursor number of the pSub result set temp table */
- int iNewParent = -1;/* Replacement table for iParent */
+ int iNewParent = -1;/* Replacement table for iParent */
int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */
int i; /* Loop counter */
Expr *pWhere; /* The WHERE clause */
@@ -137315,7 +137315,7 @@ static int flattenSubquery(
/* Check to see if flattening is permitted. Return 0 if not.
*/
assert( p!=0 );
- assert( p->pPrior==0 );
+ assert( p->pPrior==0 );
if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
pSrc = p->pSrc;
assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
@@ -137323,7 +137323,7 @@ static int flattenSubquery(
iParent = pSubitem->iCursor;
pSub = pSubitem->pSelect;
assert( pSub!=0 );
-
+
#ifndef SQLITE_OMIT_WINDOWFUNC
if( p->pWin || pSub->pWin ) return 0; /* Restriction (25) */
#endif
@@ -137336,12 +137336,12 @@ static int flattenSubquery(
** became arbitrary expressions, we were forced to add restrictions (13)
** and (14). */
if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */
- if( pSub->pLimit && pSub->pLimit->pRight ) return 0; /* Restriction (14) */
+ if( pSub->pLimit && pSub->pLimit->pRight ) return 0; /* Restriction (14) */
if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){
return 0; /* Restriction (15) */
}
if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */
- if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (4) */
+ if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (4) */
if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){
return 0; /* Restrictions (8)(9) */
}
@@ -137353,14 +137353,14 @@ static int flattenSubquery(
if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
return 0; /* Restriction (21) */
}
- if( pSub->selFlags & (SF_Recursive) ){
- return 0; /* Restrictions (22) */
+ if( pSub->selFlags & (SF_Recursive) ){
+ return 0; /* Restrictions (22) */
}
- /*
- ** If the subquery is the right operand of a LEFT JOIN, then the
- ** subquery may not be a join itself (3a). Example of why this is not
- ** allowed:
+ /*
+ ** If the subquery is the right operand of a LEFT JOIN, then the
+ ** subquery may not be a join itself (3a). Example of why this is not
+ ** allowed:
**
** t1 LEFT OUTER JOIN (t2 JOIN t3)
**
@@ -137370,41 +137370,41 @@ static int flattenSubquery(
**
** which is not at all the same thing.
**
- ** If the subquery is the right operand of a LEFT JOIN, then the outer
- ** query cannot be an aggregate. (3c) This is an artifact of the way
- ** aggregates are processed - there is no mechanism to determine if
- ** the LEFT JOIN table should be all-NULL.
+ ** If the subquery is the right operand of a LEFT JOIN, then the outer
+ ** query cannot be an aggregate. (3c) This is an artifact of the way
+ ** aggregates are processed - there is no mechanism to determine if
+ ** the LEFT JOIN table should be all-NULL.
**
- ** See also tickets #306, #350, and #3300.
+ ** See also tickets #306, #350, and #3300.
*/
- if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
- isLeftJoin = 1;
+ if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
+ isLeftJoin = 1;
if( pSubSrc->nSrc>1 /* (3a) */
|| isAgg /* (3b) */
|| IsVirtual(pSubSrc->a[0].pTab) /* (3c) */
|| (p->selFlags & SF_Distinct)!=0 /* (3d) */
){
- return 0;
- }
+ return 0;
+ }
}
-#ifdef SQLITE_EXTRA_IFNULLROW
- else if( iFrom>0 && !isAgg ){
- /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
- ** every reference to any result column from subquery in a join, even
+#ifdef SQLITE_EXTRA_IFNULLROW
+ else if( iFrom>0 && !isAgg ){
+ /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
+ ** every reference to any result column from subquery in a join, even
** though they are not necessary. This will stress-test the OP_IfNullRow
- ** opcode. */
- isLeftJoin = -1;
- }
-#endif
+ ** opcode. */
+ isLeftJoin = -1;
+ }
+#endif
- /* Restriction (17): If the sub-query is a compound SELECT, then it must
+ /* Restriction (17): If the sub-query is a compound SELECT, then it must
** use only the UNION ALL operator. And none of the simple select queries
** that make up the compound SELECT are allowed to be aggregate or distinct
** queries.
*/
if( pSub->pPrior ){
if( pSub->pOrderBy ){
- return 0; /* Restriction (20) */
+ return 0; /* Restriction (20) */
}
if( isAgg || (p->selFlags & SF_Distinct)!=0 || isLeftJoin>0 ){
return 0; /* (17d1), (17d2), or (17f) */
@@ -137415,9 +137415,9 @@ static int flattenSubquery(
assert( pSub->pSrc!=0 );
assert( (pSub->selFlags & SF_Recursive)==0 );
assert( pSub->pEList->nExpr==pSub1->pEList->nExpr );
- if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */
- || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */
- || pSub1->pSrc->nSrc<1 /* (17c) */
+ if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */
+ || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */
+ || pSub1->pSrc->nSrc<1 /* (17c) */
#ifndef SQLITE_OMIT_WINDOWFUNC
|| pSub1->pWin /* (17e) */
#endif
@@ -137427,7 +137427,7 @@ static int flattenSubquery(
testcase( pSub1->pSrc->nSrc>1 );
}
- /* Restriction (18). */
+ /* Restriction (18). */
if( p->pOrderBy ){
int ii;
for(ii=0; ii<p->pOrderBy->nExpr; ii++){
@@ -137545,14 +137545,14 @@ static int flattenSubquery(
*/
if( ALWAYS(pSubitem->pTab!=0) ){
Table *pTabToDel = pSubitem->pTab;
- if( pTabToDel->nTabRef==1 ){
+ if( pTabToDel->nTabRef==1 ){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
sqlite3ParserAddCleanup(pToplevel,
(void(*)(sqlite3*,void*))sqlite3DeleteTable,
pTabToDel);
testcase( pToplevel->earlyCleanup );
}else{
- pTabToDel->nTabRef--;
+ pTabToDel->nTabRef--;
}
pSubitem->pTab = 0;
}
@@ -137594,9 +137594,9 @@ static int flattenSubquery(
**
** The outer query has 3 slots in its FROM clause. One slot of the
** outer query (the middle slot) is used by the subquery. The next
- ** block of code will expand the outer query FROM clause to 4 slots.
- ** The middle slot is expanded to two slots in order to make space
- ** for the two elements in the FROM clause of the subquery.
+ ** block of code will expand the outer query FROM clause to 4 slots.
+ ** The middle slot is expanded to two slots in order to make space
+ ** for the two elements in the FROM clause of the subquery.
*/
if( nSubSrc>1 ){
pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1);
@@ -137609,12 +137609,12 @@ static int flattenSubquery(
*/
for(i=0; i<nSubSrc; i++){
sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
- assert( pSrc->a[i+iFrom].fg.isTabFunc==0 );
+ assert( pSrc->a[i+iFrom].fg.isTabFunc==0 );
pSrc->a[i+iFrom] = pSubSrc->a[i];
- iNewParent = pSubSrc->a[i].iCursor;
+ iNewParent = pSubSrc->a[i].iCursor;
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
}
- pSrc->a[iFrom].fg.jointype = jointype;
+ pSrc->a[iFrom].fg.jointype = jointype;
/* Now begin substituting subquery result set expressions for
** references to the iParent in the outer query.
@@ -137649,7 +137649,7 @@ static int flattenSubquery(
}
pWhere = pSub->pWhere;
pSub->pWhere = 0;
- if( isLeftJoin>0 ){
+ if( isLeftJoin>0 ){
sqlite3SetJoinExpr(pWhere, iNewParent);
}
if( pWhere ){
@@ -137659,14 +137659,14 @@ static int flattenSubquery(
pParent->pWhere = pWhere;
}
}
- if( db->mallocFailed==0 ){
- SubstContext x;
- x.pParse = pParse;
- x.iTable = iParent;
- x.iNewTable = iNewParent;
- x.isLeftJoin = isLeftJoin;
- x.pEList = pSub->pEList;
- substSelect(&x, pParent, 0);
+ if( db->mallocFailed==0 ){
+ SubstContext x;
+ x.pParse = pParse;
+ x.iTable = iParent;
+ x.iNewTable = iNewParent;
+ x.isLeftJoin = isLeftJoin;
+ x.pEList = pSub->pEList;
+ substSelect(&x, pParent, 0);
}
/* The flattened query is a compound if either the inner or the
@@ -138008,13 +138008,13 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
**
** Do not attempt this optimization if:
**
-** (1) (** This restriction was removed on 2017-09-29. We used to
-** disallow this optimization for aggregate subqueries, but now
-** it is allowed by putting the extra terms on the HAVING clause.
-** The added HAVING clause is pointless if the subquery lacks
-** a GROUP BY clause. But such a HAVING clause is also harmless
-** so there does not appear to be any reason to add extra logic
-** to suppress it. **)
+** (1) (** This restriction was removed on 2017-09-29. We used to
+** disallow this optimization for aggregate subqueries, but now
+** it is allowed by putting the extra terms on the HAVING clause.
+** The added HAVING clause is pointless if the subquery lacks
+** a GROUP BY clause. But such a HAVING clause is also harmless
+** so there does not appear to be any reason to add extra logic
+** to suppress it. **)
**
** (2) The inner query is the recursive part of a common table expression.
**
@@ -138025,10 +138025,10 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
** expression to be pushed down does not come from the ON clause
** on that LEFT JOIN.
**
-** (5) The WHERE clause expression originates in the ON or USING clause
+** (5) The WHERE clause expression originates in the ON or USING clause
** of a LEFT JOIN where iCursor is not the right-hand table of that
** left join. An example:
-**
+**
** SELECT *
** FROM (SELECT 1 AS a1 UNION ALL SELECT 2) AS aa
** JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2)
@@ -138061,7 +138061,7 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
** terms are duplicated into the subquery.
*/
static int pushDownWhereTerms(
- Parse *pParse, /* Parse context (for malloc() and error reporting) */
+ Parse *pParse, /* Parse context (for malloc() and error reporting) */
Select *pSubq, /* The subquery whose WHERE clause is to be augmented */
Expr *pWhere, /* The WHERE clause of the outer query */
int iCursor, /* Cursor number of the subquery */
@@ -138071,7 +138071,7 @@ static int pushDownWhereTerms(
int nChng = 0;
if( pWhere==0 ) return 0;
if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0;
-
+
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pSubq->pPrior ){
Select *pSel;
@@ -138083,21 +138083,21 @@ static int pushDownWhereTerms(
}
#endif
-#ifdef SQLITE_DEBUG
- /* Only the first term of a compound can have a WITH clause. But make
- ** sure no other terms are marked SF_Recursive in case something changes
- ** in the future.
- */
- {
+#ifdef SQLITE_DEBUG
+ /* Only the first term of a compound can have a WITH clause. But make
+ ** sure no other terms are marked SF_Recursive in case something changes
+ ** in the future.
+ */
+ {
Select *pX;
- for(pX=pSubq; pX; pX=pX->pPrior){
- assert( (pX->selFlags & (SF_Recursive))==0 );
- }
+ for(pX=pSubq; pX; pX=pX->pPrior){
+ assert( (pX->selFlags & (SF_Recursive))==0 );
+ }
}
-#endif
-
+#endif
+
if( pSubq->pLimit!=0 ){
- return 0; /* restriction (3) */
+ return 0; /* restriction (3) */
}
while( pWhere->op==TK_AND ){
nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight,
@@ -138117,15 +138117,15 @@ static int pushDownWhereTerms(
nChng++;
pSubq->selFlags |= SF_PushDown;
while( pSubq ){
- SubstContext x;
- pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
+ SubstContext x;
+ pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
unsetJoinExpr(pNew, -1);
- x.pParse = pParse;
- x.iTable = iCursor;
- x.iNewTable = iCursor;
- x.isLeftJoin = 0;
- x.pEList = pSubq->pEList;
- pNew = substExpr(&x, pNew);
+ x.pParse = pParse;
+ x.iTable = iCursor;
+ x.iNewTable = iCursor;
+ x.isLeftJoin = 0;
+ x.pEList = pSubq->pEList;
+ pNew = substExpr(&x, pNew);
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){
/* Restriction 6c has prevented push-down in this case */
@@ -138134,11 +138134,11 @@ static int pushDownWhereTerms(
break;
}
#endif
- if( pSubq->selFlags & SF_Aggregate ){
+ if( pSubq->selFlags & SF_Aggregate ){
pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew);
- }else{
+ }else{
pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew);
- }
+ }
pSubq = pSubq->pPrior;
}
}
@@ -138147,30 +138147,30 @@ static int pushDownWhereTerms(
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
/*
-** The pFunc is the only aggregate function in the query. Check to see
+** The pFunc is the only aggregate function in the query. Check to see
** if the query is a candidate for the min/max optimization.
**
-** If the query is a candidate for the min/max optimization, then set
-** *ppMinMax to be an ORDER BY clause to be used for the optimization
-** and return either WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX depending on
-** whether pFunc is a min() or max() function.
+** If the query is a candidate for the min/max optimization, then set
+** *ppMinMax to be an ORDER BY clause to be used for the optimization
+** and return either WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX depending on
+** whether pFunc is a min() or max() function.
**
-** If the query is not a candidate for the min/max optimization, return
-** WHERE_ORDERBY_NORMAL (which must be zero).
+** If the query is not a candidate for the min/max optimization, return
+** WHERE_ORDERBY_NORMAL (which must be zero).
**
-** This routine must be called after aggregate functions have been
-** located but before their arguments have been subjected to aggregate
-** analysis.
+** This routine must be called after aggregate functions have been
+** located but before their arguments have been subjected to aggregate
+** analysis.
*/
-static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
- int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
+static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
+ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
ExprList *pEList; /* Arguments to agg function */
- const char *zFunc; /* Name of aggregate function pFunc */
- ExprList *pOrderBy;
+ const char *zFunc; /* Name of aggregate function pFunc */
+ ExprList *pOrderBy;
u8 sortFlags = 0;
- assert( *ppMinMax==0 );
- assert( pFunc->op==TK_AGG_FUNCTION );
+ assert( *ppMinMax==0 );
+ assert( pFunc->op==TK_AGG_FUNCTION );
assert( !IsWindowFunc(pFunc) );
assert( ExprUseXList(pFunc) );
pEList = pFunc->x.pList;
@@ -138182,20 +138182,20 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
return eRet;
}
assert( !ExprHasProperty(pFunc, EP_IntValue) );
- zFunc = pFunc->u.zToken;
- if( sqlite3StrICmp(zFunc, "min")==0 ){
- eRet = WHERE_ORDERBY_MIN;
+ zFunc = pFunc->u.zToken;
+ if( sqlite3StrICmp(zFunc, "min")==0 ){
+ eRet = WHERE_ORDERBY_MIN;
if( sqlite3ExprCanBeNull(pEList->a[0].pExpr) ){
sortFlags = KEYINFO_ORDER_BIGNULL;
}
- }else if( sqlite3StrICmp(zFunc, "max")==0 ){
- eRet = WHERE_ORDERBY_MAX;
+ }else if( sqlite3StrICmp(zFunc, "max")==0 ){
+ eRet = WHERE_ORDERBY_MAX;
sortFlags = KEYINFO_ORDER_DESC;
- }else{
- return eRet;
+ }else{
+ return eRet;
}
- *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0);
- assert( pOrderBy!=0 || db->mallocFailed );
+ *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0);
+ assert( pOrderBy!=0 || db->mallocFailed );
if( pOrderBy ) pOrderBy->a[0].sortFlags = sortFlags;
return eRet;
}
@@ -138336,7 +138336,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
if( pNewSrc==0 ) return WRC_Abort;
*pNew = *p;
p->pSrc = pNewSrc;
- p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
+ p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
p->op = TK_SELECT;
p->pWhere = 0;
pNew->pGroupBy = 0;
@@ -138357,19 +138357,19 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
return WRC_Continue;
}
-/*
-** Check to see if the FROM clause term pFrom has table-valued function
-** arguments. If it does, leave an error message in pParse and return
-** non-zero, since pFrom is not allowed to be a table-valued function.
-*/
+/*
+** Check to see if the FROM clause term pFrom has table-valued function
+** arguments. If it does, leave an error message in pParse and return
+** non-zero, since pFrom is not allowed to be a table-valued function.
+*/
static int cannotBeFunction(Parse *pParse, SrcItem *pFrom){
- if( pFrom->fg.isTabFunc ){
- sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName);
- return 1;
- }
- return 0;
-}
-
+ if( pFrom->fg.isTabFunc ){
+ sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName);
+ return 1;
+ }
+ return 0;
+}
+
#ifndef SQLITE_OMIT_CTE
/*
** Argument pWith (which may be NULL) points to a linked list of nested
@@ -138382,7 +138382,7 @@ static int cannotBeFunction(Parse *pParse, SrcItem *pFrom){
** object that the returned CTE belongs to.
*/
static struct Cte *searchWith(
- With *pWith, /* Current innermost WITH clause */
+ With *pWith, /* Current innermost WITH clause */
SrcItem *pItem, /* FROM clause element to resolve */
With **ppContext /* OUT: WITH clause return value belongs to */
){
@@ -138495,12 +138495,12 @@ static int resolveFromTermToCte(
int iRecTab = -1; /* Cursor for recursive table */
CteUse *pCteUse;
- /* If pCte->zCteErr is non-NULL at this point, then this is an illegal
+ /* If pCte->zCteErr is non-NULL at this point, then this is an illegal
** recursive reference to CTE pCte. Leave an error in pParse and return
- ** early. If pCte->zCteErr is NULL, then this is not a recursive reference.
+ ** early. If pCte->zCteErr is NULL, then this is not a recursive reference.
** In this case, proceed. */
- if( pCte->zCteErr ){
- sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName);
+ if( pCte->zCteErr ){
+ sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName);
return 2;
}
if( cannotBeFunction(pParse, pFrom) ) return 2;
@@ -138520,7 +138520,7 @@ static int resolveFromTermToCte(
pCteUse->eM10d = pCte->eM10d;
}
pFrom->pTab = pTab;
- pTab->nTabRef = 1;
+ pTab->nTabRef = 1;
pTab->zName = sqlite3DbStrDup(db, pCte->zName);
pTab->iPKey = -1;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
@@ -138555,7 +138555,7 @@ static int resolveFromTermToCte(
){
pItem->pTab = pTab;
pTab->nTabRef++;
- pItem->fg.isRecursive = 1;
+ pItem->fg.isRecursive = 1;
if( pRecTerm->selFlags & SF_Recursive ){
sqlite3ErrorMsg(pParse,
"multiple references to recursive table: %s", pCte->zName
@@ -138571,7 +138571,7 @@ static int resolveFromTermToCte(
pRecTerm = pRecTerm->pPrior;
}
- pCte->zCteErr = "circular reference: %s";
+ pCte->zCteErr = "circular reference: %s";
pSavedWith = pParse->pWith;
pParse->pWith = pWith;
if( pSel->selFlags & SF_Recursive ){
@@ -138588,13 +138588,13 @@ static int resolveFromTermToCte(
pParse->pWith = pSavedWith;
return 2;
}
- }else{
+ }else{
if( sqlite3WalkSelect(pWalker, pSel) ){
pParse->pWith = pSavedWith;
return 2;
}
- }
- pParse->pWith = pWith;
+ }
+ pParse->pWith = pWith;
for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
pEList = pLeft->pEList;
@@ -138609,16 +138609,16 @@ static int resolveFromTermToCte(
pEList = pCte->pCols;
}
- sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol);
+ sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol);
if( bMayRecursive ){
if( pSel->selFlags & SF_Recursive ){
- pCte->zCteErr = "multiple recursive references: %s";
+ pCte->zCteErr = "multiple recursive references: %s";
}else{
- pCte->zCteErr = "recursive reference in a subquery: %s";
+ pCte->zCteErr = "recursive reference in a subquery: %s";
}
sqlite3WalkSelect(pWalker, pSel);
}
- pCte->zCteErr = 0;
+ pCte->zCteErr = 0;
pParse->pWith = pSavedWith;
return 1; /* Success */
}
@@ -138637,12 +138637,12 @@ static int resolveFromTermToCte(
*/
SQLITE_PRIVATE void sqlite3SelectPopWith(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
- if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){
- With *pWith = findRightmost(p)->pWith;
- if( pWith!=0 ){
+ if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){
+ With *pWith = findRightmost(p)->pWith;
+ if( pWith!=0 ){
assert( pParse->pWith==pWith || pParse->nErr );
- pParse->pWith = pWith->pOuter;
- }
+ pParse->pWith = pWith->pOuter;
+ }
}
}
#endif
@@ -138715,14 +138715,14 @@ static int selectExpander(Walker *pWalker, Select *p){
sqlite3 *db = pParse->db;
Expr *pE, *pRight, *pExpr;
u16 selFlags = p->selFlags;
- u32 elistFlags = 0;
+ u32 elistFlags = 0;
p->selFlags |= SF_Expanded;
if( db->mallocFailed ){
return WRC_Abort;
}
- assert( p->pSrc!=0 );
- if( (selFlags & SF_Expanded)!=0 ){
+ assert( p->pSrc!=0 );
+ if( (selFlags & SF_Expanded)!=0 ){
return WRC_Prune;
}
if( pWalker->eCode ){
@@ -138753,7 +138753,7 @@ static int selectExpander(Walker *pWalker, Select *p){
*/
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab;
- assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
+ assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
if( pFrom->pTab ) continue;
assert( pFrom->fg.isRecursive==0 );
if( pFrom->zName==0 ){
@@ -138776,19 +138776,19 @@ static int selectExpander(Walker *pWalker, Select *p){
assert( pFrom->pTab==0 );
pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
if( pTab==0 ) return WRC_Abort;
- if( pTab->nTabRef>=0xffff ){
+ if( pTab->nTabRef>=0xffff ){
sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
pTab->zName);
pFrom->pTab = 0;
return WRC_Abort;
}
- pTab->nTabRef++;
- if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){
- return WRC_Abort;
- }
+ pTab->nTabRef++;
+ if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){
+ return WRC_Abort;
+ }
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
if( !IsOrdinaryTable(pTab) ){
- i16 nCol;
+ i16 nCol;
u8 eCodeOrig = pWalker->eCode;
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
assert( pFrom->pSelect==0 );
@@ -138812,12 +138812,12 @@ static int selectExpander(Walker *pWalker, Select *p){
}
assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 );
#endif
- nCol = pTab->nCol;
- pTab->nCol = -1;
+ nCol = pTab->nCol;
+ pTab->nCol = -1;
pWalker->eCode = 1; /* Turn on Select.selId renumbering */
sqlite3WalkSelect(pWalker, pFrom->pSelect);
pWalker->eCode = eCodeOrig;
- pTab->nCol = nCol;
+ pTab->nCol = nCol;
}
#endif
}
@@ -138837,21 +138837,21 @@ static int selectExpander(Walker *pWalker, Select *p){
/* For every "*" that occurs in the column list, insert the names of
** all columns in all tables. And for every TABLE.* insert the names
** of all columns in TABLE. The parser inserted a special expression
- ** with the TK_ASTERISK operator for each "*" that it found in the column
- ** list. The following code just has to locate the TK_ASTERISK
- ** expressions and expand each one to the list of all columns in
- ** all tables.
+ ** with the TK_ASTERISK operator for each "*" that it found in the column
+ ** list. The following code just has to locate the TK_ASTERISK
+ ** expressions and expand each one to the list of all columns in
+ ** all tables.
**
** The first loop just checks to see if there are any "*" operators
** that need expanding.
*/
for(k=0; k<pEList->nExpr; k++){
pE = pEList->a[k].pExpr;
- if( pE->op==TK_ASTERISK ) break;
+ if( pE->op==TK_ASTERISK ) break;
assert( pE->op!=TK_DOT || pE->pRight!=0 );
assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
- if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break;
- elistFlags |= pE->flags;
+ if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break;
+ elistFlags |= pE->flags;
}
if( k<pEList->nExpr ){
/*
@@ -138867,12 +138867,12 @@ static int selectExpander(Walker *pWalker, Select *p){
for(k=0; k<pEList->nExpr; k++){
pE = a[k].pExpr;
- elistFlags |= pE->flags;
+ elistFlags |= pE->flags;
pRight = pE->pRight;
assert( pE->op!=TK_DOT || pRight!=0 );
- if( pE->op!=TK_ASTERISK
- && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK)
- ){
+ if( pE->op!=TK_ASTERISK
+ && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK)
+ ){
/* This particular expression does not need to be expanded.
*/
pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
@@ -138908,7 +138908,7 @@ static int selectExpander(Walker *pWalker, Select *p){
continue;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*";
+ zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*";
}
for(j=0; j<pTab->nCol; j++){
char *zName = pTab->aCol[j].zCnName;
@@ -138923,19 +138923,19 @@ static int selectExpander(Walker *pWalker, Select *p){
continue;
}
- /* If a column is marked as 'hidden', omit it from the expanded
- ** result-set list unless the SELECT has the SF_IncludeHidden
- ** bit set.
+ /* If a column is marked as 'hidden', omit it from the expanded
+ ** result-set list unless the SELECT has the SF_IncludeHidden
+ ** bit set.
*/
- if( (p->selFlags & SF_IncludeHidden)==0
+ if( (p->selFlags & SF_IncludeHidden)==0
&& IsHiddenColumn(&pTab->aCol[j])
- ){
+ ){
continue;
}
tableSeen = 1;
if( i>0 && zTName==0 ){
- if( (pFrom->fg.jointype & JT_NATURAL)!=0
+ if( (pFrom->fg.jointype & JT_NATURAL)!=0
&& tableAndColumnIndex(pTabList, i, zName, 0, 0, 1)
){
/* In a NATURAL join, omit the join columns from the
@@ -138954,10 +138954,10 @@ static int selectExpander(Walker *pWalker, Select *p){
if( longNames || pTabList->nSrc>1 ){
Expr *pLeft;
pLeft = sqlite3Expr(db, TK_ID, zTabName);
- pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
+ pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
if( zSchemaName ){
pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
- pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr);
+ pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr);
}
if( longNames ){
zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
@@ -138967,7 +138967,7 @@ static int selectExpander(Walker *pWalker, Select *p){
pExpr = pRight;
}
pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
- sqlite3TokenInit(&sColname, zColname);
+ sqlite3TokenInit(&sColname, zColname);
sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
if( pNew && (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
@@ -138997,29 +138997,29 @@ static int selectExpander(Walker *pWalker, Select *p){
sqlite3ExprListDelete(db, pEList);
p->pEList = pNew;
}
- if( p->pEList ){
- if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many columns in result set");
- return WRC_Abort;
- }
- if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){
- p->selFlags |= SF_ComplexResult;
- }
+ if( p->pEList ){
+ if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
+ sqlite3ErrorMsg(pParse, "too many columns in result set");
+ return WRC_Abort;
+ }
+ if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){
+ p->selFlags |= SF_ComplexResult;
+ }
}
return WRC_Continue;
}
-#if SQLITE_DEBUG
-/*
-** Always assert. This xSelectCallback2 implementation proves that the
-** xSelectCallback2 is never invoked.
-*/
-SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- assert( 0 );
-}
-#endif
-/*
+#if SQLITE_DEBUG
+/*
+** Always assert. This xSelectCallback2 implementation proves that the
+** xSelectCallback2 is never invoked.
+*/
+SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ assert( 0 );
+}
+#endif
+/*
** This routine "expands" a SELECT statement and all of its subqueries.
** For additional information on what it means to "expand" a SELECT
** statement, see the comment on the selectExpand worker callback above.
@@ -139034,11 +139034,11 @@ SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){
*/
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
Walker w;
- w.xExprCallback = sqlite3ExprWalkNoop;
+ w.xExprCallback = sqlite3ExprWalkNoop;
w.pParse = pParse;
- if( OK_IF_ALWAYS_TRUE(pParse->hasCompound) ){
+ if( OK_IF_ALWAYS_TRUE(pParse->hasCompound) ){
w.xSelectCallback = convertCompoundSelectToSubquery;
- w.xSelectCallback2 = 0;
+ w.xSelectCallback2 = 0;
sqlite3WalkSelect(&w, pSelect);
}
w.xSelectCallback = selectExpander;
@@ -139070,17 +139070,17 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
assert( p->selFlags & SF_Resolved );
if( p->selFlags & SF_HasTypeInfo ) return;
- p->selFlags |= SF_HasTypeInfo;
- pParse = pWalker->pParse;
- pTabList = p->pSrc;
- for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
- Table *pTab = pFrom->pTab;
- assert( pTab!=0 );
- if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
- /* A sub-query in the FROM clause of a SELECT */
- Select *pSel = pFrom->pSelect;
- if( pSel ){
- while( pSel->pPrior ) pSel = pSel->pPrior;
+ p->selFlags |= SF_HasTypeInfo;
+ pParse = pWalker->pParse;
+ pTabList = p->pSrc;
+ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+ Table *pTab = pFrom->pTab;
+ assert( pTab!=0 );
+ if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
+ /* A sub-query in the FROM clause of a SELECT */
+ Select *pSel = pFrom->pSelect;
+ if( pSel ){
+ while( pSel->pPrior ) pSel = pSel->pPrior;
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel,
SQLITE_AFF_NONE);
}
@@ -139100,9 +139100,9 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){
#ifndef SQLITE_OMIT_SUBQUERY
Walker w;
- w.xSelectCallback = sqlite3SelectWalkNoop;
+ w.xSelectCallback = sqlite3SelectWalkNoop;
w.xSelectCallback2 = selectAddSubqueryTypeInfo;
- w.xExprCallback = sqlite3ExprWalkNoop;
+ w.xExprCallback = sqlite3ExprWalkNoop;
w.pParse = pParse;
sqlite3WalkSelect(&w, pSelect);
#endif
@@ -139126,13 +139126,13 @@ SQLITE_PRIVATE void sqlite3SelectPrep(
Select *p, /* The SELECT statement being coded. */
NameContext *pOuterNC /* Name context for container */
){
- assert( p!=0 || pParse->db->mallocFailed );
- if( pParse->db->mallocFailed ) return;
+ assert( p!=0 || pParse->db->mallocFailed );
+ if( pParse->db->mallocFailed ) return;
if( p->selFlags & SF_HasTypeInfo ) return;
sqlite3SelectExpand(pParse, p);
- if( pParse->nErr || pParse->db->mallocFailed ) return;
+ if( pParse->nErr || pParse->db->mallocFailed ) return;
sqlite3ResolveSelectNames(pParse, p, pOuterNC);
- if( pParse->nErr || pParse->db->mallocFailed ) return;
+ if( pParse->nErr || pParse->db->mallocFailed ) return;
sqlite3SelectAddTypeInfo(pParse, p);
}
@@ -139196,8 +139196,8 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
ExprList *pList;
assert( ExprUseXList(pF->pFExpr) );
pList = pF->pFExpr->x.pList;
- sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0);
- sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
+ sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0);
+ sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
}
}
@@ -139258,7 +139258,7 @@ static void updateAccumulator(
if( pList ){
nArg = pList->nExpr;
regAgg = sqlite3GetTempRange(pParse, nArg);
- sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP);
+ sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP);
}else{
nArg = 0;
regAgg = 0;
@@ -139285,7 +139285,7 @@ static void updateAccumulator(
sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
}
sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem);
- sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
+ sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nArg);
sqlite3ReleaseTempRange(pParse, regAgg, nArg);
if( addrNext ){
@@ -139332,18 +139332,18 @@ static void explainSimpleCount(
#endif
/*
-** sqlite3WalkExpr() callback used by havingToWhere().
-**
+** sqlite3WalkExpr() callback used by havingToWhere().
+**
** If the node passed to the callback is a TK_AND node, return
-** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes.
-**
+** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes.
+**
** Otherwise, return WRC_Prune. In this case, also check if the
-** sub-expression matches the criteria for being moved to the WHERE
-** clause. If so, add it to the WHERE clause and replace the sub-expression
-** within the HAVING expression with a constant "1".
-*/
-static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
- if( pExpr->op!=TK_AND ){
+** sub-expression matches the criteria for being moved to the WHERE
+** clause. If so, add it to the WHERE clause and replace the sub-expression
+** within the HAVING expression with a constant "1".
+*/
+static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
+ if( pExpr->op!=TK_AND ){
Select *pS = pWalker->u.pSelect;
/* This routine is called before the HAVING clause of the current
** SELECT is analyzed for aggregates. So if pExpr->pAggInfo is set
@@ -139356,41 +139356,41 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
&& ExprAlwaysFalse(pExpr)==0
&& pExpr->pAggInfo==0
){
- sqlite3 *db = pWalker->pParse->db;
+ sqlite3 *db = pWalker->pParse->db;
Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1");
- if( pNew ){
+ if( pNew ){
Expr *pWhere = pS->pWhere;
- SWAP(Expr, *pNew, *pExpr);
+ SWAP(Expr, *pNew, *pExpr);
pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew);
pS->pWhere = pNew;
pWalker->eCode = 1;
- }
- }
- return WRC_Prune;
- }
- return WRC_Continue;
-}
-
-/*
-** Transfer eligible terms from the HAVING clause of a query, which is
-** processed after grouping, to the WHERE clause, which is processed before
-** grouping. For example, the query:
-**
-** SELECT * FROM <tables> WHERE a=? GROUP BY b HAVING b=? AND c=?
-**
-** can be rewritten as:
-**
-** SELECT * FROM <tables> WHERE a=? AND b=? GROUP BY b HAVING c=?
-**
-** A term of the HAVING expression is eligible for transfer if it consists
-** entirely of constants and expressions that are also GROUP BY terms that
-** use the "BINARY" collation sequence.
-*/
+ }
+ }
+ return WRC_Prune;
+ }
+ return WRC_Continue;
+}
+
+/*
+** Transfer eligible terms from the HAVING clause of a query, which is
+** processed after grouping, to the WHERE clause, which is processed before
+** grouping. For example, the query:
+**
+** SELECT * FROM <tables> WHERE a=? GROUP BY b HAVING b=? AND c=?
+**
+** can be rewritten as:
+**
+** SELECT * FROM <tables> WHERE a=? AND b=? GROUP BY b HAVING c=?
+**
+** A term of the HAVING expression is eligible for transfer if it consists
+** entirely of constants and expressions that are also GROUP BY terms that
+** use the "BINARY" collation sequence.
+*/
static void havingToWhere(Parse *pParse, Select *p){
- Walker sWalker;
- memset(&sWalker, 0, sizeof(sWalker));
- sWalker.pParse = pParse;
- sWalker.xExprCallback = havingToWhereExprCb;
+ Walker sWalker;
+ memset(&sWalker, 0, sizeof(sWalker));
+ sWalker.pParse = pParse;
+ sWalker.xExprCallback = havingToWhereExprCb;
sWalker.u.pSelect = p;
sqlite3WalkExpr(&sWalker, p->pHaving);
#if SELECTTRACE_ENABLED
@@ -139399,29 +139399,29 @@ static void havingToWhere(Parse *pParse, Select *p){
sqlite3TreeViewSelect(0, p, 0);
}
#endif
-}
-
-/*
-** Check to see if the pThis entry of pTabList is a self-join of a prior view.
-** If it is, then return the SrcList_item for the prior view. If it is not,
-** then return 0.
-*/
+}
+
+/*
+** Check to see if the pThis entry of pTabList is a self-join of a prior view.
+** If it is, then return the SrcList_item for the prior view. If it is not,
+** then return 0.
+*/
static SrcItem *isSelfJoinView(
- SrcList *pTabList, /* Search for self-joins in this FROM clause */
+ SrcList *pTabList, /* Search for self-joins in this FROM clause */
SrcItem *pThis /* Search for prior reference to this subquery */
-){
+){
SrcItem *pItem;
assert( pThis->pSelect!=0 );
if( pThis->pSelect->selFlags & SF_PushDown ) return 0;
- for(pItem = pTabList->a; pItem<pThis; pItem++){
+ for(pItem = pTabList->a; pItem<pThis; pItem++){
Select *pS1;
- if( pItem->pSelect==0 ) continue;
- if( pItem->fg.viaCoroutine ) continue;
- if( pItem->zName==0 ) continue;
+ if( pItem->pSelect==0 ) continue;
+ if( pItem->fg.viaCoroutine ) continue;
+ if( pItem->zName==0 ) continue;
assert( pItem->pTab!=0 );
assert( pThis->pTab!=0 );
if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue;
- if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
+ if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
pS1 = pItem->pSelect;
if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){
/* The query flattener left two different CTE tables with identical
@@ -139429,15 +139429,15 @@ static SrcItem *isSelfJoinView(
continue;
}
if( pItem->pSelect->selFlags & SF_PushDown ){
- /* The view was modified by some other optimization such as
- ** pushDownWhereTerms() */
- continue;
- }
- return pItem;
- }
- return 0;
-}
-
+ /* The view was modified by some other optimization such as
+ ** pushDownWhereTerms() */
+ continue;
+ }
+ return pItem;
+ }
+ return 0;
+}
+
/*
** Deallocate a single AggInfo object
*/
@@ -139447,96 +139447,96 @@ static void agginfoFree(sqlite3 *db, AggInfo *p){
sqlite3DbFreeNN(db, p);
}
-#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
-/*
-** Attempt to transform a query of the form
-**
-** SELECT count(*) FROM (SELECT x FROM t1 UNION ALL SELECT y FROM t2)
-**
-** Into this:
-**
-** SELECT (SELECT count(*) FROM t1)+(SELECT count(*) FROM t2)
-**
-** The transformation only works if all of the following are true:
-**
-** * The subquery is a UNION ALL of two or more terms
+#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
+/*
+** Attempt to transform a query of the form
+**
+** SELECT count(*) FROM (SELECT x FROM t1 UNION ALL SELECT y FROM t2)
+**
+** Into this:
+**
+** SELECT (SELECT count(*) FROM t1)+(SELECT count(*) FROM t2)
+**
+** The transformation only works if all of the following are true:
+**
+** * The subquery is a UNION ALL of two or more terms
** * The subquery does not have a LIMIT clause
-** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries
+** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries
** * The outer query is a simple count(*) with no WHERE clause or other
** extraneous syntax.
-**
-** Return TRUE if the optimization is undertaken.
-*/
-static int countOfViewOptimization(Parse *pParse, Select *p){
- Select *pSub, *pPrior;
- Expr *pExpr;
- Expr *pCount;
- sqlite3 *db;
- if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */
- if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
+**
+** Return TRUE if the optimization is undertaken.
+*/
+static int countOfViewOptimization(Parse *pParse, Select *p){
+ Select *pSub, *pPrior;
+ Expr *pExpr;
+ Expr *pCount;
+ sqlite3 *db;
+ if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */
+ if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
if( p->pWhere ) return 0;
if( p->pGroupBy ) return 0;
- pExpr = p->pEList->a[0].pExpr;
- if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */
+ pExpr = p->pEList->a[0].pExpr;
+ if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */
assert( ExprUseUToken(pExpr) );
- if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
+ if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
assert( ExprUseXList(pExpr) );
- if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */
- if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */
- pSub = p->pSrc->a[0].pSelect;
- if( pSub==0 ) return 0; /* The FROM is a subquery */
- if( pSub->pPrior==0 ) return 0; /* Must be a compound ry */
- do{
- if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */
- if( pSub->pWhere ) return 0; /* No WHERE clause */
+ if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */
+ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */
+ pSub = p->pSrc->a[0].pSelect;
+ if( pSub==0 ) return 0; /* The FROM is a subquery */
+ if( pSub->pPrior==0 ) return 0; /* Must be a compound ry */
+ do{
+ if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */
+ if( pSub->pWhere ) return 0; /* No WHERE clause */
if( pSub->pLimit ) return 0; /* No LIMIT clause */
- if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */
- pSub = pSub->pPrior; /* Repeat over compound */
- }while( pSub );
-
- /* If we reach this point then it is OK to perform the transformation */
-
- db = pParse->db;
- pCount = pExpr;
- pExpr = 0;
- pSub = p->pSrc->a[0].pSelect;
- p->pSrc->a[0].pSelect = 0;
- sqlite3SrcListDelete(db, p->pSrc);
- p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc));
- while( pSub ){
- Expr *pTerm;
- pPrior = pSub->pPrior;
- pSub->pPrior = 0;
- pSub->pNext = 0;
- pSub->selFlags |= SF_Aggregate;
- pSub->selFlags &= ~SF_Compound;
- pSub->nSelectRow = 0;
- sqlite3ExprListDelete(db, pSub->pEList);
- pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount;
- pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm);
- pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
- sqlite3PExprAddSelect(pParse, pTerm, pSub);
- if( pExpr==0 ){
- pExpr = pTerm;
- }else{
- pExpr = sqlite3PExpr(pParse, TK_PLUS, pTerm, pExpr);
- }
- pSub = pPrior;
- }
- p->pEList->a[0].pExpr = pExpr;
- p->selFlags &= ~SF_Aggregate;
-
-#if SELECTTRACE_ENABLED
+ if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */
+ pSub = pSub->pPrior; /* Repeat over compound */
+ }while( pSub );
+
+ /* If we reach this point then it is OK to perform the transformation */
+
+ db = pParse->db;
+ pCount = pExpr;
+ pExpr = 0;
+ pSub = p->pSrc->a[0].pSelect;
+ p->pSrc->a[0].pSelect = 0;
+ sqlite3SrcListDelete(db, p->pSrc);
+ p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc));
+ while( pSub ){
+ Expr *pTerm;
+ pPrior = pSub->pPrior;
+ pSub->pPrior = 0;
+ pSub->pNext = 0;
+ pSub->selFlags |= SF_Aggregate;
+ pSub->selFlags &= ~SF_Compound;
+ pSub->nSelectRow = 0;
+ sqlite3ExprListDelete(db, pSub->pEList);
+ pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount;
+ pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm);
+ pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
+ sqlite3PExprAddSelect(pParse, pTerm, pSub);
+ if( pExpr==0 ){
+ pExpr = pTerm;
+ }else{
+ pExpr = sqlite3PExpr(pParse, TK_PLUS, pTerm, pExpr);
+ }
+ pSub = pPrior;
+ }
+ p->pEList->a[0].pExpr = pExpr;
+ p->selFlags &= ~SF_Aggregate;
+
+#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x400 ){
- SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n"));
- sqlite3TreeViewSelect(0, p, 0);
- }
-#endif
- return 1;
-}
-#endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */
-
-/*
+ SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
+ return 1;
+}
+#endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */
+
+/*
** Generate code for the SELECT statement given in the p argument.
**
** The results are returned according to the SelectDest structure.
@@ -139569,8 +139569,8 @@ SQLITE_PRIVATE int sqlite3Select(
SortCtx sSort; /* Info on how to code the ORDER BY clause */
int iEnd; /* Address of the end of the query */
sqlite3 *db; /* The database connection */
- ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */
- u8 minMaxFlag; /* Flag for min/max queries */
+ ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */
+ u8 minMaxFlag; /* Flag for min/max queries */
db = pParse->db;
v = sqlite3GetVdbe(pParse);
@@ -139651,7 +139651,7 @@ SQLITE_PRIVATE int sqlite3Select(
p->selFlags &= ~SF_UFSrcCheck;
}
- if( pDest->eDest==SRT_Output ){
+ if( pDest->eDest==SRT_Output ){
sqlite3GenerateColumnNames(pParse, p);
}
@@ -139679,7 +139679,7 @@ SQLITE_PRIVATE int sqlite3Select(
for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
SrcItem *pItem = &pTabList->a[i];
Select *pSub = pItem->pSelect;
- Table *pTab = pItem->pTab;
+ Table *pTab = pItem->pTab;
/* The expander should have already created transient Table objects
** even for FROM clause elements such as subqueries that do not correspond
@@ -139701,25 +139701,25 @@ SQLITE_PRIVATE int sqlite3Select(
/* No futher action if this term of the FROM clause is no a subquery */
if( pSub==0 ) continue;
-
- /* Catch mismatch in the declared columns of a view and the number of
- ** columns in the SELECT on the RHS */
- if( pTab->nCol!=pSub->pEList->nExpr ){
- sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d",
- pTab->nCol, pTab->zName, pSub->pEList->nExpr);
- goto select_end;
- }
-
- /* Do not try to flatten an aggregate subquery.
- **
- ** Flattening an aggregate subquery is only possible if the outer query
- ** is not a join. But if the outer query is not a join, then the subquery
- ** will be implemented as a co-routine and there is no advantage to
- ** flattening in that case.
- */
- if( (pSub->selFlags & SF_Aggregate)!=0 ) continue;
- assert( pSub->pGroupBy==0 );
-
+
+ /* Catch mismatch in the declared columns of a view and the number of
+ ** columns in the SELECT on the RHS */
+ if( pTab->nCol!=pSub->pEList->nExpr ){
+ sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d",
+ pTab->nCol, pTab->zName, pSub->pEList->nExpr);
+ goto select_end;
+ }
+
+ /* Do not try to flatten an aggregate subquery.
+ **
+ ** Flattening an aggregate subquery is only possible if the outer query
+ ** is not a join. But if the outer query is not a join, then the subquery
+ ** will be implemented as a co-routine and there is no advantage to
+ ** flattening in that case.
+ */
+ if( (pSub->selFlags & SF_Aggregate)!=0 ) continue;
+ assert( pSub->pGroupBy==0 );
+
/* If a FROM-clause subquery has an ORDER BY clause that is not
** really doing anything, then delete it now so that it does not
** interfere with query flattening. See the discussion at
@@ -139753,34 +139753,34 @@ SQLITE_PRIVATE int sqlite3Select(
pSub->pOrderBy = 0;
}
- /* If the outer query contains a "complex" result set (that is,
- ** if the result set of the outer query uses functions or subqueries)
- ** and if the subquery contains an ORDER BY clause and if
- ** it will be implemented as a co-routine, then do not flatten. This
- ** restriction allows SQL constructs like this:
- **
- ** SELECT expensive_function(x)
- ** FROM (SELECT x FROM tab ORDER BY y LIMIT 10);
- **
- ** The expensive_function() is only computed on the 10 rows that
- ** are output, rather than every row of the table.
- **
- ** The requirement that the outer query have a complex result set
- ** means that flattening does occur on simpler SQL constraints without
- ** the expensive_function() like:
- **
- ** SELECT x FROM (SELECT x FROM tab ORDER BY y LIMIT 10);
- */
- if( pSub->pOrderBy!=0
- && i==0
- && (p->selFlags & SF_ComplexResult)!=0
- && (pTabList->nSrc==1
- || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)
- ){
- continue;
- }
-
- if( flattenSubquery(pParse, p, i, isAgg) ){
+ /* If the outer query contains a "complex" result set (that is,
+ ** if the result set of the outer query uses functions or subqueries)
+ ** and if the subquery contains an ORDER BY clause and if
+ ** it will be implemented as a co-routine, then do not flatten. This
+ ** restriction allows SQL constructs like this:
+ **
+ ** SELECT expensive_function(x)
+ ** FROM (SELECT x FROM tab ORDER BY y LIMIT 10);
+ **
+ ** The expensive_function() is only computed on the 10 rows that
+ ** are output, rather than every row of the table.
+ **
+ ** The requirement that the outer query have a complex result set
+ ** means that flattening does occur on simpler SQL constraints without
+ ** the expensive_function() like:
+ **
+ ** SELECT x FROM (SELECT x FROM tab ORDER BY y LIMIT 10);
+ */
+ if( pSub->pOrderBy!=0
+ && i==0
+ && (p->selFlags & SF_ComplexResult)!=0
+ && (pTabList->nSrc==1
+ || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)
+ ){
+ continue;
+ }
+
+ if( flattenSubquery(pParse, p, i, isAgg) ){
if( pParse->nErr ) goto select_end;
/* This subquery can be absorbed into its parent. */
i = -1;
@@ -139840,43 +139840,43 @@ SQLITE_PRIVATE int sqlite3Select(
}
#endif
- /* For each term in the FROM clause, do two things:
- ** (1) Authorized unreferenced tables
- ** (2) Generate code for all sub-queries
+ /* For each term in the FROM clause, do two things:
+ ** (1) Authorized unreferenced tables
+ ** (2) Generate code for all sub-queries
*/
for(i=0; i<pTabList->nSrc; i++){
SrcItem *pItem = &pTabList->a[i];
SrcItem *pPrior;
SelectDest dest;
- Select *pSub;
-#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
- const char *zSavedAuthContext;
-#endif
-
- /* Issue SQLITE_READ authorizations with a fake column name for any
- ** tables that are referenced but from which no values are extracted.
- ** Examples of where these kinds of null SQLITE_READ authorizations
- ** would occur:
- **
- ** SELECT count(*) FROM t1; -- SQLITE_READ t1.""
- ** SELECT t1.* FROM t1, t2; -- SQLITE_READ t2.""
- **
- ** The fake column name is an empty string. It is possible for a table to
- ** have a column named by the empty string, in which case there is no way to
- ** distinguish between an unreferenced table and an actual reference to the
- ** "" column. The original design was for the fake column name to be a NULL,
- ** which would be unambiguous. But legacy authorization callbacks might
- ** assume the column name is non-NULL and segfault. The use of an empty
- ** string for the fake column name seems safer.
- */
+ Select *pSub;
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+ const char *zSavedAuthContext;
+#endif
+
+ /* Issue SQLITE_READ authorizations with a fake column name for any
+ ** tables that are referenced but from which no values are extracted.
+ ** Examples of where these kinds of null SQLITE_READ authorizations
+ ** would occur:
+ **
+ ** SELECT count(*) FROM t1; -- SQLITE_READ t1.""
+ ** SELECT t1.* FROM t1, t2; -- SQLITE_READ t2.""
+ **
+ ** The fake column name is an empty string. It is possible for a table to
+ ** have a column named by the empty string, in which case there is no way to
+ ** distinguish between an unreferenced table and an actual reference to the
+ ** "" column. The original design was for the fake column name to be a NULL,
+ ** which would be unambiguous. But legacy authorization callbacks might
+ ** assume the column name is non-NULL and segfault. The use of an empty
+ ** string for the fake column name seems safer.
+ */
if( pItem->colUsed==0 && pItem->zName!=0 ){
- sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
- }
-
-#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
- /* Generate code for all sub-queries in the FROM clause
- */
- pSub = pItem->pSelect;
+ sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
+ }
+
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+ /* Generate code for all sub-queries in the FROM clause
+ */
+ pSub = pItem->pSelect;
if( pSub==0 ) continue;
/* The code for a subquery should only be generated once. */
@@ -139912,22 +139912,22 @@ SQLITE_PRIVATE int sqlite3Select(
SELECTTRACE(0x100,pParse,p,("Push-down not possible\n"));
}
- zSavedAuthContext = pParse->zAuthContext;
- pParse->zAuthContext = pItem->zName;
-
+ zSavedAuthContext = pParse->zAuthContext;
+ pParse->zAuthContext = pItem->zName;
+
/* Generate code to implement the subquery
- **
+ **
** The subquery is implemented as a co-routine if:
** (1) the subquery is guaranteed to be the outer loop (so that
** it does not need to be computed more than once), and
** (2) the subquery is not a CTE that should be materialized
- **
+ **
** TODO: Are there other reasons beside (1) and (2) to use a co-routine
- ** implementation?
+ ** implementation?
*/
- if( i==0
- && (pTabList->nSrc==1
- || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */
+ if( i==0
+ && (pTabList->nSrc==1
+ || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */
&& (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */
){
/* Implement a co-routine that will return a single row of the result
@@ -139942,10 +139942,10 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem));
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowLogEst = pSub->nSelectRow;
- pItem->fg.viaCoroutine = 1;
+ pItem->pTab->nRowLogEst = pSub->nSelectRow;
+ pItem->fg.viaCoroutine = 1;
pItem->regResult = dest.iSdst;
- sqlite3VdbeEndCoroutine(v, pItem->regReturn);
+ sqlite3VdbeEndCoroutine(v, pItem->regReturn);
sqlite3VdbeJumpHere(v, addrTop-1);
sqlite3ClearTempRegCache(pParse);
}else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){
@@ -139975,15 +139975,15 @@ SQLITE_PRIVATE int sqlite3Select(
int topAddr;
int onceAddr = 0;
int retAddr;
-
+
pItem->regReturn = ++pParse->nMem;
topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
pItem->addrFillSub = topAddr+1;
- if( pItem->fg.isCorrelated==0 ){
+ if( pItem->fg.isCorrelated==0 ){
/* If the subquery is not correlated and if we are not inside of
** a trigger, then we only need to compute the value of the subquery
** once. */
- onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
VdbeComment((v, "materialize %!S", pItem));
}else{
VdbeNoopComment((v, "materialize %!S", pItem));
@@ -139991,7 +139991,7 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
ExplainQueryPlan((pParse, 1, "MATERIALIZE %!S", pItem));
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowLogEst = pSub->nSelectRow;
+ pItem->pTab->nRowLogEst = pSub->nSelectRow;
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
VdbeComment((v, "end %!S", pItem));
@@ -140007,8 +140007,8 @@ SQLITE_PRIVATE int sqlite3Select(
}
if( db->mallocFailed ) goto select_end;
pParse->nHeight -= sqlite3SelectExprHeight(p);
- pParse->zAuthContext = zSavedAuthContext;
-#endif
+ pParse->zAuthContext = zSavedAuthContext;
+#endif
}
/* Various elements of the SELECT copied into local variables for
@@ -140054,13 +140054,13 @@ SQLITE_PRIVATE int sqlite3Select(
** the sDistinct.isTnct is still set. Hence, isTnct represents the
** original setting of the SF_Distinct flag, not the current setting */
assert( sDistinct.isTnct );
-
-#if SELECTTRACE_ENABLED
+
+#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x400 ){
- SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
- sqlite3TreeViewSelect(0, p, 0);
- }
-#endif
+ SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
}
/* If there is an ORDER BY clause, then create an ephemeral index to
@@ -140094,12 +140094,12 @@ SQLITE_PRIVATE int sqlite3Select(
/* Set the limiter.
*/
iEnd = sqlite3VdbeMakeLabel(pParse);
- if( (p->selFlags & SF_FixedLimit)==0 ){
- p->nSelectRow = 320; /* 4 billion rows */
- }
+ if( (p->selFlags & SF_FixedLimit)==0 ){
+ p->nSelectRow = 320; /* 4 billion rows */
+ }
computeLimitRegisters(pParse, p, iEnd);
if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
- sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
+ sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
sSort.sortFlags |= SORTFLAG_UseSorter;
}
@@ -140127,13 +140127,13 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3WindowCodeInit(pParse, p);
}
#endif
- assert( WHERE_USE_LIMIT==SF_FixedLimit );
+ assert( WHERE_USE_LIMIT==SF_FixedLimit );
/* Begin the database scan. */
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
- p->pEList, wctrlFlags, p->nSelectRow);
+ p->pEList, wctrlFlags, p->nSelectRow);
if( pWInfo==0 ) goto select_end;
if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
@@ -140158,7 +140158,7 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
}
- assert( p->pEList==pEList );
+ assert( p->pEList==pEList );
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pWin ){
int addrGosub = sqlite3VdbeMakeLabel(pParse);
@@ -140219,8 +140219,8 @@ SQLITE_PRIVATE int sqlite3Select(
for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
pItem->u.x.iAlias = 0;
}
- assert( 66==sqlite3LogEst(100) );
- if( p->nSelectRow>66 ) p->nSelectRow = 66;
+ assert( 66==sqlite3LogEst(100) );
+ if( p->nSelectRow>66 ) p->nSelectRow = 66;
/* If there is both a GROUP BY and an ORDER BY clause and they are
** identical, then it may be possible to disable the ORDER BY clause
@@ -140246,8 +140246,8 @@ SQLITE_PRIVATE int sqlite3Select(
}
}
}else{
- assert( 0==sqlite3LogEst(1) );
- p->nSelectRow = 0;
+ assert( 0==sqlite3LogEst(1) );
+ p->nSelectRow = 0;
}
/* Create a label to jump to when we want to abort the query */
@@ -140278,21 +140278,21 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3ExprAnalyzeAggList(&sNC, pEList);
sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
if( pHaving ){
- if( pGroupBy ){
- assert( pWhere==p->pWhere );
+ if( pGroupBy ){
+ assert( pWhere==p->pWhere );
assert( pHaving==p->pHaving );
assert( pGroupBy==p->pGroupBy );
havingToWhere(pParse, p);
- pWhere = p->pWhere;
- }
+ pWhere = p->pWhere;
+ }
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
pAggInfo->nAccumulator = pAggInfo->nColumn;
if( p->pGroupBy==0 && p->pHaving==0 && pAggInfo->nFunc==1 ){
minMaxFlag = minMaxQuery(db, pAggInfo->aFunc[0].pFExpr, &pMinMaxOrderBy);
- }else{
- minMaxFlag = WHERE_ORDERBY_NORMAL;
- }
+ }else{
+ minMaxFlag = WHERE_ORDERBY_NORMAL;
+ }
for(i=0; i<pAggInfo->nFunc; i++){
Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
assert( ExprUseXList(pExpr) );
@@ -140308,35 +140308,35 @@ SQLITE_PRIVATE int sqlite3Select(
}
pAggInfo->mxReg = pParse->nMem;
if( db->mallocFailed ) goto select_end;
-#if SELECTTRACE_ENABLED
+#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x400 ){
- int ii;
+ int ii;
SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo));
- sqlite3TreeViewSelect(0, p, 0);
+ sqlite3TreeViewSelect(0, p, 0);
if( minMaxFlag ){
sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag);
sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY");
}
for(ii=0; ii<pAggInfo->nColumn; ii++){
- sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
+ sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
ii, pAggInfo->aCol[ii].iMem);
sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0);
- }
+ }
for(ii=0; ii<pAggInfo->nFunc; ii++){
- sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",
+ sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",
ii, pAggInfo->aFunc[ii].iMem);
sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0);
- }
- }
-#endif
+ }
+ }
+#endif
+
-
/* Processing for aggregates with GROUP BY is very different and
** much more complex than aggregates without a GROUP BY.
*/
if( pGroupBy ){
KeyInfo *pKeyInfo; /* Keying information for the group by clause */
- int addr1; /* A-vs-B comparision jump */
+ int addr1; /* A-vs-B comparision jump */
int addrOutputRow; /* Start of subroutine that outputs a result row */
int regOutputRow; /* Return address register for output subroutine */
int addrSetAbort; /* Set the abort flag and return */
@@ -140437,7 +140437,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
}
regBase = sqlite3GetTempRange(pParse, nCol);
- sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
+ sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
j = nGroupBy;
for(i=0; i<pAggInfo->nColumn; i++){
struct AggInfo_col *pCol = &pAggInfo->aCol[i];
@@ -140497,8 +140497,8 @@ SQLITE_PRIVATE int sqlite3Select(
}
sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
- addr1 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v);
+ addr1 = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v);
/* Generate code that runs whenever the GROUP BY changes.
** Changes in the GROUP BY are detected by the previous code
@@ -140520,7 +140520,7 @@ SQLITE_PRIVATE int sqlite3Select(
/* Update the aggregate accumulators based on the content of
** the current row
*/
- sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeJumpHere(v, addr1);
updateAccumulator(pParse, iUseFlag, pAggInfo, eDist);
sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
VdbeComment((v, "indicate data in accumulator"));
@@ -140544,7 +140544,7 @@ SQLITE_PRIVATE int sqlite3Select(
/* Jump over the subroutines
*/
- sqlite3VdbeGoto(v, addrEnd);
+ sqlite3VdbeGoto(v, addrEnd);
/* Generate a subroutine that outputs a single row of the result
** set. This subroutine first looks at the iUseFlag. If iUseFlag
@@ -140565,7 +140565,7 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
finalizeAggFunctions(pParse, pAggInfo);
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
- selectInnerLoop(pParse, p, -1, &sSort,
+ selectInnerLoop(pParse, p, -1, &sSort,
&sDistinct, pDest,
addrOutputRow+1, addrSetAbort);
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
@@ -140682,19 +140682,19 @@ SQLITE_PRIVATE int sqlite3Select(
** processing is much simpler since there is only a single row
** of output.
*/
- assert( p->pGroupBy==0 );
+ assert( p->pGroupBy==0 );
resetAccumulator(pParse, pAggInfo);
-
- /* If this query is a candidate for the min/max optimization, then
- ** minMaxFlag will have been previously set to either
- ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will
- ** be an appropriate ORDER BY expression for the optimization.
- */
- assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
- assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
-
+
+ /* If this query is a candidate for the min/max optimization, then
+ ** minMaxFlag will have been previously set to either
+ ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will
+ ** be an appropriate ORDER BY expression for the optimization.
+ */
+ assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
+ assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
+
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
pDistinct, minMaxFlag|distFlag, 0);
if( pWInfo==0 ){
goto select_end;
@@ -140753,7 +140753,7 @@ SQLITE_PRIVATE int sqlite3Select(
select_end:
assert( db->mallocFailed==0 || db->mallocFailed==1 );
pParse->nErr += db->mallocFailed;
- sqlite3ExprListDelete(db, pMinMaxOrderBy);
+ sqlite3ExprListDelete(db, pMinMaxOrderBy);
#ifdef SQLITE_DEBUG
if( pAggInfo && !db->mallocFailed ){
for(i=0; i<pAggInfo->nColumn; i++){
@@ -140884,7 +140884,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
return 0;
malloc_failed:
- p->rc = SQLITE_NOMEM_BKPT;
+ p->rc = SQLITE_NOMEM_BKPT;
return 1;
}
@@ -140898,7 +140898,7 @@ malloc_failed:
** Instead, the entire table should be passed to sqlite3_free_table() when
** the calling procedure is finished using it.
*/
-SQLITE_API int sqlite3_get_table(
+SQLITE_API int sqlite3_get_table(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
char ***pazResult, /* Write the result table here */
@@ -140925,7 +140925,7 @@ SQLITE_API int sqlite3_get_table(
res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
if( res.azResult==0 ){
db->errCode = SQLITE_NOMEM;
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
res.azResult[0] = 0;
rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
@@ -140954,7 +140954,7 @@ SQLITE_API int sqlite3_get_table(
if( azNew==0 ){
sqlite3_free_table(&res.azResult[1]);
db->errCode = SQLITE_NOMEM;
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
res.azResult = azNew;
}
@@ -140967,7 +140967,7 @@ SQLITE_API int sqlite3_get_table(
/*
** This routine frees the space the sqlite3_get_table() malloced.
*/
-SQLITE_API void sqlite3_free_table(
+SQLITE_API void sqlite3_free_table(
char **azResult /* Result returned from sqlite3_get_table() */
){
if( azResult ){
@@ -141013,7 +141013,7 @@ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerS
sqlite3IdListDelete(db, pTmp->pIdList);
sqlite3UpsertDelete(db, pTmp->pUpsert);
sqlite3SrcListDelete(db, pTmp->pFrom);
- sqlite3DbFree(db, pTmp->zSpan);
+ sqlite3DbFree(db, pTmp->zSpan);
sqlite3DbFree(db, pTmp);
}
@@ -141218,10 +141218,10 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
#ifndef SQLITE_OMIT_AUTHORIZATION
if( !IN_RENAME_OBJECT ){
- int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
int code = SQLITE_CREATE_TRIGGER;
- const char *zDb = db->aDb[iTabDb].zDbSName;
- const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb;
+ const char *zDb = db->aDb[iTabDb].zDbSName;
+ const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb;
if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
goto trigger_cleanup;
@@ -141317,7 +141317,7 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
pStepList->pTrig = pTrig;
pStepList = pStepList->pNext;
}
- sqlite3TokenInit(&nameToken, pTrig->zName);
+ sqlite3TokenInit(&nameToken, pTrig->zName);
sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken);
if( sqlite3FixTriggerStep(&sFix, pTrig->step_list)
|| sqlite3FixExpr(&sFix, pTrig->pWhen)
@@ -141345,7 +141345,7 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
if( v==0 ) goto triggerfinish_cleanup;
sqlite3BeginWriteOperation(pParse, 0, iDb);
z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
- testcase( z==0 );
+ testcase( z==0 );
sqlite3NestedParse(pParse,
"INSERT INTO %Q." LEGACY_SCHEMA_TABLE
" VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
@@ -141364,7 +141364,7 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
assert( pLink!=0 );
pTrig = sqlite3HashInsert(pHash, zName, pTrig);
if( pTrig ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
}else if( pLink->pSchema==pLink->pTabSchema ){
Table *pTab;
pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table);
@@ -141381,29 +141381,29 @@ triggerfinish_cleanup:
}
/*
-** Duplicate a range of text from an SQL statement, then convert all
-** whitespace characters into ordinary space characters.
-*/
-static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
- char *z = sqlite3DbSpanDup(db, zStart, zEnd);
- int i;
- if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' ';
- return z;
+** Duplicate a range of text from an SQL statement, then convert all
+** whitespace characters into ordinary space characters.
+*/
+static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
+ char *z = sqlite3DbSpanDup(db, zStart, zEnd);
+ int i;
+ if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' ';
+ return z;
}
-
-/*
+
+/*
** Turn a SELECT statement (that the pSelect parameter points to) into
** a trigger step. Return a pointer to a TriggerStep structure.
**
** The parser calls this routine when it finds a SELECT statement in
** body of a TRIGGER.
*/
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(
- sqlite3 *db, /* Database connection */
- Select *pSelect, /* The SELECT statement */
- const char *zStart, /* Start of SQL text */
- const char *zEnd /* End of SQL text */
-){
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(
+ sqlite3 *db, /* Database connection */
+ Select *pSelect, /* The SELECT statement */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
+){
TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
if( pTriggerStep==0 ) {
sqlite3SelectDelete(db, pSelect);
@@ -141412,7 +141412,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(
pTriggerStep->op = TK_SELECT;
pTriggerStep->pSelect = pSelect;
pTriggerStep->orconf = OE_Default;
- pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
+ pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
return pTriggerStep;
}
@@ -141425,9 +141425,9 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(
static TriggerStep *triggerStepAllocate(
Parse *pParse, /* Parser context */
u8 op, /* Trigger opcode */
- Token *pName, /* The target name */
- const char *zStart, /* Start of SQL text */
- const char *zEnd /* End of SQL text */
+ Token *pName, /* The target name */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
sqlite3 *db = pParse->db;
TriggerStep *pTriggerStep;
@@ -141439,7 +141439,7 @@ static TriggerStep *triggerStepAllocate(
sqlite3Dequote(z);
pTriggerStep->zTarget = z;
pTriggerStep->op = op;
- pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
+ pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName);
}
@@ -141459,10 +141459,10 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
Token *pTableName, /* Name of the table into which we insert */
IdList *pColumn, /* List of columns in pTableName to insert into */
Select *pSelect, /* A SELECT statement that supplies values */
- u8 orconf, /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
+ u8 orconf, /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
Upsert *pUpsert, /* ON CONFLICT clauses for upsert */
- const char *zStart, /* Start of SQL text */
- const char *zEnd /* End of SQL text */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
sqlite3 *db = pParse->db;
TriggerStep *pTriggerStep;
@@ -141505,9 +141505,9 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
SrcList *pFrom,
ExprList *pEList, /* The SET clause: list of column and new values */
Expr *pWhere, /* The WHERE clause */
- u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
- const char *zStart, /* Start of SQL text */
- const char *zEnd /* End of SQL text */
+ u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
sqlite3 *db = pParse->db;
TriggerStep *pTriggerStep;
@@ -141542,9 +141542,9 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(
Parse *pParse, /* Parser */
Token *pTableName, /* The table from which rows are deleted */
- Expr *pWhere, /* The WHERE clause */
- const char *zStart, /* Start of SQL text */
- const char *zEnd /* End of SQL text */
+ Expr *pWhere, /* The WHERE clause */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
sqlite3 *db = pParse->db;
TriggerStep *pTriggerStep;
@@ -141647,7 +141647,7 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
#ifndef SQLITE_OMIT_AUTHORIZATION
if( pTable ){
int code = SQLITE_DROP_TRIGGER;
- const char *zDb = db->aDb[iDb].zDbSName;
+ const char *zDb = db->aDb[iDb].zDbSName;
const char *zTab = SCHEMA_TABLE(iDb);
if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) ||
@@ -141660,10 +141660,10 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
/* Generate code to destroy the database record of the trigger.
*/
if( (v = sqlite3GetVdbe(pParse))!=0 ){
- sqlite3NestedParse(pParse,
+ sqlite3NestedParse(pParse,
"DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
db->aDb[iDb].zDbSName, pTrigger->zName
- );
+ );
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
}
@@ -141693,7 +141693,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const ch
}
}
sqlite3DeleteTrigger(db, pTrigger);
- db->mDbFlags |= DBFLAG_SchemaChange;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
}
@@ -141989,14 +141989,14 @@ static int codeTriggerProgram(
pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
assert( pParse->okConstFactor==0 );
-#ifndef SQLITE_OMIT_TRACE
- if( pStep->zSpan ){
- sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0,
- sqlite3MPrintf(db, "-- %s", pStep->zSpan),
- P4_DYNAMIC);
- }
-#endif
-
+#ifndef SQLITE_OMIT_TRACE
+ if( pStep->zSpan ){
+ sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0,
+ sqlite3MPrintf(db, "-- %s", pStep->zSpan),
+ P4_DYNAMIC);
+ }
+#endif
+
switch( pStep->op ){
case TK_UPDATE: {
sqlite3Update(pParse,
@@ -142022,7 +142022,7 @@ static int codeTriggerProgram(
case TK_DELETE: {
sqlite3DeleteFrom(pParse,
sqlite3TriggerStepSrc(pParse, pStep),
- sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0
+ sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0
);
sqlite3VdbeAddOp0(v, OP_ResetCount);
break;
@@ -142139,11 +142139,11 @@ static TriggerPrg *codeRowTrigger(
pTab->zName
));
#ifndef SQLITE_OMIT_TRACE
- if( pTrigger->zName ){
+ if( pTrigger->zName ){
sqlite3VdbeChangeP4(v, -1,
- sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
- );
- }
+ sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
+ );
+ }
#endif
/* If one was specified, code the WHEN clause. If it evaluates to false
@@ -142171,7 +142171,7 @@ static TriggerPrg *codeRowTrigger(
VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
transferParseError(pParse, pSubParse);
- if( db->mallocFailed==0 && pParse->nErr==0 ){
+ if( db->mallocFailed==0 && pParse->nErr==0 ){
pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
}
pProgram->nMem = pSubParse->nMem;
@@ -142247,8 +142247,8 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(
if( pPrg ){
int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers));
- sqlite3VdbeAddOp4(v, OP_Program, reg, ignoreJump, ++pParse->nMem,
- (const char *)pPrg->pProgram, P4_SUBPROGRAM);
+ sqlite3VdbeAddOp4(v, OP_Program, reg, ignoreJump, ++pParse->nMem,
+ (const char *)pPrg->pProgram, P4_SUBPROGRAM);
VdbeComment(
(v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf)));
@@ -142481,13 +142481,13 @@ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
sqlite3ColumnExpr(pTab,pCol), enc,
pCol->affinity, &pValue);
if( pValue ){
- sqlite3VdbeAppendP4(v, pValue, P4_MEM);
+ sqlite3VdbeAppendP4(v, pValue, P4_MEM);
}
- }
+ }
#ifndef SQLITE_OMIT_FLOATING_POINT
if( pTab->aCol[i].affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){
- sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
- }
+ sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
+ }
#endif
}
@@ -142694,8 +142694,8 @@ SQLITE_PRIVATE void sqlite3Update(
SrcList *pTabList, /* The table in which we should change things */
ExprList *pChanges, /* Things to be changed */
Expr *pWhere, /* The WHERE clause. May be null */
- int onError, /* How to handle constraint errors */
- ExprList *pOrderBy, /* ORDER BY clause. May be null */
+ int onError, /* How to handle constraint errors */
+ ExprList *pOrderBy, /* ORDER BY clause. May be null */
Expr *pLimit, /* LIMIT clause. May be null */
Upsert *pUpsert /* ON CONFLICT clause, or null */
){
@@ -142725,11 +142725,11 @@ SQLITE_PRIVATE void sqlite3Update(
AuthContext sContext; /* The authorization context */
NameContext sNC; /* The name-context to resolve expressions in */
int iDb; /* Database containing the table being updated */
- int eOnePass; /* ONEPASS_XXX value from where.c */
+ int eOnePass; /* ONEPASS_XXX value from where.c */
int hasFK; /* True if foreign key processing is required */
int labelBreak; /* Jump here to break out of UPDATE loop */
int labelContinue; /* Jump here to continue next step of UPDATE loop */
- int flags; /* Flags for sqlite3WhereBegin() */
+ int flags; /* Flags for sqlite3WhereBegin() */
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True when updating a view (INSTEAD OF trigger) */
@@ -142740,18 +142740,18 @@ SQLITE_PRIVATE void sqlite3Update(
int iEph = 0; /* Ephemeral table holding all primary key values */
int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */
int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
- int addrOpen = 0; /* Address of OP_OpenEphemeral */
- int iPk = 0; /* First of nPk cells holding PRIMARY KEY value */
- i16 nPk = 0; /* Number of components of the PRIMARY KEY */
- int bReplace = 0; /* True if REPLACE conflict resolution might happen */
+ int addrOpen = 0; /* Address of OP_OpenEphemeral */
+ int iPk = 0; /* First of nPk cells holding PRIMARY KEY value */
+ i16 nPk = 0; /* Number of components of the PRIMARY KEY */
+ int bReplace = 0; /* True if REPLACE conflict resolution might happen */
int bFinishSeek = 1; /* The OP_FinishSeek opcode is needed */
int nChangeFrom = 0; /* If there is a FROM, pChanges->nExpr, else 0 */
/* Register Allocations */
int regRowCount = 0; /* A count of rows changed */
- int regOldRowid = 0; /* The old rowid */
- int regNewRowid = 0; /* The new rowid */
- int regNew = 0; /* Content of the NEW.* table in triggers */
+ int regOldRowid = 0; /* The old rowid */
+ int regNewRowid = 0; /* The new rowid */
+ int regNew = 0; /* Content of the NEW.* table in triggers */
int regOld = 0; /* Content of OLD.* table in triggers */
int regRowSet = 0; /* Rowset of rows to be updated */
int regKey = 0; /* composite PRIMARY KEY value */
@@ -142792,16 +142792,16 @@ SQLITE_PRIVATE void sqlite3Update(
nChangeFrom = (pTabList->nSrc>1) ? pChanges->nExpr : 0;
assert( nChangeFrom==0 || pUpsert==0 );
-#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
+#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
if( !isView && nChangeFrom==0 ){
- pWhere = sqlite3LimitWhere(
- pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE"
- );
- pOrderBy = 0;
- pLimit = 0;
- }
-#endif
-
+ pWhere = sqlite3LimitWhere(
+ pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE"
+ );
+ pOrderBy = 0;
+ pLimit = 0;
+ }
+#endif
+
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
goto update_cleanup;
}
@@ -142910,7 +142910,7 @@ SQLITE_PRIVATE void sqlite3Update(
int rc;
rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
j<0 ? "ROWID" : pTab->aCol[j].zCnName,
- db->aDb[iDb].zDbSName);
+ db->aDb[iDb].zDbSName);
if( rc==SQLITE_DENY ){
goto update_cleanup;
}else if( rc==SQLITE_IGNORE ){
@@ -142954,17 +142954,17 @@ SQLITE_PRIVATE void sqlite3Update(
#endif
/* The SET expressions are not actually used inside the WHERE loop.
- ** So reset the colUsed mask. Unless this is a virtual table. In that
- ** case, set all bits of the colUsed mask (to ensure that the virtual
- ** table implementation makes all columns available).
+ ** So reset the colUsed mask. Unless this is a virtual table. In that
+ ** case, set all bits of the colUsed mask (to ensure that the virtual
+ ** table implementation makes all columns available).
*/
- pTabList->a[0].colUsed = IsVirtual(pTab) ? ALLBITS : 0;
+ pTabList->a[0].colUsed = IsVirtual(pTab) ? ALLBITS : 0;
hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
/* There is one entry in the aRegIdx[] array for each index on the table
** being updated. Fill in aRegIdx[] with a register number that will hold
- ** the key for accessing each index.
+ ** the key for accessing each index.
*/
if( onError==OE_Replace ) bReplace = 1;
for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){
@@ -142973,16 +142973,16 @@ SQLITE_PRIVATE void sqlite3Update(
|| indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
){
reg = ++pParse->nMem;
- pParse->nMem += pIdx->nColumn;
+ pParse->nMem += pIdx->nColumn;
}else{
reg = 0;
for(i=0; i<pIdx->nKeyCol; i++){
if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
reg = ++pParse->nMem;
- pParse->nMem += pIdx->nColumn;
+ pParse->nMem += pIdx->nColumn;
if( onError==OE_Default && pIdx->onError==OE_Replace ){
- bReplace = 1;
- }
+ bReplace = 1;
+ }
break;
}
}
@@ -142991,17 +142991,17 @@ SQLITE_PRIVATE void sqlite3Update(
aRegIdx[nAllIdx] = reg;
}
aRegIdx[nAllIdx] = ++pParse->nMem; /* Register storing the table record */
- if( bReplace ){
+ if( bReplace ){
/* If REPLACE conflict resolution might be invoked, open cursors on all
- ** indexes in case they are needed to delete records. */
- memset(aToOpen, 1, nIdx+1);
- }
+ ** indexes in case they are needed to delete records. */
+ memset(aToOpen, 1, nIdx+1);
+ }
if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb);
/* Allocate required registers. */
- if( !IsVirtual(pTab) ){
+ if( !IsVirtual(pTab) ){
/* For now, regRowSet and aRegIdx[nAllIdx] share the same register.
** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be
** reallocated. aRegIdx[nAllIdx] is the register in which the main
@@ -143009,15 +143009,15 @@ SQLITE_PRIVATE void sqlite3Update(
** two-pass update algorithm. */
assert( aRegIdx[nAllIdx]==pParse->nMem );
regRowSet = aRegIdx[nAllIdx];
- regOldRowid = regNewRowid = ++pParse->nMem;
- if( chngPk || pTrigger || hasFK ){
- regOld = pParse->nMem + 1;
- pParse->nMem += pTab->nCol;
- }
- if( chngKey || pTrigger || hasFK ){
- regNewRowid = ++pParse->nMem;
- }
- regNew = pParse->nMem + 1;
+ regOldRowid = regNewRowid = ++pParse->nMem;
+ if( chngPk || pTrigger || hasFK ){
+ regOld = pParse->nMem + 1;
+ pParse->nMem += pTab->nCol;
+ }
+ if( chngKey || pTrigger || hasFK ){
+ regNewRowid = ++pParse->nMem;
+ }
+ regNew = pParse->nMem + 1;
pParse->nMem += pTab->nCol;
}
@@ -143032,10 +143032,10 @@ SQLITE_PRIVATE void sqlite3Update(
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( nChangeFrom==0 && isView ){
sqlite3MaterializeView(pParse, pTab,
- pWhere, pOrderBy, pLimit, iDataCur
- );
- pOrderBy = 0;
- pLimit = 0;
+ pWhere, pOrderBy, pLimit, iDataCur
+ );
+ pOrderBy = 0;
+ pLimit = 0;
}
#endif
@@ -143046,15 +143046,15 @@ SQLITE_PRIVATE void sqlite3Update(
goto update_cleanup;
}
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Virtual tables must be handled separately */
- if( IsVirtual(pTab) ){
- updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
- pWhere, onError);
- goto update_cleanup;
- }
-#endif
-
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ /* Virtual tables must be handled separately */
+ if( IsVirtual(pTab) ){
+ updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
+ pWhere, onError);
+ goto update_cleanup;
+ }
+#endif
+
/* Jump to labelBreak to abandon further processing of this UPDATE */
labelContinue = labelBreak = sqlite3VdbeMakeLabel(pParse);
@@ -143066,10 +143066,10 @@ SQLITE_PRIVATE void sqlite3Update(
&& !pParse->bReturning
&& pUpsert==0
){
- regRowCount = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
- }
-
+ regRowCount = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
+ }
+
if( nChangeFrom==0 && HasRowid(pTab) ){
sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
iEph = pParse->nTab++;
@@ -143102,7 +143102,7 @@ SQLITE_PRIVATE void sqlite3Update(
#endif
}
}
- }
+ }
if( nChangeFrom ){
sqlite3MultiWrite(pParse);
@@ -143158,7 +143158,7 @@ SQLITE_PRIVATE void sqlite3Update(
}
}
}
-
+
if( HasRowid(pTab) ){
/* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
** mode, write the rowid into the FIFO. In either of the one-pass modes,
@@ -143215,7 +143215,7 @@ SQLITE_PRIVATE void sqlite3Update(
if( addrOnce ){
sqlite3VdbeJumpHereOrPopInst(v, addrOnce);
}
- }
+ }
/* Top of the update loop */
if( eOnePass!=ONEPASS_OFF ){
@@ -143260,14 +143260,14 @@ SQLITE_PRIVATE void sqlite3Update(
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey,0);
VdbeCoverage(v);
}
- }else{
+ }else{
sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
labelContinue = sqlite3VdbeMakeLabel(pParse);
addrTop = sqlite3VdbeAddOp2(v, OP_Rowid, iEph, regOldRowid);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
VdbeCoverage(v);
- }
+ }
}
/* If the rowid value will change, set register regNewRowid to
@@ -143417,7 +143417,7 @@ SQLITE_PRIVATE void sqlite3Update(
/* Do constraint checks. */
assert( regOldRowid>0 );
sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
- regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
+ regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
aXRef, 0);
/* If REPLACE conflict handling may have been used, or if the PK of the
@@ -143438,8 +143438,8 @@ SQLITE_PRIVATE void sqlite3Update(
}
/* Delete the index entries associated with the current record. */
- sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);
-
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);
+
/* We must run the OP_FinishSeek opcode to resolve a prior
** OP_DeferredSeek if there is any possibility that there have been
** no OP_Column opcodes since the OP_DeferredSeek was issued. But
@@ -143449,44 +143449,44 @@ SQLITE_PRIVATE void sqlite3Update(
sqlite3VdbeAddOp1(v, OP_FinishSeek, iDataCur);
}
- /* If changing the rowid value, or if there are foreign key constraints
- ** to process, delete the old record. Otherwise, add a noop OP_Delete
- ** to invoke the pre-update hook.
- **
+ /* If changing the rowid value, or if there are foreign key constraints
+ ** to process, delete the old record. Otherwise, add a noop OP_Delete
+ ** to invoke the pre-update hook.
+ **
** That (regNew==regnewRowid+1) is true is also important for the
- ** pre-update hook. If the caller invokes preupdate_new(), the returned
- ** value is copied from memory cell (regNewRowid+1+iCol), where iCol
- ** is the column index supplied by the user.
- */
- assert( regNew==regNewRowid+1 );
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
- sqlite3VdbeAddOp3(v, OP_Delete, iDataCur,
- OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP),
- regNewRowid
- );
- if( eOnePass==ONEPASS_MULTI ){
- assert( hasFK==0 && chngKey==0 );
- sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
- }
- if( !pParse->nested ){
- sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
- }
-#else
- if( hasFK>1 || chngKey ){
+ ** pre-update hook. If the caller invokes preupdate_new(), the returned
+ ** value is copied from memory cell (regNewRowid+1+iCol), where iCol
+ ** is the column index supplied by the user.
+ */
+ assert( regNew==regNewRowid+1 );
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ sqlite3VdbeAddOp3(v, OP_Delete, iDataCur,
+ OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP),
+ regNewRowid
+ );
+ if( eOnePass==ONEPASS_MULTI ){
+ assert( hasFK==0 && chngKey==0 );
+ sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
+ }
+ if( !pParse->nested ){
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
+ }
+#else
+ if( hasFK>1 || chngKey ){
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
}
-#endif
+#endif
if( hasFK ){
sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey);
}
/* Insert the new index entries and the new record. */
- sqlite3CompleteInsertion(
+ sqlite3CompleteInsertion(
pParse, pTab, iDataCur, iIdxCur, regNewRowid, aRegIdx,
OPFLAG_ISUPDATE | (eOnePass==ONEPASS_MULTI ? OPFLAG_SAVEPOSITION : 0),
- 0, 0
- );
+ 0, 0
+ );
/* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
** handle rows (possibly in other tables) that refer via a foreign key
@@ -143508,11 +143508,11 @@ SQLITE_PRIVATE void sqlite3Update(
/* Repeat the above with the next record to be updated, until
** all record selected by the WHERE clause have been updated.
*/
- if( eOnePass==ONEPASS_SINGLE ){
+ if( eOnePass==ONEPASS_SINGLE ){
/* Nothing to do at end-of-loop for a single-pass */
- }else if( eOnePass==ONEPASS_MULTI ){
- sqlite3VdbeResolveLabel(v, labelContinue);
- sqlite3WhereEnd(pWInfo);
+ }else if( eOnePass==ONEPASS_MULTI ){
+ sqlite3VdbeResolveLabel(v, labelContinue);
+ sqlite3WhereEnd(pWInfo);
}else{
sqlite3VdbeResolveLabel(v, labelContinue);
sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v);
@@ -143544,9 +143544,9 @@ update_cleanup:
sqlite3ExprListDelete(db, pChanges);
sqlite3ExprDelete(db, pWhere);
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
- sqlite3ExprListDelete(db, pOrderBy);
- sqlite3ExprDelete(db, pLimit);
-#endif
+ sqlite3ExprListDelete(db, pOrderBy);
+ sqlite3ExprDelete(db, pLimit);
+#endif
return;
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
@@ -143565,21 +143565,21 @@ update_cleanup:
**
** There are two possible strategies - the default and the special
** "onepass" strategy. Onepass is only used if the virtual table
-** implementation indicates that pWhere may match at most one row.
-**
-** The default strategy is to create an ephemeral table that contains
+** implementation indicates that pWhere may match at most one row.
+**
+** The default strategy is to create an ephemeral table that contains
** for each row to be changed:
**
** (A) The original rowid of that row.
-** (B) The revised rowid for the row.
+** (B) The revised rowid for the row.
** (C) The content of every column in the row.
**
-** Then loop through the contents of this ephemeral table executing a
-** VUpdate for each row. When finished, drop the ephemeral table.
+** Then loop through the contents of this ephemeral table executing a
+** VUpdate for each row. When finished, drop the ephemeral table.
**
-** The "onepass" strategy does not use an ephemeral table. Instead, it
-** stores the same values (A, B and C above) in a register array and
-** makes a single invocation of VUpdate.
+** The "onepass" strategy does not use an ephemeral table. Instead, it
+** stores the same values (A, B and C above) in a register array and
+** makes a single invocation of VUpdate.
*/
static void updateVirtualTable(
Parse *pParse, /* The parsing context */
@@ -143597,23 +143597,23 @@ static void updateVirtualTable(
sqlite3 *db = pParse->db; /* Database connection */
const char *pVTab = (const char*)sqlite3GetVTable(db, pTab);
WhereInfo *pWInfo = 0;
- int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */
- int regArg; /* First register in VUpdate arg array */
- int regRec; /* Register in which to assemble record */
- int regRowid; /* Register for ephem table rowid */
- int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */
- int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */
+ int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */
+ int regArg; /* First register in VUpdate arg array */
+ int regRec; /* Register in which to assemble record */
+ int regRowid; /* Register for ephem table rowid */
+ int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */
+ int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */
int eOnePass; /* True to use onepass strategy */
- int addr; /* Address of OP_OpenEphemeral */
-
- /* Allocate nArg registers in which to gather the arguments for VUpdate. Then
- ** create and open the ephemeral table in which the records created from
- ** these arguments will be temporarily stored. */
- assert( v );
- ephemTab = pParse->nTab++;
- addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg);
- regArg = pParse->nMem + 1;
- pParse->nMem += nArg;
+ int addr; /* Address of OP_OpenEphemeral */
+
+ /* Allocate nArg registers in which to gather the arguments for VUpdate. Then
+ ** create and open the ephemeral table in which the records created from
+ ** these arguments will be temporarily stored. */
+ assert( v );
+ ephemTab = pParse->nTab++;
+ addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg);
+ regArg = pParse->nMem + 1;
+ pParse->nMem += nArg;
if( pSrc->nSrc>1 ){
Index *pPk = 0;
Expr *pRow;
@@ -143637,7 +143637,7 @@ static void updateVirtualTable(
}
}
pList = sqlite3ExprListAppend(pParse, 0, pRow);
-
+
for(i=0; i<pTab->nCol; i++){
if( aXRef[i]>=0 ){
pList = sqlite3ExprListAppend(pParse, pList,
@@ -143647,7 +143647,7 @@ static void updateVirtualTable(
pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i));
}
}
-
+
updateFromSelect(pParse, ephemTab, pPk, pList, pSrc, pWhere, 0, 0);
sqlite3ExprListDelete(db, pList);
eOnePass = ONEPASS_OFF;
@@ -143676,7 +143676,7 @@ static void updateVirtualTable(
}else{
sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1);
}
- }else{
+ }else{
Index *pPk; /* PRIMARY KEY index */
i16 iPk; /* PRIMARY KEY column */
pPk = sqlite3PrimaryKeyIndex(pTab);
@@ -143685,7 +143685,7 @@ static void updateVirtualTable(
iPk = pPk->aiColumn[0];
sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, iPk, regArg);
sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1);
- }
+ }
eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
@@ -143706,42 +143706,42 @@ static void updateVirtualTable(
/* Signal an assert() within OP_MakeRecord that it is allowed to
** accept no-change records with serial_type 10 */
sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC);
-#endif
+#endif
sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
}
}
-
-
+
+
if( eOnePass==ONEPASS_OFF ){
- /* End the virtual table scan */
+ /* End the virtual table scan */
if( pSrc->nSrc==1 ){
sqlite3WhereEnd(pWInfo);
}
-
- /* Begin scannning through the ephemeral table. */
- addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v);
-
+
+ /* Begin scannning through the ephemeral table. */
+ addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v);
+
/* Extract arguments from the current row of the ephemeral table and
- ** invoke the VUpdate method. */
- for(i=0; i<nArg; i++){
- sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i, regArg+i);
- }
- }
+ ** invoke the VUpdate method. */
+ for(i=0; i<nArg; i++){
+ sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i, regArg+i);
+ }
+ }
sqlite3VtabMakeWritable(pParse, pTab);
- sqlite3VdbeAddOp4(v, OP_VUpdate, 0, nArg, regArg, pVTab, P4_VTAB);
+ sqlite3VdbeAddOp4(v, OP_VUpdate, 0, nArg, regArg, pVTab, P4_VTAB);
sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
sqlite3MayAbort(pParse);
- /* End of the ephemeral table scan. Or, if using the onepass strategy,
- ** jump to here if the scan visited zero rows. */
+ /* End of the ephemeral table scan. Or, if using the onepass strategy,
+ ** jump to here if the scan visited zero rows. */
if( eOnePass==ONEPASS_OFF ){
- sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
- sqlite3VdbeJumpHere(v, addr);
- sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
- }else{
- sqlite3WhereEnd(pWInfo);
- }
+ sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addr);
+ sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
+ }else{
+ sqlite3WhereEnd(pWInfo);
+ }
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -144087,25 +144087,25 @@ SQLITE_PRIVATE void sqlite3UpsertDoUpdate(
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/*
-** Execute zSql on database db.
-**
-** If zSql returns rows, then each row will have exactly one
-** column. (This will only happen if zSql begins with "SELECT".)
-** Take each row of result and call execSql() again recursively.
-**
-** The execSqlF() routine does the same thing, except it accepts
-** a format string as its third argument
+** Execute zSql on database db.
+**
+** If zSql returns rows, then each row will have exactly one
+** column. (This will only happen if zSql begins with "SELECT".)
+** Take each row of result and call execSql() again recursively.
+**
+** The execSqlF() routine does the same thing, except it accepts
+** a format string as its third argument
*/
static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
sqlite3_stmt *pStmt;
int rc;
- /* printf("SQL: [%s]\n", zSql); fflush(stdout); */
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
+ /* printf("SQL: [%s]\n", zSql); fflush(stdout); */
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
if( rc!=SQLITE_OK ) return rc;
- while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
- const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
- assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
+ while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
+ const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
+ assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
/* The secondary SQL must be one of CREATE TABLE, CREATE INDEX,
** or INSERT. Historically there have been attacks that first
** corrupt the sqlite_schema.sql field with other kinds of statements
@@ -144114,30 +144114,30 @@ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
if( zSubSql
&& (strncmp(zSubSql,"CRE",3)==0 || strncmp(zSubSql,"INS",3)==0)
){
- rc = execSql(db, pzErrMsg, zSubSql);
- if( rc!=SQLITE_OK ) break;
- }
- }
- assert( rc!=SQLITE_ROW );
- if( rc==SQLITE_DONE ) rc = SQLITE_OK;
- if( rc ){
- sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
- }
- (void)sqlite3_finalize(pStmt);
- return rc;
-}
-static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
- char *z;
- va_list ap;
- int rc;
- va_start(ap, zSql);
- z = sqlite3VMPrintf(db, zSql, ap);
- va_end(ap);
- if( z==0 ) return SQLITE_NOMEM;
- rc = execSql(db, pzErrMsg, z);
- sqlite3DbFree(db, z);
- return rc;
-}
+ rc = execSql(db, pzErrMsg, zSubSql);
+ if( rc!=SQLITE_OK ) break;
+ }
+ }
+ assert( rc!=SQLITE_ROW );
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ if( rc ){
+ sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
+ }
+ (void)sqlite3_finalize(pStmt);
+ return rc;
+}
+static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
+ char *z;
+ va_list ap;
+ int rc;
+ va_start(ap, zSql);
+ z = sqlite3VMPrintf(db, zSql, ap);
+ va_end(ap);
+ if( z==0 ) return SQLITE_NOMEM;
+ rc = execSql(db, pzErrMsg, z);
+ sqlite3DbFree(db, z);
+ return rc;
+}
/*
** The VACUUM command is used to clean up the database,
@@ -144171,34 +144171,34 @@ static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
*/
SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){
Vdbe *v = sqlite3GetVdbe(pParse);
- int iDb = 0;
+ int iDb = 0;
if( v==0 ) goto build_vacuum_end;
if( pParse->nErr ) goto build_vacuum_end;
- if( pNm ){
-#ifndef SQLITE_BUG_COMPATIBLE_20160819
- /* Default behavior: Report an error if the argument to VACUUM is
- ** not recognized */
- iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
+ if( pNm ){
+#ifndef SQLITE_BUG_COMPATIBLE_20160819
+ /* Default behavior: Report an error if the argument to VACUUM is
+ ** not recognized */
+ iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
if( iDb<0 ) goto build_vacuum_end;
-#else
- /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments
- ** to VACUUM are silently ignored. This is a back-out of a bug fix that
- ** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270).
- ** The buggy behavior is required for binary compatibility with some
- ** legacy applications. */
- iDb = sqlite3FindDb(pParse->db, pNm);
- if( iDb<0 ) iDb = 0;
-#endif
- }
- if( iDb!=1 ){
+#else
+ /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments
+ ** to VACUUM are silently ignored. This is a back-out of a bug fix that
+ ** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270).
+ ** The buggy behavior is required for binary compatibility with some
+ ** legacy applications. */
+ iDb = sqlite3FindDb(pParse->db, pNm);
+ if( iDb<0 ) iDb = 0;
+#endif
+ }
+ if( iDb!=1 ){
int iIntoReg = 0;
if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){
iIntoReg = ++pParse->nMem;
sqlite3ExprCode(pParse, pInto, iIntoReg);
}
sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg);
- sqlite3VdbeUsesBtree(v, iDb);
- }
+ sqlite3VdbeUsesBtree(v, iDb);
+ }
build_vacuum_end:
sqlite3ExprDelete(pParse->db, pInto);
return;
@@ -144221,12 +144221,12 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
i64 saved_nChange; /* Saved value of db->nChange */
i64 saved_nTotalChange; /* Saved value of db->nTotalChange */
u32 saved_openFlags; /* Saved value of db->openFlags */
- u8 saved_mTrace; /* Saved trace settings */
+ u8 saved_mTrace; /* Saved trace settings */
Db *pDb = 0; /* Database to detach at end of vacuum */
int isMemDb; /* True if vacuuming a :memory: database */
int nRes; /* Bytes of reserved space at the end of each page */
int nDb; /* Number of attached databases */
- const char *zDbMain; /* Schema name of database to vacuum */
+ const char *zDbMain; /* Schema name of database to vacuum */
const char *zOut; /* Name of output file */
if( !db->autoCommit ){
@@ -144254,18 +144254,18 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
** restored before returning. Then set the writable-schema flag, and
** disable CHECK and foreign key constraints. */
saved_flags = db->flags;
- saved_mDbFlags = db->mDbFlags;
+ saved_mDbFlags = db->mDbFlags;
saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange;
- saved_mTrace = db->mTrace;
- db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
- db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
+ saved_mTrace = db->mTrace;
+ db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
+ db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder
| SQLITE_Defensive | SQLITE_CountRows);
- db->mTrace = 0;
+ db->mTrace = 0;
- zDbMain = db->aDb[iDb].zDbSName;
- pMain = db->aDb[iDb].pBt;
+ zDbMain = db->aDb[iDb].zDbSName;
+ pMain = db->aDb[iDb].pBt;
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
/* Attach the temporary database as 'vacuum_db'. The synchronous pragma
@@ -144286,10 +144286,10 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut);
db->openFlags = saved_openFlags;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
- assert( (db->nDb-1)==nDb );
- pDb = &db->aDb[nDb];
- assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
- pTemp = pDb->pBt;
+ assert( (db->nDb-1)==nDb );
+ pDb = &db->aDb[nDb];
+ assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
+ pTemp = pDb->pBt;
if( pOut ){
sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
i64 sz = 0;
@@ -144302,15 +144302,15 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
}
nRes = sqlite3BtreeGetRequestedReserve(pMain);
- sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
- sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
- sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL);
+ sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
+ sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
+ sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL);
/* Begin a transaction and take an exclusive lock on the main database
** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
** to ensure that we do not try to change the page-size on a WAL database.
*/
- rc = execSql(db, pzErrMsg, "BEGIN");
+ rc = execSql(db, pzErrMsg, "BEGIN");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
@@ -144327,7 +144327,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
|| (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
|| NEVER(db->mallocFailed)
){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
goto end_of_vacuum;
}
@@ -144339,35 +144339,35 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
/* Query the schema of the main database. Create a mirror schema
** in the temporary database.
*/
- db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */
- rc = execSqlF(db, pzErrMsg,
+ db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */
+ rc = execSqlF(db, pzErrMsg,
"SELECT sql FROM \"%w\".sqlite_schema"
- " WHERE type='table'AND name<>'sqlite_sequence'"
- " AND coalesce(rootpage,1)>0",
- zDbMain
+ " WHERE type='table'AND name<>'sqlite_sequence'"
+ " AND coalesce(rootpage,1)>0",
+ zDbMain
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = execSqlF(db, pzErrMsg,
+ rc = execSqlF(db, pzErrMsg,
"SELECT sql FROM \"%w\".sqlite_schema"
" WHERE type='index'",
- zDbMain
- );
+ zDbMain
+ );
if( rc!=SQLITE_OK ) goto end_of_vacuum;
- db->init.iDb = 0;
+ db->init.iDb = 0;
/* Loop through the tables in the main database. For each, do
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
** the contents to the temporary database.
*/
- rc = execSqlF(db, pzErrMsg,
- "SELECT'INSERT INTO vacuum_db.'||quote(name)"
- "||' SELECT*FROM\"%w\".'||quote(name)"
+ rc = execSqlF(db, pzErrMsg,
+ "SELECT'INSERT INTO vacuum_db.'||quote(name)"
+ "||' SELECT*FROM\"%w\".'||quote(name)"
"FROM vacuum_db.sqlite_schema "
- "WHERE type='table'AND coalesce(rootpage,1)>0",
- zDbMain
+ "WHERE type='table'AND coalesce(rootpage,1)>0",
+ zDbMain
);
- assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
- db->mDbFlags &= ~DBFLAG_Vacuum;
+ assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
+ db->mDbFlags &= ~DBFLAG_Vacuum;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy the triggers, views, and virtual tables from the main database
@@ -144375,12 +144375,12 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
** associated storage, so all we have to do is copy their entries
** from the schema table.
*/
- rc = execSqlF(db, pzErrMsg,
+ rc = execSqlF(db, pzErrMsg,
"INSERT INTO vacuum_db.sqlite_schema"
" SELECT*FROM \"%w\".sqlite_schema"
- " WHERE type IN('view','trigger')"
- " OR(type='table'AND rootpage=0)",
- zDbMain
+ " WHERE type IN('view','trigger')"
+ " OR(type='table'AND rootpage=0)",
+ zDbMain
);
if( rc ) goto end_of_vacuum;
@@ -144440,12 +144440,12 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
end_of_vacuum:
/* Restore the original value of db->flags */
- db->init.iDb = 0;
- db->mDbFlags = saved_mDbFlags;
+ db->init.iDb = 0;
+ db->mDbFlags = saved_mDbFlags;
db->flags = saved_flags;
db->nChange = saved_nChange;
db->nTotalChange = saved_nTotalChange;
- db->mTrace = saved_mTrace;
+ db->mTrace = saved_mTrace;
sqlite3BtreeSetPageSize(pMain, -1, 0, 1);
/* Currently there is an SQL level transaction open on the vacuum
@@ -144505,27 +144505,27 @@ struct VtabCtx {
};
/*
-** Construct and install a Module object for a virtual table. When this
-** routine is called, it is guaranteed that all appropriate locks are held
-** and the module is not already part of the connection.
+** Construct and install a Module object for a virtual table. When this
+** routine is called, it is guaranteed that all appropriate locks are held
+** and the module is not already part of the connection.
**
** If there already exists a module with zName, replace it with the new one.
** If pModule==0, then delete the module zName if it exists.
-*/
-SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
- sqlite3 *db, /* Database in which module is registered */
- const char *zName, /* Name assigned to this module */
- const sqlite3_module *pModule, /* The definition of the module */
- void *pAux, /* Context pointer for xCreate/xConnect */
- void (*xDestroy)(void *) /* Module destructor function */
-){
- Module *pMod;
+*/
+SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
+ sqlite3 *db, /* Database in which module is registered */
+ const char *zName, /* Name assigned to this module */
+ const sqlite3_module *pModule, /* The definition of the module */
+ void *pAux, /* Context pointer for xCreate/xConnect */
+ void (*xDestroy)(void *) /* Module destructor function */
+){
+ Module *pMod;
Module *pDel;
char *zCopy;
if( pModule==0 ){
zCopy = (char*)zName;
pMod = 0;
- }else{
+ }else{
int nName = sqlite3Strlen30(zName);
pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1);
if( pMod==0 ){
@@ -144533,29 +144533,29 @@ SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
return 0;
}
zCopy = (char *)(&pMod[1]);
- memcpy(zCopy, zName, nName+1);
- pMod->zName = zCopy;
- pMod->pModule = pModule;
- pMod->pAux = pAux;
- pMod->xDestroy = xDestroy;
- pMod->pEpoTab = 0;
+ memcpy(zCopy, zName, nName+1);
+ pMod->zName = zCopy;
+ pMod->pModule = pModule;
+ pMod->pAux = pAux;
+ pMod->xDestroy = xDestroy;
+ pMod->pEpoTab = 0;
pMod->nRefModule = 1;
}
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
if( pDel ){
if( pDel==pMod ){
- sqlite3OomFault(db);
- sqlite3DbFree(db, pDel);
- pMod = 0;
+ sqlite3OomFault(db);
+ sqlite3DbFree(db, pDel);
+ pMod = 0;
}else{
sqlite3VtabEponymousTableClear(db, pDel);
sqlite3VtabModuleUnref(db, pDel);
- }
- }
- return pMod;
-}
-
-/*
+ }
+ }
+ return pMod;
+}
+
+/*
** The actual function that does the work of creating a new module.
** This function implements the sqlite3_create_module() and
** sqlite3_create_module_v2() interfaces.
@@ -144581,7 +144581,7 @@ static int createModule(
/*
** External API function used to create a new virtual-table module.
*/
-SQLITE_API int sqlite3_create_module(
+SQLITE_API int sqlite3_create_module(
sqlite3 *db, /* Database in which module is registered */
const char *zName, /* Name assigned to this module */
const sqlite3_module *pModule, /* The definition of the module */
@@ -144596,7 +144596,7 @@ SQLITE_API int sqlite3_create_module(
/*
** External API function used to create a new virtual-table module.
*/
-SQLITE_API int sqlite3_create_module_v2(
+SQLITE_API int sqlite3_create_module_v2(
sqlite3 *db, /* Database in which module is registered */
const char *zName, /* Name assigned to this module */
const sqlite3_module *pModule, /* The definition of the module */
@@ -144973,13 +144973,13 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
v = sqlite3GetVdbe(pParse);
sqlite3ChangeCookie(pParse, iDb);
- sqlite3VdbeAddOp0(v, OP_Expire);
+ sqlite3VdbeAddOp0(v, OP_Expire);
zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt);
sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere, 0);
sqlite3DbFree(db, zStmt);
iReg = ++pParse->nMem;
- sqlite3VdbeLoadString(v, iReg, pTab->zName);
+ sqlite3VdbeLoadString(v, iReg, pTab->zName);
sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
}else{
/* If we are rereading the sqlite_schema table create the in-memory
@@ -144991,7 +144991,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
sqlite3MarkAllShadowTablesOf(db, pTab);
pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
if( pOld ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
return;
}
@@ -145059,16 +145059,16 @@ static int vtabCallConstructor(
}
}
- zModuleName = sqlite3DbStrDup(db, pTab->zName);
+ zModuleName = sqlite3DbStrDup(db, pTab->zName);
if( !zModuleName ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
- pVTable = sqlite3MallocZero(sizeof(VTable));
+ pVTable = sqlite3MallocZero(sizeof(VTable));
if( !pVTable ){
- sqlite3OomFault(db);
+ sqlite3OomFault(db);
sqlite3DbFree(db, zModuleName);
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
pVTable->db = db;
pVTable->pMod = pMod;
@@ -145087,7 +145087,7 @@ static int vtabCallConstructor(
db->pVtabCtx = &sCtx;
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
db->pVtabCtx = sCtx.pPrior;
- if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
+ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
assert( sCtx.pTab==pTab );
if( SQLITE_OK!=rc ){
@@ -145122,16 +145122,16 @@ static int vtabCallConstructor(
pTab->u.vtab.p = pVTable;
for(iCol=0; iCol<pTab->nCol; iCol++){
- char *zType = sqlite3ColumnType(&pTab->aCol[iCol], "");
+ char *zType = sqlite3ColumnType(&pTab->aCol[iCol], "");
int nType;
int i = 0;
nType = sqlite3Strlen30(zType);
- for(i=0; i<nType; i++){
- if( 0==sqlite3StrNICmp("hidden", &zType[i], 6)
- && (i==0 || zType[i-1]==' ')
- && (zType[i+6]=='\0' || zType[i+6]==' ')
- ){
- break;
+ for(i=0; i<nType; i++){
+ if( 0==sqlite3StrNICmp("hidden", &zType[i], 6)
+ && (i==0 || zType[i-1]==' ')
+ && (zType[i+6]=='\0' || zType[i+6]==' ')
+ ){
+ break;
}
}
if( i<nType ){
@@ -145190,7 +145190,7 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr);
if( rc!=SQLITE_OK ){
sqlite3ErrorMsg(pParse, "%s", zErr);
- pParse->rc = rc;
+ pParse->rc = rc;
}
sqlite3DbFree(db, zErr);
}
@@ -145211,7 +145211,7 @@ static int growVTrans(sqlite3 *db){
((sqlite3_int64)db->nVTrans + ARRAY_INCR);
aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
if( !aVTrans ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
db->aVTrans = aVTrans;
@@ -145234,7 +145234,7 @@ static void addToVTrans(sqlite3 *db, VTable *pVTab){
** This function is invoked by the vdbe to call the xCreate method
** of the virtual table named zTab in database iDb.
**
-** If an error occurs, *pzErr is set to point to an English language
+** If an error occurs, *pzErr is set to point to an English language
** description of the error and an SQLITE_XXX error code is returned.
** In this case the caller must call sqlite3DbFree(db, ) on *pzErr.
*/
@@ -145244,7 +145244,7 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
Module *pMod;
const char *zMod;
- pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
+ pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
assert( pTab && IsVirtual(pTab) && !pTab->u.vtab.p );
/* Locate the required virtual table module */
@@ -145255,7 +145255,7 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
** invoke it now. If the module has not been registered, return an
** error. Otherwise, do nothing.
*/
- if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){
+ if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){
*pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
rc = SQLITE_ERROR;
}else{
@@ -145279,12 +145279,12 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
** valid to call this function from within the xCreate() or xConnect() of a
** virtual table module.
*/
-SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
+SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
VtabCtx *pCtx;
int rc = SQLITE_OK;
Table *pTab;
char *zErr = 0;
- Parse sParse;
+ Parse sParse;
int initBusy;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -145300,65 +145300,65 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
return SQLITE_MISUSE_BKPT;
}
pTab = pCtx->pTab;
- assert( IsVirtual(pTab) );
+ assert( IsVirtual(pTab) );
- memset(&sParse, 0, sizeof(sParse));
+ memset(&sParse, 0, sizeof(sParse));
sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
- sParse.db = db;
+ sParse.db = db;
/* We should never be able to reach this point while loading the
** schema. Nevertheless, defend against that (turn off db->init.busy)
** in case a bug arises. */
assert( db->init.busy==0 );
initBusy = db->init.busy;
db->init.busy = 0;
- sParse.nQueryLoop = 1;
+ sParse.nQueryLoop = 1;
if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr)
- && sParse.pNewTable
- && !db->mallocFailed
+ && sParse.pNewTable
+ && !db->mallocFailed
&& IsOrdinaryTable(sParse.pNewTable)
- ){
- if( !pTab->aCol ){
- Table *pNew = sParse.pNewTable;
- Index *pIdx;
- pTab->aCol = pNew->aCol;
+ ){
+ if( !pTab->aCol ){
+ Table *pNew = sParse.pNewTable;
+ Index *pIdx;
+ pTab->aCol = pNew->aCol;
sqlite3ExprListDelete(db, pNew->u.tab.pDfltList);
pTab->nNVCol = pTab->nCol = pNew->nCol;
- pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
- pNew->nCol = 0;
- pNew->aCol = 0;
- assert( pTab->pIndex==0 );
- assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 );
- if( !HasRowid(pNew)
- && pCtx->pVTable->pMod->pModule->xUpdate!=0
- && sqlite3PrimaryKeyIndex(pNew)->nKeyCol!=1
- ){
- /* WITHOUT ROWID virtual tables must either be read-only (xUpdate==0)
- ** or else must have a single-column PRIMARY KEY */
- rc = SQLITE_ERROR;
- }
- pIdx = pNew->pIndex;
- if( pIdx ){
- assert( pIdx->pNext==0 );
- pTab->pIndex = pIdx;
- pNew->pIndex = 0;
- pIdx->pTable = pTab;
- }
- }
- pCtx->bDeclared = 1;
- }else{
- sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
- sqlite3DbFree(db, zErr);
- rc = SQLITE_ERROR;
+ pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
+ pNew->nCol = 0;
+ pNew->aCol = 0;
+ assert( pTab->pIndex==0 );
+ assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 );
+ if( !HasRowid(pNew)
+ && pCtx->pVTable->pMod->pModule->xUpdate!=0
+ && sqlite3PrimaryKeyIndex(pNew)->nKeyCol!=1
+ ){
+ /* WITHOUT ROWID virtual tables must either be read-only (xUpdate==0)
+ ** or else must have a single-column PRIMARY KEY */
+ rc = SQLITE_ERROR;
+ }
+ pIdx = pNew->pIndex;
+ if( pIdx ){
+ assert( pIdx->pNext==0 );
+ pTab->pIndex = pIdx;
+ pNew->pIndex = 0;
+ pIdx->pTable = pTab;
+ }
+ }
+ pCtx->bDeclared = 1;
+ }else{
+ sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
+ sqlite3DbFree(db, zErr);
+ rc = SQLITE_ERROR;
}
sParse.eParseMode = PARSE_MODE_NORMAL;
- if( sParse.pVdbe ){
- sqlite3VdbeFinalize(sParse.pVdbe);
- }
- sqlite3DeleteTable(db, sParse.pNewTable);
- sqlite3ParserReset(&sParse);
+ if( sParse.pVdbe ){
+ sqlite3VdbeFinalize(sParse.pVdbe);
+ }
+ sqlite3DeleteTable(db, sParse.pNewTable);
+ sqlite3ParserReset(&sParse);
db->init.busy = initBusy;
-
+
assert( (rc&0xff)==rc );
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
@@ -145376,13 +145376,13 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
int rc = SQLITE_OK;
Table *pTab;
- pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
+ pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
if( ALWAYS(pTab!=0)
&& ALWAYS(IsVirtual(pTab))
&& ALWAYS(pTab->u.vtab.p!=0)
){
VTable *p;
- int (*xDestroy)(sqlite3_vtab *);
+ int (*xDestroy)(sqlite3_vtab *);
for(p=pTab->u.vtab.p; p; p=p->pNext){
assert( p->pVtab );
if( p->pVtab->nRef>0 ){
@@ -145390,11 +145390,11 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
}
}
p = vtabDisconnectAll(db, pTab);
- xDestroy = p->pMod->pModule->xDestroy;
+ xDestroy = p->pMod->pModule->xDestroy;
if( xDestroy==0 ) xDestroy = p->pMod->pModule->xDisconnect;
assert( xDestroy!=0 );
pTab->nTabRef++;
- rc = xDestroy(p->pVtab);
+ rc = xDestroy(p->pVtab);
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
if( rc==SQLITE_OK ){
assert( pTab->u.vtab.p==p && p->pNext==0 );
@@ -145521,12 +145521,12 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){
if( rc==SQLITE_OK ){
rc = pModule->xBegin(pVTab->pVtab);
if( rc==SQLITE_OK ){
- int iSvpt = db->nStatement + db->nSavepoint;
+ int iSvpt = db->nStatement + db->nSavepoint;
addToVTrans(db, pVTab);
- if( iSvpt && pModule->xSavepoint ){
- pVTab->iSavepoint = iSvpt;
- rc = pModule->xSavepoint(pVTab->pVtab, iSvpt-1);
- }
+ if( iSvpt && pModule->xSavepoint ){
+ pVTab->iSavepoint = iSvpt;
+ rc = pModule->xSavepoint(pVTab->pVtab, iSvpt-1);
+ }
}
}
}
@@ -145605,7 +145605,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
Table *pTab;
sqlite3_vtab *pVtab;
sqlite3_module *pMod;
- void (*xSFunc)(sqlite3_context*,int,sqlite3_value**) = 0;
+ void (*xSFunc)(sqlite3_context*,int,sqlite3_value**) = 0;
void *pArg = 0;
FuncDef *pNew;
int rc = 0;
@@ -145615,8 +145615,8 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
if( pExpr->op!=TK_COLUMN ) return pDef;
assert( ExprUseYTab(pExpr) );
pTab = pExpr->y.pTab;
- if( pTab==0 ) return pDef;
- if( !IsVirtual(pTab) ) return pDef;
+ if( pTab==0 ) return pDef;
+ if( !IsVirtual(pTab) ) return pDef;
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
assert( pVtab!=0 );
assert( pVtab->pModule!=0 );
@@ -145652,9 +145652,9 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
return pDef;
}
*pNew = *pDef;
- pNew->zName = (const char*)&pNew[1];
- memcpy((char*)&pNew[1], pDef->zName, sqlite3Strlen30(pDef->zName)+1);
- pNew->xSFunc = xSFunc;
+ pNew->zName = (const char*)&pNew[1];
+ memcpy((char*)&pNew[1], pDef->zName, sqlite3Strlen30(pDef->zName)+1);
+ pNew->xSFunc = xSFunc;
pNew->pUserData = pArg;
pNew->funcFlags |= SQLITE_FUNC_EPHEM;
return pNew;
@@ -145681,83 +145681,83 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
pToplevel->apVtabLock = apVtabLock;
pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
}else{
- sqlite3OomFault(pToplevel->db);
+ sqlite3OomFault(pToplevel->db);
}
}
/*
-** Check to see if virtual table module pMod can be have an eponymous
-** virtual table instance. If it can, create one if one does not already
+** Check to see if virtual table module pMod can be have an eponymous
+** virtual table instance. If it can, create one if one does not already
** exist. Return non-zero if either the eponymous virtual table instance
** exists when this routine returns or if an attempt to create it failed
** and an error message was left in pParse.
-**
-** An eponymous virtual table instance is one that is named after its
-** module, and more importantly, does not require a CREATE VIRTUAL TABLE
-** statement in order to come into existance. Eponymous virtual table
-** instances always exist. They cannot be DROP-ed.
-**
-** Any virtual table module for which xConnect and xCreate are the same
-** method can have an eponymous virtual table instance.
-*/
-SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
- const sqlite3_module *pModule = pMod->pModule;
- Table *pTab;
- char *zErr = 0;
- int rc;
- sqlite3 *db = pParse->db;
- if( pMod->pEpoTab ) return 1;
- if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0;
- pTab = sqlite3DbMallocZero(db, sizeof(Table));
- if( pTab==0 ) return 0;
- pTab->zName = sqlite3DbStrDup(db, pMod->zName);
- if( pTab->zName==0 ){
- sqlite3DbFree(db, pTab);
- return 0;
- }
- pMod->pEpoTab = pTab;
- pTab->nTabRef = 1;
+**
+** An eponymous virtual table instance is one that is named after its
+** module, and more importantly, does not require a CREATE VIRTUAL TABLE
+** statement in order to come into existance. Eponymous virtual table
+** instances always exist. They cannot be DROP-ed.
+**
+** Any virtual table module for which xConnect and xCreate are the same
+** method can have an eponymous virtual table instance.
+*/
+SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
+ const sqlite3_module *pModule = pMod->pModule;
+ Table *pTab;
+ char *zErr = 0;
+ int rc;
+ sqlite3 *db = pParse->db;
+ if( pMod->pEpoTab ) return 1;
+ if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0;
+ pTab = sqlite3DbMallocZero(db, sizeof(Table));
+ if( pTab==0 ) return 0;
+ pTab->zName = sqlite3DbStrDup(db, pMod->zName);
+ if( pTab->zName==0 ){
+ sqlite3DbFree(db, pTab);
+ return 0;
+ }
+ pMod->pEpoTab = pTab;
+ pTab->nTabRef = 1;
pTab->eTabType = TABTYP_VTAB;
- pTab->pSchema = db->aDb[0].pSchema;
+ pTab->pSchema = db->aDb[0].pSchema;
assert( pTab->u.vtab.nArg==0 );
- pTab->iPKey = -1;
+ pTab->iPKey = -1;
pTab->tabFlags |= TF_Eponymous;
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
addModuleArgument(pParse, pTab, 0);
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
- rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
- if( rc ){
- sqlite3ErrorMsg(pParse, "%s", zErr);
- sqlite3DbFree(db, zErr);
- sqlite3VtabEponymousTableClear(db, pMod);
- }
- return 1;
-}
-
-/*
-** Erase the eponymous virtual table instance associated with
-** virtual table module pMod, if it exists.
-*/
-SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){
- Table *pTab = pMod->pEpoTab;
- if( pTab!=0 ){
- /* Mark the table as Ephemeral prior to deleting it, so that the
+ rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
+ if( rc ){
+ sqlite3ErrorMsg(pParse, "%s", zErr);
+ sqlite3DbFree(db, zErr);
+ sqlite3VtabEponymousTableClear(db, pMod);
+ }
+ return 1;
+}
+
+/*
+** Erase the eponymous virtual table instance associated with
+** virtual table module pMod, if it exists.
+*/
+SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){
+ Table *pTab = pMod->pEpoTab;
+ if( pTab!=0 ){
+ /* Mark the table as Ephemeral prior to deleting it, so that the
** sqlite3DeleteTable() routine will know that it is not stored in
- ** the schema. */
- pTab->tabFlags |= TF_Ephemeral;
- sqlite3DeleteTable(db, pTab);
- pMod->pEpoTab = 0;
- }
-}
-
-/*
+ ** the schema. */
+ pTab->tabFlags |= TF_Ephemeral;
+ sqlite3DeleteTable(db, pTab);
+ pMod->pEpoTab = 0;
+ }
+}
+
+/*
** Return the ON CONFLICT resolution mode in effect for the virtual
** table update operation currently in progress.
**
** The results of this routine are undefined unless it is called from
** within an xUpdate method.
*/
-SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
+SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
static const unsigned char aMap[] = {
SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE
};
@@ -145775,7 +145775,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
** the SQLite core with additional information about the behavior
** of the virtual table being implemented.
*/
-SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
+SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
va_list ap;
int rc = SQLITE_OK;
VtabCtx *p;
@@ -145904,10 +145904,10 @@ struct WhereLevel {
int addrBody; /* Beginning of the body of this loop */
int regBignull; /* big-null flag reg. True if a NULL-scan is needed */
int addrBignull; /* Jump here for next part of big-null scan */
-#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
- u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */
+#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */
int addrLikeRep; /* LIKE range processing address */
-#endif
+#endif
u8 iFrom; /* Which entry in the FROM clause */
u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
int p1, p2; /* Operands of the opcode used to end the loop */
@@ -145959,8 +145959,8 @@ struct WhereLoop {
union {
struct { /* Information for internal btree tables */
u16 nEq; /* Number of equality constraints */
- u16 nBtm; /* Size of BTM vector */
- u16 nTop; /* Size of TOP vector */
+ u16 nBtm; /* Size of BTM vector */
+ u16 nTop; /* Size of TOP vector */
u16 nDistinctCol; /* Index columns used to sort for DISTINCT */
Index *pIndex; /* Index used, or NULL */
} btree;
@@ -146084,12 +146084,12 @@ struct WherePath {
*/
struct WhereTerm {
Expr *pExpr; /* Pointer to the subexpression that is this term */
- WhereClause *pWC; /* The clause this term is part of */
- LogEst truthProb; /* Probability of truth for this expression */
- u16 wtFlags; /* TERM_xxx bit flags. See below */
- u16 eOperator; /* A WO_xx value describing <op> */
- u8 nChild; /* Number of children that must disable us */
- u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
+ WhereClause *pWC; /* The clause this term is part of */
+ LogEst truthProb; /* Probability of truth for this expression */
+ u16 wtFlags; /* TERM_xxx bit flags. See below */
+ u16 eOperator; /* A WO_xx value describing <op> */
+ u8 nChild; /* Number of children that must disable us */
+ u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
int iParent; /* Disable pWC->a[iParent] when this term disabled */
int leftCursor; /* Cursor number of X in "X <op> <expr>" */
union {
@@ -146119,7 +146119,7 @@ struct WhereTerm {
#define TERM_LIKECOND 0x0200 /* Conditionally this LIKE operator term */
#define TERM_LIKE 0x0400 /* The original LIKE operator */
#define TERM_IS 0x0800 /* Term.pExpr is an IS operator */
-#define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */
+#define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */
#define TERM_HEURTRUTH 0x2000 /* Heuristic truthProb used */
#ifdef SQLITE_ENABLE_STAT4
# define TERM_HIGHTRUTH 0x4000 /* Term excludes few rows */
@@ -146134,15 +146134,15 @@ struct WhereTerm {
struct WhereScan {
WhereClause *pOrigWC; /* Original, innermost WhereClause */
WhereClause *pWC; /* WhereClause currently being scanned */
- const char *zCollName; /* Required collating sequence, if not NULL */
- Expr *pIdxExpr; /* Search for this index expression */
+ const char *zCollName; /* Required collating sequence, if not NULL */
+ Expr *pIdxExpr; /* Search for this index expression */
char idxaff; /* Must match this affinity, if zCollName!=NULL */
unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */
unsigned char iEquiv; /* Next unused slot in aiCur[] and aiColumn[] */
u32 opMask; /* Acceptable operators */
int k; /* Resume scanning at this->pWC->a[this->k] */
- int aiCur[11]; /* Cursors in the equivalence class */
- i16 aiColumn[11]; /* Corresponding column number in the eq-class */
+ int aiCur[11]; /* Cursors in the equivalence class */
+ i16 aiColumn[11]; /* Corresponding column number in the eq-class */
};
/*
@@ -146216,7 +146216,7 @@ struct WhereAndInfo {
** no gaps.
*/
struct WhereMaskSet {
- int bVarSelect; /* Used by sqlite3WhereExprUsage() */
+ int bVarSelect; /* Used by sqlite3WhereExprUsage() */
int n; /* Number of assigned cursor values */
int ix[BMS]; /* Cursor assigned to each bit */
};
@@ -146245,10 +146245,10 @@ struct WhereLoopBuilder {
unsigned int iPlanLimit; /* Search limiter */
};
-/* Allowed values for WhereLoopBuider.bldFlags */
+/* Allowed values for WhereLoopBuider.bldFlags */
#define SQLITE_BLDF1_INDEXED 0x0001 /* An index is used */
#define SQLITE_BLDF1_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
-
+
#define SQLITE_BLDF2_2NDPASS 0x0004 /* Second builder pass needed */
/* The WhereLoopBuilder.iPlanLimit is used to limit the number of
@@ -146299,18 +146299,18 @@ struct WhereInfo {
Parse *pParse; /* Parsing and code generating context */
SrcList *pTabList; /* List of tables in the join */
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
- ExprList *pResultSet; /* Result set of the query */
- Expr *pWhere; /* The complete WHERE clause */
- int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
- int iContinue; /* Jump here to continue with next record */
- int iBreak; /* Jump here to break out of the loop */
- int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
+ ExprList *pResultSet; /* Result set of the query */
+ Expr *pWhere; /* The complete WHERE clause */
+ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
+ int iContinue; /* Jump here to continue with next record */
+ int iBreak; /* Jump here to break out of the loop */
+ int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
- u8 nLevel; /* Number of nested loop */
+ u8 nLevel; /* Number of nested loop */
i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */
- u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */
- u8 eDistinct; /* One of the WHERE_DISTINCT_* values */
+ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */
+ u8 eDistinct; /* One of the WHERE_DISTINCT_* values */
unsigned bDeferredSeek :1; /* Uses OP_DeferredSeek */
unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */
unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */
@@ -146318,10 +146318,10 @@ struct WhereInfo {
LogEst nRowOut; /* Estimated number of output rows */
int iTop; /* The very beginning of the WHERE loop */
int iEndWhere; /* End of the WHERE clause itself */
- WhereLoop *pLoops; /* List of all WhereLoop objects */
+ WhereLoop *pLoops; /* List of all WhereLoop objects */
WhereExprMod *pExprMods; /* Expression modifications */
- Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
- WhereClause sWC; /* Decomposition of the WHERE clause */
+ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
+ WhereClause sWC; /* Decomposition of the WHERE clause */
WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
WhereLevel a[1]; /* Information about each nest loop in WHERE */
};
@@ -146332,11 +146332,11 @@ struct WhereInfo {
** where.c:
*/
SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int);
-#ifdef WHERETRACE_ENABLED
-SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC);
+#ifdef WHERETRACE_ENABLED
+SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC);
SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm);
SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC);
-#endif
+#endif
SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm(
WhereClause *pWC, /* The WHERE clause to be searched */
int iCur, /* Cursor number of LHS */
@@ -146395,13 +146395,13 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
** operators that are of interest to the query planner. An
** OR-ed combination of these values can be used when searching for
** particular WhereTerms within a WhereClause.
-**
-** Value constraints:
-** WO_EQ == SQLITE_INDEX_CONSTRAINT_EQ
-** WO_LT == SQLITE_INDEX_CONSTRAINT_LT
-** WO_LE == SQLITE_INDEX_CONSTRAINT_LE
-** WO_GT == SQLITE_INDEX_CONSTRAINT_GT
-** WO_GE == SQLITE_INDEX_CONSTRAINT_GE
+**
+** Value constraints:
+** WO_EQ == SQLITE_INDEX_CONSTRAINT_EQ
+** WO_LT == SQLITE_INDEX_CONSTRAINT_LT
+** WO_LE == SQLITE_INDEX_CONSTRAINT_LE
+** WO_GT == SQLITE_INDEX_CONSTRAINT_GT
+** WO_GE == SQLITE_INDEX_CONSTRAINT_GE
*/
#define WO_IN 0x0001
#define WO_EQ 0x0002
@@ -146409,7 +146409,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
#define WO_LE (WO_EQ<<(TK_LE-TK_EQ))
#define WO_GT (WO_EQ<<(TK_GT-TK_EQ))
#define WO_GE (WO_EQ<<(TK_GE-TK_EQ))
-#define WO_AUX 0x0040 /* Op useful to virtual tables only */
+#define WO_AUX 0x0040 /* Op useful to virtual tables only */
#define WO_IS 0x0080
#define WO_ISNULL 0x0100
#define WO_OR 0x0200 /* Two or more OR-connected terms */
@@ -146455,18 +146455,18 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
/************** Continuing where we left off in wherecode.c ******************/
#ifndef SQLITE_OMIT_EXPLAIN
-
-/*
-** Return the name of the i-th column of the pIdx index.
-*/
-static const char *explainIndexColumnName(Index *pIdx, int i){
- i = pIdx->aiColumn[i];
- if( i==XN_EXPR ) return "<expr>";
- if( i==XN_ROWID ) return "rowid";
+
+/*
+** Return the name of the i-th column of the pIdx index.
+*/
+static const char *explainIndexColumnName(Index *pIdx, int i){
+ i = pIdx->aiColumn[i];
+ if( i==XN_EXPR ) return "<expr>";
+ if( i==XN_ROWID ) return "rowid";
return pIdx->pTable->aCol[i].zCnName;
-}
-
-/*
+}
+
+/*
** This routine is a helper for explainIndexRange() below
**
** pStr holds the text of an expression that we are building up one term
@@ -146476,31 +146476,31 @@ static const char *explainIndexColumnName(Index *pIdx, int i){
*/
static void explainAppendTerm(
StrAccum *pStr, /* The text expression being built */
- Index *pIdx, /* Index to read column names from */
- int nTerm, /* Number of terms */
- int iTerm, /* Zero-based index of first term. */
- int bAnd, /* Non-zero to append " AND " */
+ Index *pIdx, /* Index to read column names from */
+ int nTerm, /* Number of terms */
+ int iTerm, /* Zero-based index of first term. */
+ int bAnd, /* Non-zero to append " AND " */
const char *zOp /* Name of the operator */
){
- int i;
-
- assert( nTerm>=1 );
+ int i;
+
+ assert( nTerm>=1 );
if( bAnd ) sqlite3_str_append(pStr, " AND ", 5);
-
+
if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
- for(i=0; i<nTerm; i++){
+ for(i=0; i<nTerm; i++){
if( i ) sqlite3_str_append(pStr, ",", 1);
sqlite3_str_appendall(pStr, explainIndexColumnName(pIdx, iTerm+i));
- }
+ }
if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
-
+
sqlite3_str_append(pStr, zOp, 1);
-
+
if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
- for(i=0; i<nTerm; i++){
+ for(i=0; i<nTerm; i++){
if( i ) sqlite3_str_append(pStr, ",", 1);
sqlite3_str_append(pStr, "?", 1);
- }
+ }
if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
}
@@ -146518,7 +146518,7 @@ static void explainAppendTerm(
**
** "a=? AND b>?"
*/
-static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
+static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
Index *pIndex = pLoop->u.btree.pIndex;
u16 nEq = pLoop->u.btree.nEq;
u16 nSkip = pLoop->nSkip;
@@ -146527,18 +146527,18 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
sqlite3_str_append(pStr, " (", 2);
for(i=0; i<nEq; i++){
- const char *z = explainIndexColumnName(pIndex, i);
+ const char *z = explainIndexColumnName(pIndex, i);
if( i ) sqlite3_str_append(pStr, " AND ", 5);
sqlite3_str_appendf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
}
j = i;
if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
- explainAppendTerm(pStr, pIndex, pLoop->u.btree.nBtm, j, i, ">");
- i = 1;
+ explainAppendTerm(pStr, pIndex, pLoop->u.btree.nBtm, j, i, ">");
+ i = 1;
}
if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
- explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<");
+ explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<");
}
sqlite3_str_append(pStr, ")", 1);
}
@@ -146560,7 +146560,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
){
int ret = 0;
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
- if( sqlite3ParseToplevel(pParse)->explain==2 )
+ if( sqlite3ParseToplevel(pParse)->explain==2 )
#endif
{
SrcItem *pItem = &pTabList->a[pLevel->iFrom];
@@ -146575,7 +146575,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
pLoop = pLevel->pWLoop;
flags = pLoop->wsFlags;
- if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0;
+ if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0;
isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
@@ -146607,19 +146607,19 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
if( zFmt ){
sqlite3_str_append(&str, " USING ", 7);
sqlite3_str_appendf(&str, zFmt, pIdx->zName);
- explainIndexRange(&str, pLoop);
+ explainIndexRange(&str, pLoop);
}
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
- const char *zRangeOp;
+ const char *zRangeOp;
if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
- zRangeOp = "=";
+ zRangeOp = "=";
}else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
- zRangeOp = ">? AND rowid<";
+ zRangeOp = ">? AND rowid<";
}else if( flags&WHERE_BTM_LIMIT ){
- zRangeOp = ">";
+ zRangeOp = ">";
}else{
assert( flags&WHERE_TOP_LIMIT);
- zRangeOp = "<";
+ zRangeOp = "<";
}
sqlite3_str_appendf(&str,
" USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
@@ -146721,8 +146721,8 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
*/
static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
int nLoop = 0;
- assert( pTerm!=0 );
- while( (pTerm->wtFlags & TERM_CODED)==0
+ assert( pTerm!=0 );
+ while( (pTerm->wtFlags & TERM_CODED)==0
&& (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
&& (pLevel->notReady & pTerm->prereqAll)==0
){
@@ -146739,7 +146739,7 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
#endif
if( pTerm->iParent<0 ) break;
pTerm = &pTerm->pWC->a[pTerm->iParent];
- assert( pTerm!=0 );
+ assert( pTerm!=0 );
pTerm->nChild--;
if( pTerm->nChild!=0 ) break;
nLoop++;
@@ -146780,153 +146780,153 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
/* Code the OP_Affinity opcode if there is anything left to do. */
if( n>0 ){
- sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n);
+ sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n);
}
}
-/*
+/*
** Expression pRight, which is the RHS of a comparison operation, is
-** either a vector of n elements or, if n==1, a scalar expression.
-** Before the comparison operation, affinity zAff is to be applied
-** to the pRight values. This function modifies characters within the
-** affinity string to SQLITE_AFF_BLOB if either:
-**
-** * the comparison will be performed with no affinity, or
-** * the affinity change in zAff is guaranteed not to change the value.
-*/
-static void updateRangeAffinityStr(
- Expr *pRight, /* RHS of comparison */
- int n, /* Number of vector elements in comparison */
- char *zAff /* Affinity string to modify */
-){
- int i;
- for(i=0; i<n; i++){
- Expr *p = sqlite3VectorFieldSubexpr(pRight, i);
- if( sqlite3CompareAffinity(p, zAff[i])==SQLITE_AFF_BLOB
- || sqlite3ExprNeedsNoAffinityChange(p, zAff[i])
- ){
- zAff[i] = SQLITE_AFF_BLOB;
- }
- }
-}
-
-
-/*
-** pX is an expression of the form: (vector) IN (SELECT ...)
-** In other words, it is a vector IN operator with a SELECT clause on the
-** LHS. But not all terms in the vector are indexable and the terms might
-** not be in the correct order for indexing.
-**
-** This routine makes a copy of the input pX expression and then adjusts
-** the vector on the LHS with corresponding changes to the SELECT so that
-** the vector contains only index terms and those terms are in the correct
-** order. The modified IN expression is returned. The caller is responsible
-** for deleting the returned expression.
-**
-** Example:
-**
-** CREATE TABLE t1(a,b,c,d,e,f);
-** CREATE INDEX t1x1 ON t1(e,c);
-** SELECT * FROM t1 WHERE (a,b,c,d,e) IN (SELECT v,w,x,y,z FROM t2)
-** \_______________________________________/
-** The pX expression
-**
-** Since only columns e and c can be used with the index, in that order,
-** the modified IN expression that is returned will be:
-**
-** (e,c) IN (SELECT z,x FROM t2)
-**
-** The reduced pX is different from the original (obviously) and thus is
-** only used for indexing, to improve performance. The original unaltered
-** IN expression must also be run on each output row for correctness.
-*/
-static Expr *removeUnindexableInClauseTerms(
- Parse *pParse, /* The parsing context */
- int iEq, /* Look at loop terms starting here */
- WhereLoop *pLoop, /* The current loop */
- Expr *pX /* The IN expression to be reduced */
-){
- sqlite3 *db = pParse->db;
+** either a vector of n elements or, if n==1, a scalar expression.
+** Before the comparison operation, affinity zAff is to be applied
+** to the pRight values. This function modifies characters within the
+** affinity string to SQLITE_AFF_BLOB if either:
+**
+** * the comparison will be performed with no affinity, or
+** * the affinity change in zAff is guaranteed not to change the value.
+*/
+static void updateRangeAffinityStr(
+ Expr *pRight, /* RHS of comparison */
+ int n, /* Number of vector elements in comparison */
+ char *zAff /* Affinity string to modify */
+){
+ int i;
+ for(i=0; i<n; i++){
+ Expr *p = sqlite3VectorFieldSubexpr(pRight, i);
+ if( sqlite3CompareAffinity(p, zAff[i])==SQLITE_AFF_BLOB
+ || sqlite3ExprNeedsNoAffinityChange(p, zAff[i])
+ ){
+ zAff[i] = SQLITE_AFF_BLOB;
+ }
+ }
+}
+
+
+/*
+** pX is an expression of the form: (vector) IN (SELECT ...)
+** In other words, it is a vector IN operator with a SELECT clause on the
+** LHS. But not all terms in the vector are indexable and the terms might
+** not be in the correct order for indexing.
+**
+** This routine makes a copy of the input pX expression and then adjusts
+** the vector on the LHS with corresponding changes to the SELECT so that
+** the vector contains only index terms and those terms are in the correct
+** order. The modified IN expression is returned. The caller is responsible
+** for deleting the returned expression.
+**
+** Example:
+**
+** CREATE TABLE t1(a,b,c,d,e,f);
+** CREATE INDEX t1x1 ON t1(e,c);
+** SELECT * FROM t1 WHERE (a,b,c,d,e) IN (SELECT v,w,x,y,z FROM t2)
+** \_______________________________________/
+** The pX expression
+**
+** Since only columns e and c can be used with the index, in that order,
+** the modified IN expression that is returned will be:
+**
+** (e,c) IN (SELECT z,x FROM t2)
+**
+** The reduced pX is different from the original (obviously) and thus is
+** only used for indexing, to improve performance. The original unaltered
+** IN expression must also be run on each output row for correctness.
+*/
+static Expr *removeUnindexableInClauseTerms(
+ Parse *pParse, /* The parsing context */
+ int iEq, /* Look at loop terms starting here */
+ WhereLoop *pLoop, /* The current loop */
+ Expr *pX /* The IN expression to be reduced */
+){
+ sqlite3 *db = pParse->db;
Expr *pNew;
pNew = sqlite3ExprDup(db, pX, 0);
- if( db->mallocFailed==0 ){
+ if( db->mallocFailed==0 ){
ExprList *pOrigRhs; /* Original unmodified RHS */
ExprList *pOrigLhs; /* Original unmodified LHS */
- ExprList *pRhs = 0; /* New RHS after modifications */
- ExprList *pLhs = 0; /* New LHS after mods */
- int i; /* Loop counter */
- Select *pSelect; /* Pointer to the SELECT on the RHS */
-
+ ExprList *pRhs = 0; /* New RHS after modifications */
+ ExprList *pLhs = 0; /* New LHS after mods */
+ int i; /* Loop counter */
+ Select *pSelect; /* Pointer to the SELECT on the RHS */
+
assert( ExprUseXSelect(pNew) );
pOrigRhs = pNew->x.pSelect->pEList;
assert( pNew->pLeft!=0 );
assert( ExprUseXList(pNew->pLeft) );
pOrigLhs = pNew->pLeft->x.pList;
- for(i=iEq; i<pLoop->nLTerm; i++){
- if( pLoop->aLTerm[i]->pExpr==pX ){
+ for(i=iEq; i<pLoop->nLTerm; i++){
+ if( pLoop->aLTerm[i]->pExpr==pX ){
int iField;
assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 );
iField = pLoop->aLTerm[i]->u.x.iField - 1;
if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
- pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
- pOrigRhs->a[iField].pExpr = 0;
- assert( pOrigLhs->a[iField].pExpr!=0 );
- pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
- pOrigLhs->a[iField].pExpr = 0;
- }
- }
- sqlite3ExprListDelete(db, pOrigRhs);
- sqlite3ExprListDelete(db, pOrigLhs);
- pNew->pLeft->x.pList = pLhs;
- pNew->x.pSelect->pEList = pRhs;
- if( pLhs && pLhs->nExpr==1 ){
- /* Take care here not to generate a TK_VECTOR containing only a
- ** single value. Since the parser never creates such a vector, some
- ** of the subroutines do not handle this case. */
- Expr *p = pLhs->a[0].pExpr;
- pLhs->a[0].pExpr = 0;
- sqlite3ExprDelete(db, pNew->pLeft);
- pNew->pLeft = p;
- }
- pSelect = pNew->x.pSelect;
- if( pSelect->pOrderBy ){
+ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
+ pOrigRhs->a[iField].pExpr = 0;
+ assert( pOrigLhs->a[iField].pExpr!=0 );
+ pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
+ pOrigLhs->a[iField].pExpr = 0;
+ }
+ }
+ sqlite3ExprListDelete(db, pOrigRhs);
+ sqlite3ExprListDelete(db, pOrigLhs);
+ pNew->pLeft->x.pList = pLhs;
+ pNew->x.pSelect->pEList = pRhs;
+ if( pLhs && pLhs->nExpr==1 ){
+ /* Take care here not to generate a TK_VECTOR containing only a
+ ** single value. Since the parser never creates such a vector, some
+ ** of the subroutines do not handle this case. */
+ Expr *p = pLhs->a[0].pExpr;
+ pLhs->a[0].pExpr = 0;
+ sqlite3ExprDelete(db, pNew->pLeft);
+ pNew->pLeft = p;
+ }
+ pSelect = pNew->x.pSelect;
+ if( pSelect->pOrderBy ){
/* If the SELECT statement has an ORDER BY clause, zero the
** iOrderByCol variables. These are set to non-zero when an
** ORDER BY term exactly matches one of the terms of the
- ** result-set. Since the result-set of the SELECT statement may
+ ** result-set. Since the result-set of the SELECT statement may
** have been modified or reordered, these variables are no longer
** set correctly. Since setting them is just an optimization,
- ** it's easiest just to zero them here. */
- ExprList *pOrderBy = pSelect->pOrderBy;
- for(i=0; i<pOrderBy->nExpr; i++){
- pOrderBy->a[i].u.x.iOrderByCol = 0;
- }
- }
-
-#if 0
- printf("For indexing, change the IN expr:\n");
- sqlite3TreeViewExpr(0, pX, 0);
- printf("Into:\n");
- sqlite3TreeViewExpr(0, pNew, 0);
-#endif
- }
- return pNew;
-}
-
-
-/*
+ ** it's easiest just to zero them here. */
+ ExprList *pOrderBy = pSelect->pOrderBy;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ pOrderBy->a[i].u.x.iOrderByCol = 0;
+ }
+ }
+
+#if 0
+ printf("For indexing, change the IN expr:\n");
+ sqlite3TreeViewExpr(0, pX, 0);
+ printf("Into:\n");
+ sqlite3TreeViewExpr(0, pNew, 0);
+#endif
+ }
+ return pNew;
+}
+
+
+/*
** Generate code for a single equality term of the WHERE clause. An equality
** term can be either X=expr or X IN (...). pTerm is the term to be
** coded.
**
-** The current value for the constraint is left in a register, the index
-** of which is returned. An attempt is made store the result in iTarget but
-** this is only guaranteed for TK_ISNULL and TK_IN constraints. If the
-** constraint is a TK_EQ or TK_IS, then the current value might be left in
-** some other register and it is the caller's responsibility to compensate.
+** The current value for the constraint is left in a register, the index
+** of which is returned. An attempt is made store the result in iTarget but
+** this is only guaranteed for TK_ISNULL and TK_IN constraints. If the
+** constraint is a TK_EQ or TK_IS, then the current value might be left in
+** some other register and it is the caller's responsibility to compensate.
**
-** For a constraint of the form X=expr, the expression is evaluated in
-** straight-line code. For constraints of the form X IN (...)
+** For a constraint of the form X=expr, the expression is evaluated in
+** straight-line code. For constraints of the form X IN (...)
** this routine sets up a loop that will iterate over all values of X.
*/
static int codeEqualityTerm(
@@ -146941,7 +146941,7 @@ static int codeEqualityTerm(
Vdbe *v = pParse->pVdbe;
int iReg; /* Register holding results */
- assert( pLevel->pWLoop->aLTerm[iEq]==pTerm );
+ assert( pLevel->pWLoop->aLTerm[iEq]==pTerm );
assert( iTarget>0 );
if( pX->op==TK_EQ || pX->op==TK_IS ){
iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
@@ -146950,13 +146950,13 @@ static int codeEqualityTerm(
sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
#ifndef SQLITE_OMIT_SUBQUERY
}else{
- int eType = IN_INDEX_NOOP;
+ int eType = IN_INDEX_NOOP;
int iTab;
struct InLoop *pIn;
WhereLoop *pLoop = pLevel->pWLoop;
- int i;
- int nEq = 0;
- int *aiMap = 0;
+ int i;
+ int nEq = 0;
+ int *aiMap = 0;
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
&& pLoop->u.btree.pIndex!=0
@@ -146968,34 +146968,34 @@ static int codeEqualityTerm(
}
assert( pX->op==TK_IN );
iReg = iTarget;
-
- for(i=0; i<iEq; i++){
- if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){
- disableTerm(pLevel, pTerm);
- return iTarget;
- }
- }
- for(i=iEq;i<pLoop->nLTerm; i++){
- assert( pLoop->aLTerm[i]!=0 );
- if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
- }
-
+
+ for(i=0; i<iEq; i++){
+ if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){
+ disableTerm(pLevel, pTerm);
+ return iTarget;
+ }
+ }
+ for(i=iEq;i<pLoop->nLTerm; i++){
+ assert( pLoop->aLTerm[i]!=0 );
+ if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
+ }
+
iTab = 0;
if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){
eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
- }else{
- sqlite3 *db = pParse->db;
- pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
-
- if( !db->mallocFailed ){
- aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
+ }else{
+ sqlite3 *db = pParse->db;
+ pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
+
+ if( !db->mallocFailed ){
+ aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
pTerm->pExpr->iTable = iTab;
- }
- sqlite3ExprDelete(db, pX);
- pX = pTerm->pExpr;
- }
-
+ }
+ sqlite3ExprDelete(db, pX);
+ pX = pTerm->pExpr;
+ }
+
if( eType==IN_INDEX_INDEX_DESC ){
testcase( bRev );
bRev = !bRev;
@@ -147012,28 +147012,28 @@ static int codeEqualityTerm(
if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){
pLoop->wsFlags |= WHERE_IN_EARLYOUT;
}
-
- i = pLevel->u.in.nIn;
- pLevel->u.in.nIn += nEq;
+
+ i = pLevel->u.in.nIn;
+ pLevel->u.in.nIn += nEq;
pLevel->u.in.aInLoop =
sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
pIn = pLevel->u.in.aInLoop;
if( pIn ){
- int iMap = 0; /* Index in aiMap[] */
- pIn += i;
- for(i=iEq;i<pLoop->nLTerm; i++){
- if( pLoop->aLTerm[i]->pExpr==pX ){
- int iOut = iReg + i - iEq;
- if( eType==IN_INDEX_ROWID ){
- pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut);
- }else{
- int iCol = aiMap ? aiMap[iMap++] : 0;
- pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut);
- }
- sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
- if( i==iEq ){
- pIn->iCur = iTab;
+ int iMap = 0; /* Index in aiMap[] */
+ pIn += i;
+ for(i=iEq;i<pLoop->nLTerm; i++){
+ if( pLoop->aLTerm[i]->pExpr==pX ){
+ int iOut = iReg + i - iEq;
+ if( eType==IN_INDEX_ROWID ){
+ pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut);
+ }else{
+ int iCol = aiMap ? aiMap[iMap++] : 0;
+ pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut);
+ }
+ sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
+ if( i==iEq ){
+ pIn->iCur = iTab;
pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
if( iEq>0 ){
pIn->iBase = iReg - i;
@@ -147041,11 +147041,11 @@ static int codeEqualityTerm(
}else{
pIn->nPrefix = 0;
}
- }else{
- pIn->eEndLoopOp = OP_Noop;
- }
- pIn++;
- }
+ }else{
+ pIn->eEndLoopOp = OP_Noop;
+ }
+ pIn++;
+ }
}
testcase( iEq>0
&& (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0
@@ -147058,7 +147058,7 @@ static int codeEqualityTerm(
}else{
pLevel->u.in.nIn = 0;
}
- sqlite3DbFree(pParse->db, aiMap);
+ sqlite3DbFree(pParse->db, aiMap);
#endif
}
@@ -147157,8 +147157,8 @@ static int codeAllEqualityTerms(
nReg = pLoop->u.btree.nEq + nExtraReg;
pParse->nMem += nReg;
- zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx));
- assert( zAff!=0 || pParse->db->mallocFailed );
+ zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx));
+ assert( zAff!=0 || pParse->db->mallocFailed );
if( nSkip ){
int iIdxCur = pLevel->iIdxCur;
@@ -147175,8 +147175,8 @@ static int codeAllEqualityTerms(
sqlite3VdbeJumpHere(v, j);
for(j=0; j<nSkip; j++){
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
- testcase( pIdx->aiColumn[j]==XN_EXPR );
- VdbeComment((v, "%s", explainIndexColumnName(pIdx, j)));
+ testcase( pIdx->aiColumn[j]==XN_EXPR );
+ VdbeComment((v, "%s", explainIndexColumnName(pIdx, j)));
}
}
@@ -147200,15 +147200,15 @@ static int codeAllEqualityTerms(
sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j);
}
}
- if( pTerm->eOperator & WO_IN ){
- if( pTerm->pExpr->flags & EP_xIsSelect ){
- /* No affinity ever needs to be (or should be) applied to a value
+ if( pTerm->eOperator & WO_IN ){
+ if( pTerm->pExpr->flags & EP_xIsSelect ){
+ /* No affinity ever needs to be (or should be) applied to a value
** from the RHS of an "? IN (SELECT ...)" expression. The
** sqlite3FindInIndex() routine has already ensured that the
- ** affinity of the comparison has been applied to the value. */
- if( zAff ) zAff[j] = SQLITE_AFF_BLOB;
- }
- }else if( (pTerm->eOperator & WO_ISNULL)==0 ){
+ ** affinity of the comparison has been applied to the value. */
+ if( zAff ) zAff[j] = SQLITE_AFF_BLOB;
+ }
+ }else if( (pTerm->eOperator & WO_ISNULL)==0 ){
Expr *pRight = pTerm->pExpr->pRight;
if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
@@ -147228,23 +147228,23 @@ static int codeAllEqualityTerms(
return regBase;
}
-#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
/*
-** If the most recently coded instruction is a constant range constraint
+** If the most recently coded instruction is a constant range constraint
** (a string literal) that originated from the LIKE optimization, then
-** set P3 and P5 on the OP_String opcode so that the string will be cast
-** to a BLOB at appropriate times.
+** set P3 and P5 on the OP_String opcode so that the string will be cast
+** to a BLOB at appropriate times.
**
** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range
** expression: "x>='ABC' AND x<'abd'". But this requires that the range
** scan loop run twice, once for strings and a second time for BLOBs.
** The OP_String opcodes on the second pass convert the upper and lower
-** bound string constants to blobs. This routine makes the necessary changes
+** bound string constants to blobs. This routine makes the necessary changes
** to the OP_String opcodes for that to happen.
-**
-** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then
-** only the one pass through the string space is required, so this routine
-** becomes a no-op.
+**
+** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then
+** only the one pass through the string space is required, so this routine
+** becomes a no-op.
*/
static void whereLikeOptimizationStringFixup(
Vdbe *v, /* prepared statement under construction */
@@ -147258,332 +147258,332 @@ static void whereLikeOptimizationStringFixup(
assert( pOp!=0 );
assert( pOp->opcode==OP_String8
|| pTerm->pWC->pWInfo->pParse->db->mallocFailed );
- pOp->p3 = (int)(pLevel->iLikeRepCntr>>1); /* Register holding counter */
- pOp->p5 = (u8)(pLevel->iLikeRepCntr&1); /* ASC or DESC */
- }
-}
-#else
-# define whereLikeOptimizationStringFixup(A,B,C)
-#endif
-
-#ifdef SQLITE_ENABLE_CURSOR_HINTS
-/*
-** Information is passed from codeCursorHint() down to individual nodes of
-** the expression tree (by sqlite3WalkExpr()) using an instance of this
-** structure.
-*/
-struct CCurHint {
- int iTabCur; /* Cursor for the main table */
- int iIdxCur; /* Cursor for the index, if pIdx!=0. Unused otherwise */
- Index *pIdx; /* The index used to access the table */
-};
-
-/*
-** This function is called for every node of an expression that is a candidate
-** for a cursor hint on an index cursor. For TK_COLUMN nodes that reference
-** the table CCurHint.iTabCur, verify that the same column can be
-** accessed through the index. If it cannot, then set pWalker->eCode to 1.
-*/
-static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){
- struct CCurHint *pHint = pWalker->u.pCCurHint;
- assert( pHint->pIdx!=0 );
- if( pExpr->op==TK_COLUMN
- && pExpr->iTable==pHint->iTabCur
+ pOp->p3 = (int)(pLevel->iLikeRepCntr>>1); /* Register holding counter */
+ pOp->p5 = (u8)(pLevel->iLikeRepCntr&1); /* ASC or DESC */
+ }
+}
+#else
+# define whereLikeOptimizationStringFixup(A,B,C)
+#endif
+
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+/*
+** Information is passed from codeCursorHint() down to individual nodes of
+** the expression tree (by sqlite3WalkExpr()) using an instance of this
+** structure.
+*/
+struct CCurHint {
+ int iTabCur; /* Cursor for the main table */
+ int iIdxCur; /* Cursor for the index, if pIdx!=0. Unused otherwise */
+ Index *pIdx; /* The index used to access the table */
+};
+
+/*
+** This function is called for every node of an expression that is a candidate
+** for a cursor hint on an index cursor. For TK_COLUMN nodes that reference
+** the table CCurHint.iTabCur, verify that the same column can be
+** accessed through the index. If it cannot, then set pWalker->eCode to 1.
+*/
+static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){
+ struct CCurHint *pHint = pWalker->u.pCCurHint;
+ assert( pHint->pIdx!=0 );
+ if( pExpr->op==TK_COLUMN
+ && pExpr->iTable==pHint->iTabCur
&& sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn)<0
- ){
- pWalker->eCode = 1;
- }
- return WRC_Continue;
-}
-
-/*
-** Test whether or not expression pExpr, which was part of a WHERE clause,
-** should be included in the cursor-hint for a table that is on the rhs
+ ){
+ pWalker->eCode = 1;
+ }
+ return WRC_Continue;
+}
+
+/*
+** Test whether or not expression pExpr, which was part of a WHERE clause,
+** should be included in the cursor-hint for a table that is on the rhs
** of a LEFT JOIN. Set Walker.eCode to non-zero before returning if the
-** expression is not suitable.
-**
-** An expression is unsuitable if it might evaluate to non NULL even if
-** a TK_COLUMN node that does affect the value of the expression is set
-** to NULL. For example:
-**
-** col IS NULL
-** col IS NOT NULL
-** coalesce(col, 1)
-** CASE WHEN col THEN 0 ELSE 1 END
-*/
-static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){
+** expression is not suitable.
+**
+** An expression is unsuitable if it might evaluate to non NULL even if
+** a TK_COLUMN node that does affect the value of the expression is set
+** to NULL. For example:
+**
+** col IS NULL
+** col IS NOT NULL
+** coalesce(col, 1)
+** CASE WHEN col THEN 0 ELSE 1 END
+*/
+static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_IS
|| pExpr->op==TK_ISNULL || pExpr->op==TK_ISNOT
|| pExpr->op==TK_NOTNULL || pExpr->op==TK_CASE
- ){
- pWalker->eCode = 1;
- }else if( pExpr->op==TK_FUNCTION ){
- int d1;
- char d2[4];
- if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){
- pWalker->eCode = 1;
- }
- }
-
- return WRC_Continue;
-}
-
-
-/*
-** This function is called on every node of an expression tree used as an
-** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN
-** that accesses any table other than the one identified by
-** CCurHint.iTabCur, then do the following:
-**
+ ){
+ pWalker->eCode = 1;
+ }else if( pExpr->op==TK_FUNCTION ){
+ int d1;
+ char d2[4];
+ if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){
+ pWalker->eCode = 1;
+ }
+ }
+
+ return WRC_Continue;
+}
+
+
+/*
+** This function is called on every node of an expression tree used as an
+** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN
+** that accesses any table other than the one identified by
+** CCurHint.iTabCur, then do the following:
+**
** 1) allocate a register and code an OP_Column instruction to read
-** the specified column into the new register, and
-**
+** the specified column into the new register, and
+**
** 2) transform the expression node to a TK_REGISTER node that reads
-** from the newly populated register.
-**
-** Also, if the node is a TK_COLUMN that does access the table idenified
-** by pCCurHint.iTabCur, and an index is being used (which we will
-** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into
-** an access of the index rather than the original table.
-*/
-static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){
- int rc = WRC_Continue;
- struct CCurHint *pHint = pWalker->u.pCCurHint;
- if( pExpr->op==TK_COLUMN ){
- if( pExpr->iTable!=pHint->iTabCur ){
- int reg = ++pWalker->pParse->nMem; /* Register for column value */
+** from the newly populated register.
+**
+** Also, if the node is a TK_COLUMN that does access the table idenified
+** by pCCurHint.iTabCur, and an index is being used (which we will
+** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into
+** an access of the index rather than the original table.
+*/
+static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){
+ int rc = WRC_Continue;
+ struct CCurHint *pHint = pWalker->u.pCCurHint;
+ if( pExpr->op==TK_COLUMN ){
+ if( pExpr->iTable!=pHint->iTabCur ){
+ int reg = ++pWalker->pParse->nMem; /* Register for column value */
sqlite3ExprCode(pWalker->pParse, pExpr, reg);
- pExpr->op = TK_REGISTER;
- pExpr->iTable = reg;
- }else if( pHint->pIdx!=0 ){
- pExpr->iTable = pHint->iIdxCur;
+ pExpr->op = TK_REGISTER;
+ pExpr->iTable = reg;
+ }else if( pHint->pIdx!=0 ){
+ pExpr->iTable = pHint->iIdxCur;
pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn);
- assert( pExpr->iColumn>=0 );
- }
- }else if( pExpr->op==TK_AGG_FUNCTION ){
- /* An aggregate function in the WHERE clause of a query means this must
- ** be a correlated sub-query, and expression pExpr is an aggregate from
- ** the parent context. Do not walk the function arguments in this case.
- **
- ** todo: It should be possible to replace this node with a TK_REGISTER
+ assert( pExpr->iColumn>=0 );
+ }
+ }else if( pExpr->op==TK_AGG_FUNCTION ){
+ /* An aggregate function in the WHERE clause of a query means this must
+ ** be a correlated sub-query, and expression pExpr is an aggregate from
+ ** the parent context. Do not walk the function arguments in this case.
+ **
+ ** todo: It should be possible to replace this node with a TK_REGISTER
** expression, as the result of the expression must be stored in a
- ** register at this point. The same holds for TK_AGG_COLUMN nodes. */
- rc = WRC_Prune;
- }
- return rc;
-}
-
-/*
-** Insert an OP_CursorHint instruction if it is appropriate to do so.
-*/
-static void codeCursorHint(
+ ** register at this point. The same holds for TK_AGG_COLUMN nodes. */
+ rc = WRC_Prune;
+ }
+ return rc;
+}
+
+/*
+** Insert an OP_CursorHint instruction if it is appropriate to do so.
+*/
+static void codeCursorHint(
SrcItem *pTabItem, /* FROM clause item */
- WhereInfo *pWInfo, /* The where clause */
- WhereLevel *pLevel, /* Which loop to provide hints for */
- WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */
-){
- Parse *pParse = pWInfo->pParse;
- sqlite3 *db = pParse->db;
- Vdbe *v = pParse->pVdbe;
- Expr *pExpr = 0;
- WhereLoop *pLoop = pLevel->pWLoop;
- int iCur;
- WhereClause *pWC;
- WhereTerm *pTerm;
- int i, j;
- struct CCurHint sHint;
- Walker sWalker;
-
- if( OptimizationDisabled(db, SQLITE_CursorHints) ) return;
- iCur = pLevel->iTabCur;
- assert( iCur==pWInfo->pTabList->a[pLevel->iFrom].iCursor );
- sHint.iTabCur = iCur;
- sHint.iIdxCur = pLevel->iIdxCur;
- sHint.pIdx = pLoop->u.btree.pIndex;
- memset(&sWalker, 0, sizeof(sWalker));
- sWalker.pParse = pParse;
- sWalker.u.pCCurHint = &sHint;
- pWC = &pWInfo->sWC;
- for(i=0; i<pWC->nTerm; i++){
- pTerm = &pWC->a[i];
- if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( pTerm->prereqAll & pLevel->notReady ) continue;
-
+ WhereInfo *pWInfo, /* The where clause */
+ WhereLevel *pLevel, /* Which loop to provide hints for */
+ WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */
+){
+ Parse *pParse = pWInfo->pParse;
+ sqlite3 *db = pParse->db;
+ Vdbe *v = pParse->pVdbe;
+ Expr *pExpr = 0;
+ WhereLoop *pLoop = pLevel->pWLoop;
+ int iCur;
+ WhereClause *pWC;
+ WhereTerm *pTerm;
+ int i, j;
+ struct CCurHint sHint;
+ Walker sWalker;
+
+ if( OptimizationDisabled(db, SQLITE_CursorHints) ) return;
+ iCur = pLevel->iTabCur;
+ assert( iCur==pWInfo->pTabList->a[pLevel->iFrom].iCursor );
+ sHint.iTabCur = iCur;
+ sHint.iIdxCur = pLevel->iIdxCur;
+ sHint.pIdx = pLoop->u.btree.pIndex;
+ memset(&sWalker, 0, sizeof(sWalker));
+ sWalker.pParse = pParse;
+ sWalker.u.pCCurHint = &sHint;
+ pWC = &pWInfo->sWC;
+ for(i=0; i<pWC->nTerm; i++){
+ pTerm = &pWC->a[i];
+ if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+ if( pTerm->prereqAll & pLevel->notReady ) continue;
+
/* Any terms specified as part of the ON(...) clause for any LEFT
- ** JOIN for which the current table is not the rhs are omitted
+ ** JOIN for which the current table is not the rhs are omitted
** from the cursor-hint.
- **
+ **
** If this table is the rhs of a LEFT JOIN, "IS" or "IS NULL" terms
- ** that were specified as part of the WHERE clause must be excluded.
- ** This is to address the following:
- **
- ** SELECT ... t1 LEFT JOIN t2 ON (t1.a=t2.b) WHERE t2.c IS NULL;
- **
- ** Say there is a single row in t2 that matches (t1.a=t2.b), but its
+ ** that were specified as part of the WHERE clause must be excluded.
+ ** This is to address the following:
+ **
+ ** SELECT ... t1 LEFT JOIN t2 ON (t1.a=t2.b) WHERE t2.c IS NULL;
+ **
+ ** Say there is a single row in t2 that matches (t1.a=t2.b), but its
** t2.c values is not NULL. If the (t2.c IS NULL) constraint is
- ** pushed down to the cursor, this row is filtered out, causing
- ** SQLite to synthesize a row of NULL values. Which does match the
- ** WHERE clause, and so the query returns a row. Which is incorrect.
- **
- ** For the same reason, WHERE terms such as:
- **
- ** WHERE 1 = (t2.c IS NULL)
- **
- ** are also excluded. See codeCursorHintIsOrFunction() for details.
- */
- if( pTabItem->fg.jointype & JT_LEFT ){
- Expr *pExpr = pTerm->pExpr;
+ ** pushed down to the cursor, this row is filtered out, causing
+ ** SQLite to synthesize a row of NULL values. Which does match the
+ ** WHERE clause, and so the query returns a row. Which is incorrect.
+ **
+ ** For the same reason, WHERE terms such as:
+ **
+ ** WHERE 1 = (t2.c IS NULL)
+ **
+ ** are also excluded. See codeCursorHintIsOrFunction() for details.
+ */
+ if( pTabItem->fg.jointype & JT_LEFT ){
+ Expr *pExpr = pTerm->pExpr;
if( !ExprHasProperty(pExpr, EP_FromJoin)
- || pExpr->iRightJoinTable!=pTabItem->iCursor
- ){
- sWalker.eCode = 0;
- sWalker.xExprCallback = codeCursorHintIsOrFunction;
- sqlite3WalkExpr(&sWalker, pTerm->pExpr);
- if( sWalker.eCode ) continue;
- }
- }else{
- if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue;
- }
-
- /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize
- ** the cursor. These terms are not needed as hints for a pure range
- ** scan (that has no == terms) so omit them. */
- if( pLoop->u.btree.nEq==0 && pTerm!=pEndRange ){
- for(j=0; j<pLoop->nLTerm && pLoop->aLTerm[j]!=pTerm; j++){}
- if( j<pLoop->nLTerm ) continue;
- }
-
- /* No subqueries or non-deterministic functions allowed */
- if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue;
-
- /* For an index scan, make sure referenced columns are actually in
- ** the index. */
- if( sHint.pIdx!=0 ){
- sWalker.eCode = 0;
- sWalker.xExprCallback = codeCursorHintCheckExpr;
- sqlite3WalkExpr(&sWalker, pTerm->pExpr);
- if( sWalker.eCode ) continue;
- }
-
- /* If we survive all prior tests, that means this term is worth hinting */
+ || pExpr->iRightJoinTable!=pTabItem->iCursor
+ ){
+ sWalker.eCode = 0;
+ sWalker.xExprCallback = codeCursorHintIsOrFunction;
+ sqlite3WalkExpr(&sWalker, pTerm->pExpr);
+ if( sWalker.eCode ) continue;
+ }
+ }else{
+ if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue;
+ }
+
+ /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize
+ ** the cursor. These terms are not needed as hints for a pure range
+ ** scan (that has no == terms) so omit them. */
+ if( pLoop->u.btree.nEq==0 && pTerm!=pEndRange ){
+ for(j=0; j<pLoop->nLTerm && pLoop->aLTerm[j]!=pTerm; j++){}
+ if( j<pLoop->nLTerm ) continue;
+ }
+
+ /* No subqueries or non-deterministic functions allowed */
+ if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue;
+
+ /* For an index scan, make sure referenced columns are actually in
+ ** the index. */
+ if( sHint.pIdx!=0 ){
+ sWalker.eCode = 0;
+ sWalker.xExprCallback = codeCursorHintCheckExpr;
+ sqlite3WalkExpr(&sWalker, pTerm->pExpr);
+ if( sWalker.eCode ) continue;
+ }
+
+ /* If we survive all prior tests, that means this term is worth hinting */
pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
- }
- if( pExpr!=0 ){
- sWalker.xExprCallback = codeCursorHintFixExpr;
- sqlite3WalkExpr(&sWalker, pExpr);
+ }
+ if( pExpr!=0 ){
+ sWalker.xExprCallback = codeCursorHintFixExpr;
+ sqlite3WalkExpr(&sWalker, pExpr);
sqlite3VdbeAddOp4(v, OP_CursorHint,
- (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0,
- (const char*)pExpr, P4_EXPR);
- }
-}
-#else
-# define codeCursorHint(A,B,C,D) /* No-op */
-#endif /* SQLITE_ENABLE_CURSOR_HINTS */
-
-/*
-** Cursor iCur is open on an intkey b-tree (a table). Register iRowid contains
-** a rowid value just read from cursor iIdxCur, open on index pIdx. This
+ (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0,
+ (const char*)pExpr, P4_EXPR);
+ }
+}
+#else
+# define codeCursorHint(A,B,C,D) /* No-op */
+#endif /* SQLITE_ENABLE_CURSOR_HINTS */
+
+/*
+** Cursor iCur is open on an intkey b-tree (a table). Register iRowid contains
+** a rowid value just read from cursor iIdxCur, open on index pIdx. This
** function generates code to do a deferred seek of cursor iCur to the
-** rowid stored in register iRowid.
-**
-** Normally, this is just:
-**
-** OP_DeferredSeek $iCur $iRowid
-**
-** However, if the scan currently being coded is a branch of an OR-loop and
-** the statement currently being coded is a SELECT, then P3 of OP_DeferredSeek
-** is set to iIdxCur and P4 is set to point to an array of integers
+** rowid stored in register iRowid.
+**
+** Normally, this is just:
+**
+** OP_DeferredSeek $iCur $iRowid
+**
+** However, if the scan currently being coded is a branch of an OR-loop and
+** the statement currently being coded is a SELECT, then P3 of OP_DeferredSeek
+** is set to iIdxCur and P4 is set to point to an array of integers
** containing one entry for each column of the table cursor iCur is open
** on. For each table column, if the column is the i'th column of the
-** index, then the corresponding array entry is set to (i+1). If the column
-** does not appear in the index at all, the array entry is set to 0.
-*/
-static void codeDeferredSeek(
- WhereInfo *pWInfo, /* Where clause context */
- Index *pIdx, /* Index scan is using */
- int iCur, /* Cursor for IPK b-tree */
- int iIdxCur /* Index cursor */
-){
- Parse *pParse = pWInfo->pParse; /* Parse context */
- Vdbe *v = pParse->pVdbe; /* Vdbe to generate code within */
-
- assert( iIdxCur>0 );
- assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 );
+** index, then the corresponding array entry is set to (i+1). If the column
+** does not appear in the index at all, the array entry is set to 0.
+*/
+static void codeDeferredSeek(
+ WhereInfo *pWInfo, /* Where clause context */
+ Index *pIdx, /* Index scan is using */
+ int iCur, /* Cursor for IPK b-tree */
+ int iIdxCur /* Index cursor */
+){
+ Parse *pParse = pWInfo->pParse; /* Parse context */
+ Vdbe *v = pParse->pVdbe; /* Vdbe to generate code within */
+
+ assert( iIdxCur>0 );
+ assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 );
pWInfo->bDeferredSeek = 1;
- sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur);
- if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
- && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask)
- ){
- int i;
- Table *pTab = pIdx->pTable;
+ sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur);
+ if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
+ && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask)
+ ){
+ int i;
+ Table *pTab = pIdx->pTable;
u32 *ai = (u32*)sqlite3DbMallocZero(pParse->db, sizeof(u32)*(pTab->nCol+1));
- if( ai ){
- ai[0] = pTab->nCol;
- for(i=0; i<pIdx->nColumn-1; i++){
+ if( ai ){
+ ai[0] = pTab->nCol;
+ for(i=0; i<pIdx->nColumn-1; i++){
int x1, x2;
- assert( pIdx->aiColumn[i]<pTab->nCol );
+ assert( pIdx->aiColumn[i]<pTab->nCol );
x1 = pIdx->aiColumn[i];
x2 = sqlite3TableColumnToStorage(pTab, x1);
testcase( x1!=x2 );
if( x1>=0 ) ai[x2+1] = i+1;
- }
- sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY);
- }
- }
-}
-
-/*
-** If the expression passed as the second argument is a vector, generate
-** code to write the first nReg elements of the vector into an array
-** of registers starting with iReg.
-**
-** If the expression is not a vector, then nReg must be passed 1. In
-** this case, generate code to evaluate the expression and leave the
-** result in register iReg.
-*/
-static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
- assert( nReg>0 );
- if( p && sqlite3ExprIsVector(p) ){
-#ifndef SQLITE_OMIT_SUBQUERY
+ }
+ sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY);
+ }
+ }
+}
+
+/*
+** If the expression passed as the second argument is a vector, generate
+** code to write the first nReg elements of the vector into an array
+** of registers starting with iReg.
+**
+** If the expression is not a vector, then nReg must be passed 1. In
+** this case, generate code to evaluate the expression and leave the
+** result in register iReg.
+*/
+static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
+ assert( nReg>0 );
+ if( p && sqlite3ExprIsVector(p) ){
+#ifndef SQLITE_OMIT_SUBQUERY
if( ExprUseXSelect(p) ){
- Vdbe *v = pParse->pVdbe;
+ Vdbe *v = pParse->pVdbe;
int iSelect;
assert( p->op==TK_SELECT );
iSelect = sqlite3CodeSubselect(pParse, p);
- sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
- }else
-#endif
- {
- int i;
+ sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
+ }else
+#endif
+ {
+ int i;
const ExprList *pList;
assert( ExprUseXList(p) );
pList = p->x.pList;
- assert( nReg<=pList->nExpr );
- for(i=0; i<nReg; i++){
- sqlite3ExprCode(pParse, pList->a[i].pExpr, iReg+i);
- }
- }
- }else{
+ assert( nReg<=pList->nExpr );
+ for(i=0; i<nReg; i++){
+ sqlite3ExprCode(pParse, pList->a[i].pExpr, iReg+i);
+ }
+ }
+ }else{
assert( nReg==1 || pParse->nErr );
- sqlite3ExprCode(pParse, p, iReg);
- }
-}
-
-/* An instance of the IdxExprTrans object carries information about a
-** mapping from an expression on table columns into a column in an index
-** down through the Walker.
-*/
-typedef struct IdxExprTrans {
- Expr *pIdxExpr; /* The index expression */
- int iTabCur; /* The cursor of the corresponding table */
- int iIdxCur; /* The cursor for the index */
- int iIdxCol; /* The column for the index */
+ sqlite3ExprCode(pParse, p, iReg);
+ }
+}
+
+/* An instance of the IdxExprTrans object carries information about a
+** mapping from an expression on table columns into a column in an index
+** down through the Walker.
+*/
+typedef struct IdxExprTrans {
+ Expr *pIdxExpr; /* The index expression */
+ int iTabCur; /* The cursor of the corresponding table */
+ int iIdxCur; /* The cursor for the index */
+ int iIdxCol; /* The column for the index */
int iTabCol; /* The column for the table */
WhereInfo *pWInfo; /* Complete WHERE clause information */
sqlite3 *db; /* Database connection (for malloc()) */
-} IdxExprTrans;
-
+} IdxExprTrans;
+
/*
** Preserve pExpr on the WhereETrans list of the WhereInfo.
*/
@@ -147597,30 +147597,30 @@ static void preserveExpr(IdxExprTrans *pTrans, Expr *pExpr){
memcpy(&pNew->orig, pExpr, sizeof(*pExpr));
}
-/* The walker node callback used to transform matching expressions into
-** a reference to an index column for an index on an expression.
-**
-** If pExpr matches, then transform it into a reference to the index column
-** that contains the value of pExpr.
-*/
-static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
- IdxExprTrans *pX = p->u.pIdxTrans;
- if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
+/* The walker node callback used to transform matching expressions into
+** a reference to an index column for an index on an expression.
+**
+** If pExpr matches, then transform it into a reference to the index column
+** that contains the value of pExpr.
+*/
+static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
+ IdxExprTrans *pX = p->u.pIdxTrans;
+ if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
preserveExpr(pX, pExpr);
pExpr->affExpr = sqlite3ExprAffinity(pExpr);
- pExpr->op = TK_COLUMN;
- pExpr->iTable = pX->iIdxCur;
- pExpr->iColumn = pX->iIdxCol;
+ pExpr->op = TK_COLUMN;
+ pExpr->iTable = pX->iIdxCur;
+ pExpr->iColumn = pX->iIdxCol;
testcase( ExprHasProperty(pExpr, EP_Skip) );
testcase( ExprHasProperty(pExpr, EP_Unlikely) );
ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn);
pExpr->y.pTab = 0;
- return WRC_Prune;
- }else{
- return WRC_Continue;
- }
-}
-
+ return WRC_Prune;
+ }else{
+ return WRC_Continue;
+ }
+}
+
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
/* A walker node callback that translates a column reference to a table
** into a corresponding column reference of an index.
@@ -147641,37 +147641,37 @@ static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){
}
#endif /* SQLITE_OMIT_GENERATED_COLUMNS */
-/*
-** For an indexes on expression X, locate every instance of expression X
-** in pExpr and change that subexpression into a reference to the appropriate
-** column of the index.
+/*
+** For an indexes on expression X, locate every instance of expression X
+** in pExpr and change that subexpression into a reference to the appropriate
+** column of the index.
**
** 2019-10-24: Updated to also translate references to a VIRTUAL column in
** the table into references to the corresponding (stored) column of the
** index.
-*/
-static void whereIndexExprTrans(
- Index *pIdx, /* The Index */
- int iTabCur, /* Cursor of the table that is being indexed */
- int iIdxCur, /* Cursor of the index itself */
- WhereInfo *pWInfo /* Transform expressions in this WHERE clause */
-){
- int iIdxCol; /* Column number of the index */
- ExprList *aColExpr; /* Expressions that are indexed */
+*/
+static void whereIndexExprTrans(
+ Index *pIdx, /* The Index */
+ int iTabCur, /* Cursor of the table that is being indexed */
+ int iIdxCur, /* Cursor of the index itself */
+ WhereInfo *pWInfo /* Transform expressions in this WHERE clause */
+){
+ int iIdxCol; /* Column number of the index */
+ ExprList *aColExpr; /* Expressions that are indexed */
Table *pTab;
- Walker w;
- IdxExprTrans x;
- aColExpr = pIdx->aColExpr;
+ Walker w;
+ IdxExprTrans x;
+ aColExpr = pIdx->aColExpr;
if( aColExpr==0 && !pIdx->bHasVCol ){
/* The index does not reference any expressions or virtual columns
** so no translations are needed. */
return;
}
pTab = pIdx->pTable;
- memset(&w, 0, sizeof(w));
- w.u.pIdxTrans = &x;
- x.iTabCur = iTabCur;
- x.iIdxCur = iIdxCur;
+ memset(&w, 0, sizeof(w));
+ w.u.pIdxTrans = &x;
+ x.iTabCur = iTabCur;
+ x.iIdxCur = iIdxCur;
x.pWInfo = pWInfo;
x.db = pWInfo->pParse->db;
for(iIdxCol=0; iIdxCol<pIdx->nColumn; iIdxCol++){
@@ -147700,14 +147700,14 @@ static void whereIndexExprTrans(
}else{
continue;
}
- x.iIdxCol = iIdxCol;
- sqlite3WalkExpr(&w, pWInfo->pWhere);
- sqlite3WalkExprList(&w, pWInfo->pOrderBy);
- sqlite3WalkExprList(&w, pWInfo->pResultSet);
- }
-}
-
-/*
+ x.iIdxCol = iIdxCol;
+ sqlite3WalkExpr(&w, pWInfo->pWhere);
+ sqlite3WalkExprList(&w, pWInfo->pOrderBy);
+ sqlite3WalkExprList(&w, pWInfo->pResultSet);
+ }
+}
+
+/*
** The pTruth expression is always true because it is the WHERE clause
** a partial index that is driving a query loop. Look through all of the
** WHERE clause terms on the query, and if any of those terms must be
@@ -147757,12 +147757,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3 *db; /* Database connection */
SrcItem *pTabItem; /* FROM clause term being coded */
int addrBrk; /* Jump here to break out of the loop */
- int addrHalt; /* addrBrk for the outermost loop */
+ int addrHalt; /* addrBrk for the outermost loop */
int addrCont; /* Jump here to continue with next cycle */
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
int iReleaseReg = 0; /* Temp register to free before returning */
- Index *pIdx = 0; /* Index used by loop (if any) */
- int iLoop; /* Iteration of constraint generator loop */
+ Index *pIdx = 0; /* Index used by loop (if any) */
+ int iLoop; /* Iteration of constraint generator loop */
pWC = &pWInfo->sWC;
db = pParse->db;
@@ -147808,19 +147808,19 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
|| pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
);
- if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
+ if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
pLevel->iLeftJoin = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
VdbeComment((v, "init LEFT JOIN no-match flag"));
}
- /* Compute a safe address to jump to if we discover that the table for
- ** this loop is empty and can never contribute content. */
- for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){}
- addrHalt = pWInfo->a[j].addrBrk;
-
+ /* Compute a safe address to jump to if we discover that the table for
+ ** this loop is empty and can never contribute content. */
+ for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){}
+ addrHalt = pWInfo->a[j].addrBrk;
+
/* Special case of a FROM clause subquery implemented as a co-routine */
- if( pTabItem->fg.viaCoroutine ){
+ if( pTabItem->fg.viaCoroutine ){
int regYield = pTabItem->regReturn;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
@@ -147837,94 +147837,94 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int iReg; /* P3 Value for OP_VFilter */
int addrNotFound;
int nConstraint = pLoop->nLTerm;
- int iIn; /* Counter for IN constraints */
+ int iIn; /* Counter for IN constraints */
iReg = sqlite3GetTempRange(pParse, nConstraint+2);
addrNotFound = pLevel->addrBrk;
for(j=0; j<nConstraint; j++){
int iTarget = iReg+j+2;
pTerm = pLoop->aLTerm[j];
- if( NEVER(pTerm==0) ) continue;
+ if( NEVER(pTerm==0) ) continue;
if( pTerm->eOperator & WO_IN ){
codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
addrNotFound = pLevel->addrNxt;
}else{
- Expr *pRight = pTerm->pExpr->pRight;
- codeExprOrVector(pParse, pRight, iTarget, 1);
+ Expr *pRight = pTerm->pExpr->pRight;
+ codeExprOrVector(pParse, pRight, iTarget, 1);
}
}
sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
pLoop->u.vtab.idxStr,
- pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC);
+ pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC);
VdbeCoverage(v);
pLoop->u.vtab.needFree = 0;
/* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed
** the u.vtab.idxStr. NULL it out to prevent a use-after-free */
if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
- pLevel->p1 = iCur;
- pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
- pLevel->p2 = sqlite3VdbeCurrentAddr(v);
+ pLevel->p1 = iCur;
+ pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
+ pLevel->p2 = sqlite3VdbeCurrentAddr(v);
assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
if( pLoop->wsFlags & WHERE_IN_ABLE ){
iIn = pLevel->u.in.nIn;
}else{
iIn = 0;
}
- for(j=nConstraint-1; j>=0; j--){
- pTerm = pLoop->aLTerm[j];
+ for(j=nConstraint-1; j>=0; j--){
+ pTerm = pLoop->aLTerm[j];
if( (pTerm->eOperator & WO_IN)!=0 ) iIn--;
- if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
- disableTerm(pLevel, pTerm);
+ if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
+ disableTerm(pLevel, pTerm);
}else if( (pTerm->eOperator & WO_IN)!=0
&& sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1
){
- Expr *pCompare; /* The comparison operator */
- Expr *pRight; /* RHS of the comparison */
- VdbeOp *pOp; /* Opcode to access the value of the IN constraint */
-
- /* Reload the constraint value into reg[iReg+j+2]. The same value
- ** was loaded into the same register prior to the OP_VFilter, but
- ** the xFilter implementation might have changed the datatype or
- ** encoding of the value in the register, so it *must* be reloaded. */
- assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed );
- if( !db->mallocFailed ){
+ Expr *pCompare; /* The comparison operator */
+ Expr *pRight; /* RHS of the comparison */
+ VdbeOp *pOp; /* Opcode to access the value of the IN constraint */
+
+ /* Reload the constraint value into reg[iReg+j+2]. The same value
+ ** was loaded into the same register prior to the OP_VFilter, but
+ ** the xFilter implementation might have changed the datatype or
+ ** encoding of the value in the register, so it *must* be reloaded. */
+ assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed );
+ if( !db->mallocFailed ){
assert( iIn>=0 && iIn<pLevel->u.in.nIn );
pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop);
- assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid );
- assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 );
- assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 );
- testcase( pOp->opcode==OP_Rowid );
- sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
- }
-
+ assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid );
+ assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 );
+ assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 );
+ testcase( pOp->opcode==OP_Rowid );
+ sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
+ }
+
/* Generate code that will continue to the next row if
- ** the IN constraint is not satisfied */
- pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
- assert( pCompare!=0 || db->mallocFailed );
- if( pCompare ){
- pCompare->pLeft = pTerm->pExpr->pLeft;
- pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
- if( pRight ){
- pRight->iTable = iReg+j+2;
+ ** the IN constraint is not satisfied */
+ pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
+ assert( pCompare!=0 || db->mallocFailed );
+ if( pCompare ){
+ pCompare->pLeft = pTerm->pExpr->pLeft;
+ pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
+ if( pRight ){
+ pRight->iTable = iReg+j+2;
sqlite3ExprIfFalse(
pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL
);
- }
- pCompare->pLeft = 0;
- sqlite3ExprDelete(db, pCompare);
- }
+ }
+ pCompare->pLeft = 0;
+ sqlite3ExprDelete(db, pCompare);
+ }
}
}
assert( iIn==0 || db->mallocFailed );
- /* These registers need to be preserved in case there is an IN operator
- ** loop. So we could deallocate the registers here (and potentially
- ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
- ** simpler and safer to simply not reuse the registers.
- **
- ** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
- */
+ /* These registers need to be preserved in case there is an IN operator
+ ** loop. So we could deallocate the registers here (and potentially
+ ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
+ ** simpler and safer to simply not reuse the registers.
+ **
+ ** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
+ */
}else
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -147945,7 +147945,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
addrNxt = pLevel->addrNxt;
- sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
VdbeCoverage(v);
pLevel->op = OP_Noop;
}else if( (pLoop->wsFlags & WHERE_IPK)!=0
@@ -147968,11 +147968,11 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
pStart = pEnd;
pEnd = pTerm;
}
- codeCursorHint(pTabItem, pWInfo, pLevel, pEnd);
+ codeCursorHint(pTabItem, pWInfo, pLevel, pEnd);
if( pStart ){
Expr *pX; /* The expression that defines the start bound */
int r1, rTemp; /* Registers for holding the start boundary */
- int op; /* Cursor seek operation */
+ int op; /* Cursor seek operation */
/* The following constant maps TK_xx codes into corresponding
** seek opcodes. It depends on a particular ordering of TK_xx
@@ -147992,9 +147992,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
pX = pStart->pExpr;
assert( pX!=0 );
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
- if( sqlite3ExprIsVector(pX->pRight) ){
- r1 = rTemp = sqlite3GetTempReg(pParse);
- codeExprOrVector(pParse, pX->pRight, r1, 1);
+ if( sqlite3ExprIsVector(pX->pRight) ){
+ r1 = rTemp = sqlite3GetTempReg(pParse);
+ codeExprOrVector(pParse, pX->pRight, r1, 1);
testcase( pX->op==TK_GT );
testcase( pX->op==TK_GE );
testcase( pX->op==TK_LT );
@@ -148004,12 +148004,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
assert( pX->op!=TK_GE || op==OP_SeekGE );
assert( pX->op!=TK_LT || op==OP_SeekLE );
assert( pX->op!=TK_LE || op==OP_SeekLE );
- }else{
- r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
- disableTerm(pLevel, pStart);
- op = aMoveOp[(pX->op - TK_GT)];
- }
- sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1);
+ }else{
+ r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
+ disableTerm(pLevel, pStart);
+ op = aMoveOp[(pX->op - TK_GT)];
+ }
+ sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1);
VdbeComment((v, "pk"));
VdbeCoverageIf(v, pX->op==TK_GT);
VdbeCoverageIf(v, pX->op==TK_LE);
@@ -148017,7 +148017,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
VdbeCoverageIf(v, pX->op==TK_GE);
sqlite3ReleaseTempReg(pParse, rTemp);
}else{
- sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt);
+ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
}
@@ -148029,17 +148029,17 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
testcase( pEnd->wtFlags & TERM_VIRTUAL );
memEndValue = ++pParse->nMem;
- codeExprOrVector(pParse, pX->pRight, memEndValue, 1);
+ codeExprOrVector(pParse, pX->pRight, memEndValue, 1);
if( 0==sqlite3ExprIsVector(pX->pRight)
&& (pX->op==TK_LT || pX->op==TK_GT)
- ){
+ ){
testOp = bRev ? OP_Le : OP_Ge;
}else{
testOp = bRev ? OP_Lt : OP_Gt;
}
- if( 0==sqlite3ExprIsVector(pX->pRight) ){
- disableTerm(pLevel, pEnd);
- }
+ if( 0==sqlite3ExprIsVector(pX->pRight) ){
+ disableTerm(pLevel, pEnd);
+ }
}
start = sqlite3VdbeCurrentAddr(v);
pLevel->op = bRev ? OP_Prev : OP_Next;
@@ -148105,8 +148105,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
OP_IdxLT, /* 3: (end_constraints && bRev && endEq) */
};
u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */
- u16 nBtm = pLoop->u.btree.nBtm; /* Length of BTM vector */
- u16 nTop = pLoop->u.btree.nTop; /* Length of TOP vector */
+ u16 nBtm = pLoop->u.btree.nBtm; /* Length of BTM vector */
+ u16 nTop = pLoop->u.btree.nTop; /* Length of TOP vector */
int regBase; /* Base register holding constraint values */
WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */
WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */
@@ -148118,7 +148118,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int nExtraReg = 0; /* Number of extra registers needed */
int op; /* Instruction opcode */
char *zStartAff; /* Affinity for start of range constraint */
- char *zEndAff = 0; /* Affinity for end of range constraint */
+ char *zEndAff = 0; /* Affinity for end of range constraint */
u8 bSeekPastNull = 0; /* True to seek past initial nulls */
u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */
int omitTable; /* True if we use the index only */
@@ -148135,36 +148135,36 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
j = nEq;
if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
pRangeStart = pLoop->aLTerm[j++];
- nExtraReg = MAX(nExtraReg, pLoop->u.btree.nBtm);
+ nExtraReg = MAX(nExtraReg, pLoop->u.btree.nBtm);
/* Like optimization range constraints always occur in pairs */
assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 ||
(pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 );
}
if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
pRangeEnd = pLoop->aLTerm[j++];
- nExtraReg = MAX(nExtraReg, pLoop->u.btree.nTop);
-#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ nExtraReg = MAX(nExtraReg, pLoop->u.btree.nTop);
+#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
assert( pRangeStart!=0 ); /* LIKE opt constraints */
assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */
- pLevel->iLikeRepCntr = (u32)++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 1, (int)pLevel->iLikeRepCntr);
- VdbeComment((v, "LIKE loop counter"));
- pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v);
- /* iLikeRepCntr actually stores 2x the counter register number. The
- ** bottom bit indicates whether the search order is ASC or DESC. */
+ pLevel->iLikeRepCntr = (u32)++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, (int)pLevel->iLikeRepCntr);
+ VdbeComment((v, "LIKE loop counter"));
+ pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v);
+ /* iLikeRepCntr actually stores 2x the counter register number. The
+ ** bottom bit indicates whether the search order is ASC or DESC. */
testcase( bRev );
testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
- assert( (bRev & ~1)==0 );
- pLevel->iLikeRepCntr <<=1;
- pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC);
+ assert( (bRev & ~1)==0 );
+ pLevel->iLikeRepCntr <<=1;
+ pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC);
}
-#endif
- if( pRangeStart==0 ){
- j = pIdx->aiColumn[nEq];
- if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){
- bSeekPastNull = 1;
- }
+#endif
+ if( pRangeStart==0 ){
+ j = pIdx->aiColumn[nEq];
+ if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){
+ bSeekPastNull = 1;
+ }
}
}
assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
@@ -148198,7 +148198,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) ){
SWAP(WhereTerm *, pRangeEnd, pRangeStart);
SWAP(u8, bSeekPastNull, bStopAtNull);
- SWAP(u8, nBtm, nTop);
+ SWAP(u8, nBtm, nTop);
}
if( iLevel>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 ){
@@ -148207,18 +148207,18 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur);
}
- /* Generate code to evaluate all constraint terms using == or IN
- ** and store the values of those terms in an array of registers
- ** starting at regBase.
- */
- codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd);
- regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
- assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
- if( zStartAff && nTop ){
- zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]);
- }
+ /* Generate code to evaluate all constraint terms using == or IN
+ ** and store the values of those terms in an array of registers
+ ** starting at regBase.
+ */
+ codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd);
+ regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
+ assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
+ if( zStartAff && nTop ){
+ zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]);
+ }
addrNxt = (regBignull ? pLevel->addrBignull : pLevel->addrNxt);
-
+
testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
@@ -148231,7 +148231,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
nConstraint = nEq;
if( pRangeStart ){
Expr *pRight = pRangeStart->pExpr->pRight;
- codeExprOrVector(pParse, pRight, regBase+nEq, nBtm);
+ codeExprOrVector(pParse, pRight, regBase+nEq, nBtm);
whereLikeOptimizationStringFixup(v, pLevel, pRangeStart);
if( (pRangeStart->wtFlags & TERM_VNULL)==0
&& sqlite3ExprCanBeNull(pRight)
@@ -148240,16 +148240,16 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
VdbeCoverage(v);
}
if( zStartAff ){
- updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]);
+ updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]);
}
- nConstraint += nBtm;
+ nConstraint += nBtm;
testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
- if( sqlite3ExprIsVector(pRight)==0 ){
- disableTerm(pLevel, pRangeStart);
- }else{
- startEq = 1;
- }
- bSeekPastNull = 0;
+ if( sqlite3ExprIsVector(pRight)==0 ){
+ disableTerm(pLevel, pRangeStart);
+ }else{
+ startEq = 1;
+ }
+ bSeekPastNull = 0;
}else if( bSeekPastNull ){
startEq = 0;
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
@@ -148261,18 +148261,18 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
nConstraint++;
}
codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
- if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){
- /* The skip-scan logic inside the call to codeAllEqualityConstraints()
- ** above has already left the cursor sitting on the correct row,
- ** so no further seeking is needed */
- }else{
+ if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){
+ /* The skip-scan logic inside the call to codeAllEqualityConstraints()
+ ** above has already left the cursor sitting on the correct row,
+ ** so no further seeking is needed */
+ }else{
if( regBignull ){
sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull);
VdbeComment((v, "NULL-scan pass ctr"));
}
- op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
- assert( op!=0 );
+ op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
+ assert( op!=0 );
if( (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 && op==OP_SeekGE ){
assert( regBignull==0 );
/* TUNING: The OP_SeekScan opcode seeks to reduce the number
@@ -148287,14 +148287,14 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
(pIdx->aiRowLogEst[0]+9)/10);
VdbeCoverage(v);
}
- sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
- VdbeCoverage(v);
- VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
- VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last );
- VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT );
- VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
- VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
- VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT );
+ sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
+ VdbeCoverage(v);
+ VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
+ VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last );
+ VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT );
+ VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
+ VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
+ VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT );
assert( bSeekPastNull==0 || bStopAtNull==0 );
if( regBignull ){
@@ -148312,7 +148312,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
assert( op==OP_Rewind || op==OP_Last || op==OP_SeekGE || op==OP_SeekLE);
}
- }
+ }
/* Load the value for the inequality constraint at the end of the
** range (if any).
@@ -148331,7 +148331,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
*/
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
}
- codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
+ codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
if( (pRangeEnd->wtFlags & TERM_VNULL)==0
&& sqlite3ExprCanBeNull(pRight)
@@ -148339,20 +148339,20 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
VdbeCoverage(v);
}
- if( zEndAff ){
- updateRangeAffinityStr(pRight, nTop, zEndAff);
- codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff);
- }else{
- assert( pParse->db->mallocFailed );
+ if( zEndAff ){
+ updateRangeAffinityStr(pRight, nTop, zEndAff);
+ codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff);
+ }else{
+ assert( pParse->db->mallocFailed );
}
- nConstraint += nTop;
+ nConstraint += nTop;
testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
-
- if( sqlite3ExprIsVector(pRight)==0 ){
- disableTerm(pLevel, pRangeEnd);
- }else{
- endEq = 1;
- }
+
+ if( sqlite3ExprIsVector(pRight)==0 ){
+ disableTerm(pLevel, pRangeEnd);
+ }else{
+ endEq = 1;
+ }
}else if( bStopAtNull ){
if( regBignull==0 ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
@@ -148361,7 +148361,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
nConstraint++;
}
sqlite3DbFree(db, zStartAff);
- sqlite3DbFree(db, zEndAff);
+ sqlite3DbFree(db, zEndAff);
/* Top of the loop body */
if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v);
@@ -148443,7 +148443,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
}
-
+
/* If a partial index is driving the loop, try to eliminate WHERE clause
** terms from the query that must be true due to the WHERE clause of
** the partial index.
@@ -148461,8 +148461,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** a LEFT JOIN: */
assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 );
}
-
- /* Record the instruction used to terminate the loop. */
+
+ /* Record the instruction used to terminate the loop. */
if( pLoop->wsFlags & WHERE_ONEROW ){
pLevel->op = OP_Noop;
}else if( bRev ){
@@ -148477,7 +148477,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
}else{
assert( pLevel->p5==0 );
}
- if( omitTable ) pIdx = 0;
+ if( omitTable ) pIdx = 0;
}else
#ifndef SQLITE_OMIT_OR_OPTIMIZATION
@@ -148539,7 +148539,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int ii; /* Loop counter */
Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
Table *pTab = pTabItem->pTab;
-
+
pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->eOperator & WO_OR );
@@ -148615,9 +148615,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
Expr *pExpr = pWC->a[iTerm].pExpr;
if( &pWC->a[iTerm] == pTerm ) continue;
- testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
- testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
- if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
+ testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
+ testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
+ if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
pExpr = sqlite3ExprDup(db, pExpr, 0);
@@ -148644,7 +148644,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
WhereInfo *pSubWInfo; /* Info for single OR-term scan */
Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
Expr *pDelete; /* Local copy of OR clause term */
- int jmp1 = 0; /* Address of jump operation */
+ int jmp1 = 0; /* Address of jump operation */
testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0
&& !ExprHasProperty(pOrExpr, EP_FromJoin)
); /* See TH3 vtab25.400 and ticket 614b25314c766238 */
@@ -148679,7 +148679,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
if( HasRowid(pTab) ){
sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid);
- jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0,
+ jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0,
regRowid, iSet);
VdbeCoverage(v);
}else{
@@ -148707,13 +148707,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** need to insert the key into the temp table, as it will never
** be tested for. */
if( iSet ){
- jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk);
+ jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk);
VdbeCoverage(v);
}
if( iSet>=0 ){
sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, regRowset, regRowid,
- r, nPk);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, regRowset, regRowid,
+ r, nPk);
if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
}
@@ -148727,7 +148727,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
/* Jump here (skipping the main loop body subroutine) if the
** current sub-WHERE row is a duplicate from prior sub-WHEREs. */
- if( jmp1 ) sqlite3VdbeJumpHere(v, jmp1);
+ if( jmp1 ) sqlite3VdbeJumpHere(v, jmp1);
/* The pSubWInfo->untestedTerms flag means that this OR term
** contained one or more AND term from a notReady table. The
@@ -148781,7 +148781,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3ExprDelete(db, pAndExpr);
}
sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
- sqlite3VdbeGoto(v, pLevel->addrBrk);
+ sqlite3VdbeGoto(v, pLevel->addrBrk);
sqlite3VdbeResolveLabel(v, iLoopBody);
if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
@@ -148796,15 +148796,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
static const u8 aStep[] = { OP_Next, OP_Prev };
static const u8 aStart[] = { OP_Rewind, OP_Last };
assert( bRev==0 || bRev==1 );
- if( pTabItem->fg.isRecursive ){
+ if( pTabItem->fg.isRecursive ){
/* Tables marked isRecursive have only a single row that is stored in
** a pseudo-cursor. No need to Rewind or Next such cursors. */
pLevel->op = OP_Noop;
}else{
- codeCursorHint(pTabItem, pWInfo, pLevel, 0);
+ codeCursorHint(pTabItem, pWInfo, pLevel, 0);
pLevel->op = aStep[bRev];
pLevel->p1 = iCur;
- pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt);
+ pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
@@ -148817,81 +148817,81 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
/* Insert code to test every subexpression that can be completely
** computed using the current set of tables.
- **
- ** This loop may run between one and three times, depending on the
- ** constraints to be generated. The value of stack variable iLoop
- ** determines the constraints coded by each iteration, as follows:
- **
- ** iLoop==1: Code only expressions that are entirely covered by pIdx.
- ** iLoop==2: Code remaining expressions that do not contain correlated
+ **
+ ** This loop may run between one and three times, depending on the
+ ** constraints to be generated. The value of stack variable iLoop
+ ** determines the constraints coded by each iteration, as follows:
+ **
+ ** iLoop==1: Code only expressions that are entirely covered by pIdx.
+ ** iLoop==2: Code remaining expressions that do not contain correlated
** sub-queries.
- ** iLoop==3: Code all remaining expressions.
- **
- ** An effort is made to skip unnecessary iterations of the loop.
- */
- iLoop = (pIdx ? 1 : 2);
- do{
- int iNext = 0; /* Next value for iLoop */
- for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
- Expr *pE;
- int skipLikeAddr = 0;
- testcase( pTerm->wtFlags & TERM_VIRTUAL );
- testcase( pTerm->wtFlags & TERM_CODED );
- if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
- testcase( pWInfo->untestedTerms==0
- && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 );
- pWInfo->untestedTerms = 1;
- continue;
- }
- pE = pTerm->pExpr;
- assert( pE!=0 );
+ ** iLoop==3: Code all remaining expressions.
+ **
+ ** An effort is made to skip unnecessary iterations of the loop.
+ */
+ iLoop = (pIdx ? 1 : 2);
+ do{
+ int iNext = 0; /* Next value for iLoop */
+ for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
+ Expr *pE;
+ int skipLikeAddr = 0;
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
+ testcase( pTerm->wtFlags & TERM_CODED );
+ if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+ if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
+ testcase( pWInfo->untestedTerms==0
+ && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 );
+ pWInfo->untestedTerms = 1;
+ continue;
+ }
+ pE = pTerm->pExpr;
+ assert( pE!=0 );
if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){
- continue;
- }
-
- if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
- iNext = 2;
- continue;
- }
- if( iLoop<3 && (pTerm->wtFlags & TERM_VARSELECT) ){
- if( iNext==0 ) iNext = 3;
- continue;
- }
-
+ continue;
+ }
+
+ if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
+ iNext = 2;
+ continue;
+ }
+ if( iLoop<3 && (pTerm->wtFlags & TERM_VARSELECT) ){
+ if( iNext==0 ) iNext = 3;
+ continue;
+ }
+
if( (pTerm->wtFlags & TERM_LIKECOND)!=0 ){
- /* If the TERM_LIKECOND flag is set, that means that the range search
- ** is sufficient to guarantee that the LIKE operator is true, so we
- ** can skip the call to the like(A,B) function. But this only works
- ** for strings. So do not skip the call to the function on the pass
- ** that compares BLOBs. */
-#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
- continue;
-#else
- u32 x = pLevel->iLikeRepCntr;
+ /* If the TERM_LIKECOND flag is set, that means that the range search
+ ** is sufficient to guarantee that the LIKE operator is true, so we
+ ** can skip the call to the like(A,B) function. But this only works
+ ** for strings. So do not skip the call to the function on the pass
+ ** that compares BLOBs. */
+#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ continue;
+#else
+ u32 x = pLevel->iLikeRepCntr;
if( x>0 ){
skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1));
VdbeCoverageIf(v, (x&1)==1);
VdbeCoverageIf(v, (x&1)==0);
}
-#endif
- }
-#ifdef WHERETRACE_ENABLED /* 0xffff */
- if( sqlite3WhereTrace ){
- VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d",
- pWC->nTerm-j, pTerm, iLoop));
- }
+#endif
+ }
+#ifdef WHERETRACE_ENABLED /* 0xffff */
+ if( sqlite3WhereTrace ){
+ VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d",
+ pWC->nTerm-j, pTerm, iLoop));
+ }
if( sqlite3WhereTrace & 0x800 ){
sqlite3DebugPrintf("Coding auxiliary constraint:\n");
sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
}
-#endif
- sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
- if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
- pTerm->wtFlags |= TERM_CODED;
+#endif
+ sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
+ if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
+ pTerm->wtFlags |= TERM_CODED;
}
- iLoop = iNext;
- }while( iLoop>0 );
+ iLoop = iNext;
+ }while( iLoop>0 );
/* Insert code to test for implied constraints based on transitivity
** of the "==" operator.
@@ -148902,7 +148902,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** the implied "t1.a=123" constraint.
*/
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
- Expr *pE, sEAlt;
+ Expr *pE, sEAlt;
WhereTerm *pAlt;
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
@@ -148933,9 +148933,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
testcase( pAlt->eOperator & WO_IS );
testcase( pAlt->eOperator & WO_IN );
VdbeModuleComment((v, "begin transitive constraint"));
- sEAlt = *pAlt->pExpr;
- sEAlt.pLeft = pE->pLeft;
- sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL);
+ sEAlt = *pAlt->pExpr;
+ sEAlt.pLeft = pE->pLeft;
+ sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL);
pAlt->wtFlags |= TERM_CODED;
}
@@ -149042,7 +149042,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
if( pWC->nTerm>=pWC->nSlot ){
WhereTerm *pOld = pWC->a;
sqlite3 *db = pWC->pWInfo->pParse->db;
- pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
+ pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
if( pWC->a==0 ){
if( wtFlags & TERM_DYNAMIC ){
sqlite3ExprDelete(db, p);
@@ -149066,15 +149066,15 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
pTerm->wtFlags = wtFlags;
pTerm->pWC = pWC;
pTerm->iParent = -1;
- memset(&pTerm->eOperator, 0,
- sizeof(WhereTerm) - offsetof(WhereTerm,eOperator));
+ memset(&pTerm->eOperator, 0,
+ sizeof(WhereTerm) - offsetof(WhereTerm,eOperator));
return idx;
}
/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term. The allowed operators are
-** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL"
+** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL"
*/
static int allowedOp(int op){
assert( TK_GT>TK_EQ && TK_GT<TK_GE );
@@ -149165,7 +149165,7 @@ static int isLikeOrGlob(
sqlite3 *db = pParse->db; /* Database connection */
sqlite3_value *pVal = 0;
int op; /* Opcode of pRight */
- int rc; /* Result code to return */
+ int rc; /* Result code to return */
if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, (char*)wc) ){
return 0;
@@ -149179,12 +149179,12 @@ static int isLikeOrGlob(
pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
op = pRight->op;
- if( op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
+ if( op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){
Vdbe *pReprepare = pParse->pReprepare;
int iCol = pRight->iColumn;
pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB);
if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
- z = sqlite3_value_text(pVal);
+ z = sqlite3_value_text(pVal);
}
sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
@@ -149193,41 +149193,41 @@ static int isLikeOrGlob(
z = (u8*)pRight->u.zToken;
}
if( z ){
-
- /* Count the number of prefix characters prior to the first wildcard */
+
+ /* Count the number of prefix characters prior to the first wildcard */
cnt = 0;
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
- if( c==wc[3] && z[cnt]!=0 ) cnt++;
+ if( c==wc[3] && z[cnt]!=0 ) cnt++;
}
-
- /* The optimization is possible only if (1) the pattern does not begin
- ** with a wildcard and if (2) the non-wildcard prefix does not end with
+
+ /* The optimization is possible only if (1) the pattern does not begin
+ ** with a wildcard and if (2) the non-wildcard prefix does not end with
** an (illegal 0xff) character, or (3) the pattern does not consist of
** a single escape character. The second condition is necessary so
- ** that we can increment the prefix key to find an upper bound for the
+ ** that we can increment the prefix key to find an upper bound for the
** range search. The third is because the caller assumes that the pattern
** consists of at least one character after all escapes have been
** removed. */
if( cnt!=0 && 255!=(u8)z[cnt-1] && (cnt>1 || z[0]!=wc[3]) ){
Expr *pPrefix;
-
- /* A "complete" match if the pattern ends with "*" or "%" */
+
+ /* A "complete" match if the pattern ends with "*" or "%" */
*pisComplete = c==wc[0] && z[cnt+1]==0;
-
- /* Get the pattern prefix. Remove all escapes from the prefix. */
- pPrefix = sqlite3Expr(db, TK_STRING, (char*)z);
- if( pPrefix ){
- int iFrom, iTo;
+
+ /* Get the pattern prefix. Remove all escapes from the prefix. */
+ pPrefix = sqlite3Expr(db, TK_STRING, (char*)z);
+ if( pPrefix ){
+ int iFrom, iTo;
char *zNew;
assert( !ExprHasProperty(pPrefix, EP_IntValue) );
zNew = pPrefix->u.zToken;
- zNew[cnt] = 0;
- for(iFrom=iTo=0; iFrom<cnt; iFrom++){
- if( zNew[iFrom]==wc[3] ) iFrom++;
- zNew[iTo++] = zNew[iFrom];
- }
- zNew[iTo] = 0;
+ zNew[cnt] = 0;
+ for(iFrom=iTo=0; iFrom<cnt; iFrom++){
+ if( zNew[iFrom]==wc[3] ) iFrom++;
+ zNew[iTo++] = zNew[iFrom];
+ }
+ zNew[iTo] = 0;
assert( iTo>0 );
/* If the LHS is not an ordinary column with TEXT affinity, then the
@@ -149267,11 +149267,11 @@ static int isLikeOrGlob(
return 0;
}
}
- }
+ }
*ppPrefix = pPrefix;
-
- /* If the RHS pattern is a bound parameter, make arrangements to
- ** reprepare the statement when that parameter is rebound */
+
+ /* If the RHS pattern is a bound parameter, make arrangements to
+ ** reprepare the statement when that parameter is rebound */
if( op==TK_VARIABLE ){
Vdbe *v = pParse->pVdbe;
sqlite3VdbeSetVarmask(v, pRight->iColumn);
@@ -149294,66 +149294,66 @@ static int isLikeOrGlob(
}
}
- rc = (z!=0);
+ rc = (z!=0);
sqlite3ValueFree(pVal);
- return rc;
+ return rc;
}
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
-** Check to see if the pExpr expression is a form that needs to be passed
-** to the xBestIndex method of virtual tables. Forms of interest include:
-**
-** Expression Virtual Table Operator
-** ----------------------- ---------------------------------
-** 1. column MATCH expr SQLITE_INDEX_CONSTRAINT_MATCH
-** 2. column GLOB expr SQLITE_INDEX_CONSTRAINT_GLOB
-** 3. column LIKE expr SQLITE_INDEX_CONSTRAINT_LIKE
-** 4. column REGEXP expr SQLITE_INDEX_CONSTRAINT_REGEXP
-** 5. column != expr SQLITE_INDEX_CONSTRAINT_NE
-** 6. expr != column SQLITE_INDEX_CONSTRAINT_NE
-** 7. column IS NOT expr SQLITE_INDEX_CONSTRAINT_ISNOT
-** 8. expr IS NOT column SQLITE_INDEX_CONSTRAINT_ISNOT
-** 9. column IS NOT NULL SQLITE_INDEX_CONSTRAINT_ISNOTNULL
-**
-** In every case, "column" must be a column of a virtual table. If there
+** Check to see if the pExpr expression is a form that needs to be passed
+** to the xBestIndex method of virtual tables. Forms of interest include:
+**
+** Expression Virtual Table Operator
+** ----------------------- ---------------------------------
+** 1. column MATCH expr SQLITE_INDEX_CONSTRAINT_MATCH
+** 2. column GLOB expr SQLITE_INDEX_CONSTRAINT_GLOB
+** 3. column LIKE expr SQLITE_INDEX_CONSTRAINT_LIKE
+** 4. column REGEXP expr SQLITE_INDEX_CONSTRAINT_REGEXP
+** 5. column != expr SQLITE_INDEX_CONSTRAINT_NE
+** 6. expr != column SQLITE_INDEX_CONSTRAINT_NE
+** 7. column IS NOT expr SQLITE_INDEX_CONSTRAINT_ISNOT
+** 8. expr IS NOT column SQLITE_INDEX_CONSTRAINT_ISNOT
+** 9. column IS NOT NULL SQLITE_INDEX_CONSTRAINT_ISNOTNULL
+**
+** In every case, "column" must be a column of a virtual table. If there
** is a match, set *ppLeft to the "column" expression, set *ppRight to the
-** "expr" expression (even though in forms (6) and (8) the column is on the
-** right and the expression is on the left). Also set *peOp2 to the
-** appropriate virtual table operator. The return value is 1 or 2 if there
-** is a match. The usual return is 1, but if the RHS is also a column
-** of virtual table in forms (5) or (7) then return 2.
-**
-** If the expression matches none of the patterns above, return 0.
-*/
-static int isAuxiliaryVtabOperator(
+** "expr" expression (even though in forms (6) and (8) the column is on the
+** right and the expression is on the left). Also set *peOp2 to the
+** appropriate virtual table operator. The return value is 1 or 2 if there
+** is a match. The usual return is 1, but if the RHS is also a column
+** of virtual table in forms (5) or (7) then return 2.
+**
+** If the expression matches none of the patterns above, return 0.
+*/
+static int isAuxiliaryVtabOperator(
sqlite3 *db, /* Parsing context */
- Expr *pExpr, /* Test this expression */
- unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */
- Expr **ppLeft, /* Column expression to left of MATCH/op2 */
- Expr **ppRight /* Expression to left of MATCH/op2 */
-){
- if( pExpr->op==TK_FUNCTION ){
- static const struct Op2 {
- const char *zOp;
- unsigned char eOp2;
- } aOp[] = {
- { "match", SQLITE_INDEX_CONSTRAINT_MATCH },
- { "glob", SQLITE_INDEX_CONSTRAINT_GLOB },
- { "like", SQLITE_INDEX_CONSTRAINT_LIKE },
- { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP }
- };
- ExprList *pList;
- Expr *pCol; /* Column reference */
- int i;
+ Expr *pExpr, /* Test this expression */
+ unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */
+ Expr **ppLeft, /* Column expression to left of MATCH/op2 */
+ Expr **ppRight /* Expression to left of MATCH/op2 */
+){
+ if( pExpr->op==TK_FUNCTION ){
+ static const struct Op2 {
+ const char *zOp;
+ unsigned char eOp2;
+ } aOp[] = {
+ { "match", SQLITE_INDEX_CONSTRAINT_MATCH },
+ { "glob", SQLITE_INDEX_CONSTRAINT_GLOB },
+ { "like", SQLITE_INDEX_CONSTRAINT_LIKE },
+ { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP }
+ };
+ ExprList *pList;
+ Expr *pCol; /* Column reference */
+ int i;
assert( ExprUseXList(pExpr) );
- pList = pExpr->x.pList;
- if( pList==0 || pList->nExpr!=2 ){
- return 0;
- }
+ pList = pExpr->x.pList;
+ if( pList==0 || pList->nExpr!=2 ){
+ return 0;
+ }
/* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a
** virtual table on their second argument, which is the same as
@@ -149362,7 +149362,7 @@ static int isAuxiliaryVtabOperator(
** vtab_column MATCH expression
** MATCH(expression,vtab_column)
*/
- pCol = pList->a[1].pExpr;
+ pCol = pList->a[1].pExpr;
assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) );
testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
if( ExprIsVtab(pCol) ){
@@ -149375,7 +149375,7 @@ static int isAuxiliaryVtabOperator(
return 1;
}
}
- }
+ }
/* We can also match against the first column of overloaded
** functions where xFindFunction returns a value of at least
@@ -149408,31 +149408,31 @@ static int isAuxiliaryVtabOperator(
*ppLeft = pCol;
return 1;
}
- }
- }
- }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
- int res = 0;
- Expr *pLeft = pExpr->pLeft;
- Expr *pRight = pExpr->pRight;
+ }
+ }
+ }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
+ int res = 0;
+ Expr *pLeft = pExpr->pLeft;
+ Expr *pRight = pExpr->pRight;
assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) );
testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 );
if( ExprIsVtab(pLeft) ){
- res++;
- }
+ res++;
+ }
assert( pRight==0 || pRight->op!=TK_COLUMN || ExprUseYTab(pRight) );
testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 );
if( pRight && ExprIsVtab(pRight) ){
- res++;
- SWAP(Expr*, pLeft, pRight);
- }
- *ppLeft = pLeft;
- *ppRight = pRight;
- if( pExpr->op==TK_NE ) *peOp2 = SQLITE_INDEX_CONSTRAINT_NE;
- if( pExpr->op==TK_ISNOT ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOT;
- if( pExpr->op==TK_NOTNULL ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOTNULL;
- return res;
- }
- return 0;
+ res++;
+ SWAP(Expr*, pLeft, pRight);
+ }
+ *ppLeft = pLeft;
+ *ppRight = pRight;
+ if( pExpr->op==TK_NE ) *peOp2 = SQLITE_INDEX_CONSTRAINT_NE;
+ if( pExpr->op==TK_ISNOT ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOT;
+ if( pExpr->op==TK_NOTNULL ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOTNULL;
+ return res;
+ }
+ return 0;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -149510,8 +149510,8 @@ static void whereCombineDisjuncts(
&& (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return;
assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 );
assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 );
- if( sqlite3ExprCompare(0,pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
- if( sqlite3ExprCompare(0,pOne->pExpr->pRight, pTwo->pExpr->pRight,-1) )return;
+ if( sqlite3ExprCompare(0,pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
+ if( sqlite3ExprCompare(0,pOne->pExpr->pRight, pTwo->pExpr->pRight,-1) )return;
/* If we reach this point, it means the two subterms can be combined */
if( (eOp & (eOp-1))!=0 ){
if( eOp & (WO_LT|WO_LE) ){
@@ -149646,7 +149646,7 @@ static void exprAnalyzeOrTerm(
if( pOrInfo==0 ) return;
pTerm->wtFlags |= TERM_ORINFO;
pOrWc = &pOrInfo->wc;
- memset(pOrWc->aStatic, 0, sizeof(pOrWc->aStatic));
+ memset(pOrWc->aStatic, 0, sizeof(pOrWc->aStatic));
sqlite3WhereClauseInit(pOrWc, pWInfo);
sqlite3WhereSplit(pOrWc, pExpr, TK_OR);
sqlite3WhereExprAnalyze(pSrc, pOrWc);
@@ -149663,7 +149663,7 @@ static void exprAnalyzeOrTerm(
WhereAndInfo *pAndInfo;
assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 );
chngToIN = 0;
- pAndInfo = sqlite3DbMallocRawNN(db, sizeof(*pAndInfo));
+ pAndInfo = sqlite3DbMallocRawNN(db, sizeof(*pAndInfo));
if( pAndInfo ){
WhereClause *pAndWC;
WhereTerm *pAndTerm;
@@ -149674,7 +149674,7 @@ static void exprAnalyzeOrTerm(
pOrTerm->eOperator = WO_AND;
pOrTerm->leftCursor = -1;
pAndWC = &pAndInfo->wc;
- memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic));
+ memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic));
sqlite3WhereClauseInit(pAndWC, pWC->pWInfo);
sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
sqlite3WhereExprAnalyze(pSrc, pAndWC);
@@ -149683,8 +149683,8 @@ static void exprAnalyzeOrTerm(
for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
assert( pAndTerm->pExpr );
if( allowedOp(pAndTerm->pExpr->op)
- || pAndTerm->eOperator==WO_AUX
- ){
+ || pAndTerm->eOperator==WO_AUX
+ ){
b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
}
}
@@ -149858,7 +149858,7 @@ static void exprAnalyzeOrTerm(
}
assert( pLeft!=0 );
pDup = sqlite3ExprDup(db, pLeft, 0);
- pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0);
+ pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0);
if( pNew ){
int idxNew;
transferJoinMarkings(pNew, pExpr);
@@ -149907,7 +149907,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){
}
pColl = sqlite3ExprCompareCollSeq(pParse, pExpr);
if( sqlite3IsBinary(pColl) ) return 1;
- return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight);
+ return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight);
}
/*
@@ -149940,73 +149940,73 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
}
/*
-** Expression pExpr is one operand of a comparison operator that might
-** be useful for indexing. This routine checks to see if pExpr appears
-** in any index. Return TRUE (1) if pExpr is an indexed term and return
-** FALSE (0) if not. If TRUE is returned, also set aiCurCol[0] to the cursor
-** number of the table that is indexed and aiCurCol[1] to the column number
-** of the column that is indexed, or XN_EXPR (-2) if an expression is being
-** indexed.
-**
-** If pExpr is a TK_COLUMN column reference, then this routine always returns
-** true even if that particular column is not indexed, because the column
-** might be added to an automatic index later.
-*/
-static SQLITE_NOINLINE int exprMightBeIndexed2(
- SrcList *pFrom, /* The FROM clause */
- Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
- int *aiCurCol, /* Write the referenced table cursor and column here */
- Expr *pExpr /* An operand of a comparison operator */
-){
- Index *pIdx;
- int i;
- int iCur;
- for(i=0; mPrereq>1; i++, mPrereq>>=1){}
- iCur = pFrom->a[i].iCursor;
- for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->aColExpr==0 ) continue;
- for(i=0; i<pIdx->nKeyCol; i++){
- if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
- if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
- aiCurCol[0] = iCur;
- aiCurCol[1] = XN_EXPR;
- return 1;
- }
- }
- }
- return 0;
-}
-static int exprMightBeIndexed(
- SrcList *pFrom, /* The FROM clause */
- Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
- int *aiCurCol, /* Write the referenced table cursor & column here */
- Expr *pExpr, /* An operand of a comparison operator */
- int op /* The specific comparison operator */
-){
+** Expression pExpr is one operand of a comparison operator that might
+** be useful for indexing. This routine checks to see if pExpr appears
+** in any index. Return TRUE (1) if pExpr is an indexed term and return
+** FALSE (0) if not. If TRUE is returned, also set aiCurCol[0] to the cursor
+** number of the table that is indexed and aiCurCol[1] to the column number
+** of the column that is indexed, or XN_EXPR (-2) if an expression is being
+** indexed.
+**
+** If pExpr is a TK_COLUMN column reference, then this routine always returns
+** true even if that particular column is not indexed, because the column
+** might be added to an automatic index later.
+*/
+static SQLITE_NOINLINE int exprMightBeIndexed2(
+ SrcList *pFrom, /* The FROM clause */
+ Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
+ int *aiCurCol, /* Write the referenced table cursor and column here */
+ Expr *pExpr /* An operand of a comparison operator */
+){
+ Index *pIdx;
+ int i;
+ int iCur;
+ for(i=0; mPrereq>1; i++, mPrereq>>=1){}
+ iCur = pFrom->a[i].iCursor;
+ for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->aColExpr==0 ) continue;
+ for(i=0; i<pIdx->nKeyCol; i++){
+ if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
+ if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
+ aiCurCol[0] = iCur;
+ aiCurCol[1] = XN_EXPR;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+static int exprMightBeIndexed(
+ SrcList *pFrom, /* The FROM clause */
+ Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
+ int *aiCurCol, /* Write the referenced table cursor & column here */
+ Expr *pExpr, /* An operand of a comparison operator */
+ int op /* The specific comparison operator */
+){
/* If this expression is a vector to the left or right of a
** inequality constraint (>, <, >= or <=), perform the processing
- ** on the first element of the vector. */
- assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE );
- assert( TK_IS<TK_GE && TK_ISNULL<TK_GE && TK_IN<TK_GE );
- assert( op<=TK_GE );
- if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
+ ** on the first element of the vector. */
+ assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE );
+ assert( TK_IS<TK_GE && TK_ISNULL<TK_GE && TK_IN<TK_GE );
+ assert( op<=TK_GE );
+ if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
assert( ExprUseXList(pExpr) );
- pExpr = pExpr->x.pList->a[0].pExpr;
-
- }
-
- if( pExpr->op==TK_COLUMN ){
- aiCurCol[0] = pExpr->iTable;
- aiCurCol[1] = pExpr->iColumn;
- return 1;
- }
- if( mPrereq==0 ) return 0; /* No table references */
- if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */
- return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
-}
-
-
-/*
+ pExpr = pExpr->x.pList->a[0].pExpr;
+
+ }
+
+ if( pExpr->op==TK_COLUMN ){
+ aiCurCol[0] = pExpr->iTable;
+ aiCurCol[1] = pExpr->iColumn;
+ return 1;
+ }
+ if( mPrereq==0 ) return 0; /* No table references */
+ if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */
+ return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
+}
+
+
+/*
** The input to this routine is an WhereTerm structure with only the
** "pExpr" field filled in. The job of this routine is to analyze the
** subexpression and populate all the other fields of the WhereTerm
@@ -150042,8 +150042,8 @@ static void exprAnalyze(
int op; /* Top-level operator. pExpr->op */
Parse *pParse = pWInfo->pParse; /* Parsing context */
sqlite3 *db = pParse->db; /* Database connection */
- unsigned char eOp2 = 0; /* op2 value for LIKE/REGEXP/GLOB */
- int nLeft; /* Number of elements on left side vector */
+ unsigned char eOp2 = 0; /* op2 value for LIKE/REGEXP/GLOB */
+ int nLeft; /* Number of elements on left side vector */
if( db->mallocFailed ){
return;
@@ -150056,7 +150056,7 @@ static void exprAnalyze(
op = pExpr->op;
if( op==TK_IN ){
assert( pExpr->pRight==0 );
- if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
+ if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
if( ExprUseXSelect(pExpr) ){
pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect);
}else{
@@ -150067,47 +150067,47 @@ static void exprAnalyze(
}else{
pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight);
}
- pMaskSet->bVarSelect = 0;
+ pMaskSet->bVarSelect = 0;
prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr);
- if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT;
+ if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT;
if( ExprHasProperty(pExpr, EP_FromJoin) ){
Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
prereqAll |= x;
extraRight = x-1; /* ON clause terms may not be used with an index
** on left table of a LEFT JOIN. Ticket #3015 */
- if( (prereqAll>>1)>=x ){
- sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
- return;
- }
+ if( (prereqAll>>1)>=x ){
+ sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
+ return;
+ }
}
pTerm->prereqAll = prereqAll;
pTerm->leftCursor = -1;
pTerm->iParent = -1;
pTerm->eOperator = 0;
if( allowedOp(op) ){
- int aiCurCol[2];
+ int aiCurCol[2];
Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
-
+
if( pTerm->u.x.iField>0 ){
- assert( op==TK_IN );
- assert( pLeft->op==TK_VECTOR );
+ assert( op==TK_IN );
+ assert( pLeft->op==TK_VECTOR );
assert( ExprUseXList(pLeft) );
pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr;
- }
-
- if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
- pTerm->leftCursor = aiCurCol[0];
+ }
+
+ if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
+ pTerm->leftCursor = aiCurCol[0];
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
pTerm->u.x.leftColumn = aiCurCol[1];
pTerm->eOperator = operatorMask(op) & opMask;
}
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
if( pRight
- && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
+ && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
&& !ExprHasProperty(pRight, EP_FixedCol)
- ){
+ ){
WhereTerm *pNew;
Expr *pDup;
u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
@@ -150136,7 +150136,7 @@ static void exprAnalyze(
pNew = pTerm;
}
pNew->wtFlags |= exprCommute(pParse, pDup);
- pNew->leftCursor = aiCurCol[0];
+ pNew->leftCursor = aiCurCol[0];
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
pNew->u.x.leftColumn = aiCurCol[1];
testcase( (prereqLeft | extraRight) != prereqLeft );
@@ -150186,7 +150186,7 @@ static void exprAnalyze(
int idxNew;
pNewExpr = sqlite3PExpr(pParse, ops[i],
sqlite3ExprDup(db, pExpr->pLeft, 0),
- sqlite3ExprDup(db, pList->a[i].pExpr, 0));
+ sqlite3ExprDup(db, pList->a[i].pExpr, 0));
transferJoinMarkings(pNewExpr, pExpr);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
@@ -150312,7 +150312,7 @@ static void exprAnalyze(
pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
- pStr1);
+ pStr1);
transferJoinMarkings(pNewExpr1, pExpr);
idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags);
testcase( idxNew1==0 );
@@ -150320,7 +150320,7 @@ static void exprAnalyze(
pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName),
- pStr2);
+ pStr2);
transferJoinMarkings(pNewExpr2, pExpr);
idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags);
testcase( idxNew2==0 );
@@ -150333,66 +150333,66 @@ static void exprAnalyze(
}
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
- /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create
- ** new terms for each component comparison - "a = ?" and "b = ?". The
- ** new terms completely replace the original vector comparison, which is
- ** no longer used.
- **
- ** This is only required if at least one side of the comparison operation
- ** is not a sub-select. */
+ /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create
+ ** new terms for each component comparison - "a = ?" and "b = ?". The
+ ** new terms completely replace the original vector comparison, which is
+ ** no longer used.
+ **
+ ** This is only required if at least one side of the comparison operation
+ ** is not a sub-select. */
if( (pExpr->op==TK_EQ || pExpr->op==TK_IS)
&& (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
&& sqlite3ExprVectorSize(pExpr->pRight)==nLeft
&& ( (pExpr->pLeft->flags & EP_xIsSelect)==0
|| (pExpr->pRight->flags & EP_xIsSelect)==0)
&& pWC->op==TK_AND
- ){
- int i;
- for(i=0; i<nLeft; i++){
- int idxNew;
- Expr *pNew;
+ ){
+ int i;
+ for(i=0; i<nLeft; i++){
+ int idxNew;
+ Expr *pNew;
Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, nLeft);
Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, nLeft);
-
- pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
- transferJoinMarkings(pNew, pExpr);
- idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
- exprAnalyze(pSrc, pWC, idxNew);
- }
- pTerm = &pWC->a[idxTerm];
+
+ pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
+ transferJoinMarkings(pNew, pExpr);
+ idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
+ exprAnalyze(pSrc, pWC, idxNew);
+ }
+ pTerm = &pWC->a[idxTerm];
pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
- pTerm->eOperator = 0;
- }
-
- /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
- ** a virtual term for each vector component. The expression object
+ pTerm->eOperator = 0;
+ }
+
+ /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
+ ** a virtual term for each vector component. The expression object
** used by each such virtual term is pExpr (the full vector IN(...)
** expression). The WhereTerm.u.x.iField variable identifies the index within
- ** the vector on the LHS that the virtual term represents.
- **
+ ** the vector on the LHS that the virtual term represents.
+ **
** This only works if the RHS is a simple SELECT (not a compound) that does
** not use window functions.
- */
+ */
else if( pExpr->op==TK_IN
&& pTerm->u.x.iField==0
- && pExpr->pLeft->op==TK_VECTOR
+ && pExpr->pLeft->op==TK_VECTOR
&& ALWAYS( ExprUseXSelect(pExpr) )
- && pExpr->x.pSelect->pPrior==0
+ && pExpr->x.pSelect->pPrior==0
#ifndef SQLITE_OMIT_WINDOWFUNC
&& pExpr->x.pSelect->pWin==0
#endif
&& pWC->op==TK_AND
- ){
- int i;
- for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
- int idxNew;
- idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
+ ){
+ int i;
+ for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
+ int idxNew;
+ idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
pWC->a[idxNew].u.x.iField = i+1;
- exprAnalyze(pSrc, pWC, idxNew);
- markTermAsChild(pWC, idxNew, idxTerm);
- }
- }
-
+ exprAnalyze(pSrc, pWC, idxNew);
+ markTermAsChild(pWC, idxNew, idxTerm);
+ }
+ }
+
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Add a WO_AUX auxiliary term to the constraint set if the
** current expression is of the form "column OP expr" where OP
@@ -150442,8 +150442,8 @@ static void exprAnalyze(
/* Prevent ON clause terms of a LEFT JOIN from being used to drive
** an index for tables to the left of the join.
*/
- testcase( pTerm!=&pWC->a[idxTerm] );
- pTerm = &pWC->a[idxTerm];
+ testcase( pTerm!=&pWC->a[idxTerm] );
+ pTerm = &pWC->a[idxTerm];
pTerm->prereqRight |= extraRight;
}
@@ -150499,8 +150499,8 @@ SQLITE_PRIVATE void sqlite3WhereClauseInit(
/*
** Deallocate a WhereClause structure. The WhereClause structure
-** itself is not freed. This routine is the inverse of
-** sqlite3WhereClauseInit().
+** itself is not freed. This routine is the inverse of
+** sqlite3WhereClauseInit().
*/
SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){
int i;
@@ -150528,22 +150528,22 @@ SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){
** tree.
*/
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
- Bitmask mask;
+ Bitmask mask;
if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){
- return sqlite3WhereGetMask(pMaskSet, p->iTable);
+ return sqlite3WhereGetMask(pMaskSet, p->iTable);
}else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
assert( p->op!=TK_IF_NULL_ROW );
return 0;
}
- mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
+ mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft);
- if( p->pRight ){
+ if( p->pRight ){
mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight);
- assert( p->x.pList==0 );
+ assert( p->x.pList==0 );
}else if( ExprUseXSelect(p) ){
- if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
+ if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
- }else if( p->x.pList ){
+ }else if( p->x.pList ){
mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
}
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -150589,40 +150589,40 @@ SQLITE_PRIVATE void sqlite3WhereExprAnalyze(
}
}
-/*
-** For table-valued-functions, transform the function arguments into
+/*
+** For table-valued-functions, transform the function arguments into
** new WHERE clause terms.
-**
-** Each function argument translates into an equality constraint against
-** a HIDDEN column in the table.
-*/
-SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
- Parse *pParse, /* Parsing context */
+**
+** Each function argument translates into an equality constraint against
+** a HIDDEN column in the table.
+*/
+SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
+ Parse *pParse, /* Parsing context */
SrcItem *pItem, /* The FROM clause term to process */
- WhereClause *pWC /* Xfer function arguments to here */
-){
- Table *pTab;
- int j, k;
- ExprList *pArgs;
- Expr *pColRef;
- Expr *pTerm;
- if( pItem->fg.isTabFunc==0 ) return;
- pTab = pItem->pTab;
- assert( pTab!=0 );
- pArgs = pItem->u1.pFuncArg;
- if( pArgs==0 ) return;
- for(j=k=0; j<pArgs->nExpr; j++){
+ WhereClause *pWC /* Xfer function arguments to here */
+){
+ Table *pTab;
+ int j, k;
+ ExprList *pArgs;
+ Expr *pColRef;
+ Expr *pTerm;
+ if( pItem->fg.isTabFunc==0 ) return;
+ pTab = pItem->pTab;
+ assert( pTab!=0 );
+ pArgs = pItem->u1.pFuncArg;
+ if( pArgs==0 ) return;
+ for(j=k=0; j<pArgs->nExpr; j++){
Expr *pRhs;
- while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
- if( k>=pTab->nCol ){
- sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
- pTab->zName, j);
- return;
- }
- pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
- if( pColRef==0 ) return;
- pColRef->iTable = pItem->iCursor;
- pColRef->iColumn = k++;
+ while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
+ if( k>=pTab->nCol ){
+ sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
+ pTab->zName, j);
+ return;
+ }
+ pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
+ if( pColRef==0 ) return;
+ pColRef->iTable = pItem->iCursor;
+ pColRef->iColumn = k++;
assert( ExprUseYTab(pColRef) );
pColRef->y.pTab = pTab;
pRhs = sqlite3PExpr(pParse, TK_UPLUS,
@@ -150631,10 +150631,10 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
if( pItem->fg.jointype & JT_LEFT ){
sqlite3SetJoinExpr(pTerm, pItem->iCursor);
}
- whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
- }
-}
-
+ whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
+ }
+}
+
/************** End of whereexpr.c *******************************************/
/************** Begin file where.c *******************************************/
/*
@@ -150658,29 +150658,29 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
/* #include "sqliteInt.h" */
/* #include "whereInt.h" */
-/*
-** Extra information appended to the end of sqlite3_index_info but not
-** visible to the xBestIndex function, at least not directly. The
-** sqlite3_vtab_collation() interface knows how to reach it, however.
-**
-** This object is not an API and can be changed from one release to the
-** next. As long as allocateIndexInfo() and sqlite3_vtab_collation()
-** agree on the structure, all will be well.
-*/
-typedef struct HiddenIndexInfo HiddenIndexInfo;
-struct HiddenIndexInfo {
- WhereClause *pWC; /* The Where clause being analyzed */
- Parse *pParse; /* The parsing context */
-};
-
+/*
+** Extra information appended to the end of sqlite3_index_info but not
+** visible to the xBestIndex function, at least not directly. The
+** sqlite3_vtab_collation() interface knows how to reach it, however.
+**
+** This object is not an API and can be changed from one release to the
+** next. As long as allocateIndexInfo() and sqlite3_vtab_collation()
+** agree on the structure, all will be well.
+*/
+typedef struct HiddenIndexInfo HiddenIndexInfo;
+struct HiddenIndexInfo {
+ WhereClause *pWC; /* The Where clause being analyzed */
+ Parse *pParse; /* The parsing context */
+};
+
/* Forward declaration of methods */
static int whereLoopResize(sqlite3*, WhereLoop*, int);
/*
** Return the estimated number of output rows from a WHERE clause
*/
-SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
- return pWInfo->nRowOut;
+SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
+ return pWInfo->nRowOut;
}
/*
@@ -150710,7 +150710,7 @@ SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
** subsequent rows for the current iteration of the inner loop (because they
** will not fit in the sorter either) and continue with the second inner
** loop - the loop immediately outside the inner-most.
-**
+**
** When a row does not fit in the sorter (because the sorter already
** holds LIMIT+OFFSET rows that are smaller), then a jump is made to the
** label returned by this function.
@@ -150725,7 +150725,7 @@ SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
** Returning the continuation the second inner loop is an optimization
** that might make the code run a little faster, but should not change
** the final answer.
-*/
+*/
SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){
WhereLevel *pInner;
if( !pWInfo->bOrderedInnerLoop ){
@@ -150736,9 +150736,9 @@ SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){
pInner = &pWInfo->a[pWInfo->nLevel-1];
assert( pInner->addrNxt!=0 );
return pInner->addrNxt;
-}
-
-/*
+}
+
+/*
** While generating code for the min/max optimization, after handling
** the aggregate-step call to min() or max(), check to see if any
** additional looping is required. If the output order is such that
@@ -150782,10 +150782,10 @@ SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){
}
/*
-** Return ONEPASS_OFF (0) if an UPDATE or DELETE statement is unable to
+** Return ONEPASS_OFF (0) if an UPDATE or DELETE statement is unable to
** operate directly on the rowids returned by a WHERE clause. Return
-** ONEPASS_SINGLE (1) if the statement can operation directly because only
-** a single row is to be changed. Return ONEPASS_MULTI (2) if the one-pass
+** ONEPASS_SINGLE (1) if the statement can operation directly because only
+** a single row is to be changed. Return ONEPASS_MULTI (2) if the one-pass
** optimization can be used on multiple
**
** If the ONEPASS optimization is used (if this routine returns true)
@@ -150800,14 +150800,14 @@ SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){
*/
SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){
memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2);
-#ifdef WHERETRACE_ENABLED
- if( sqlite3WhereTrace && pWInfo->eOnePass!=ONEPASS_OFF ){
- sqlite3DebugPrintf("%s cursors: %d %d\n",
- pWInfo->eOnePass==ONEPASS_SINGLE ? "ONEPASS_SINGLE" : "ONEPASS_MULTI",
- aiCur[0], aiCur[1]);
- }
-#endif
- return pWInfo->eOnePass;
+#ifdef WHERETRACE_ENABLED
+ if( sqlite3WhereTrace && pWInfo->eOnePass!=ONEPASS_OFF ){
+ sqlite3DebugPrintf("%s cursors: %d %d\n",
+ pWInfo->eOnePass==ONEPASS_SINGLE ? "ONEPASS_SINGLE" : "ONEPASS_MULTI",
+ aiCur[0], aiCur[1]);
+ }
+#endif
+ return pWInfo->eOnePass;
}
/*
@@ -150913,44 +150913,44 @@ static Expr *whereRightSubexprIsColumn(Expr *p){
*/
static WhereTerm *whereScanNext(WhereScan *pScan){
int iCur; /* The cursor on the LHS of the term */
- i16 iColumn; /* The column on the LHS of the term. -1 for IPK */
+ i16 iColumn; /* The column on the LHS of the term. -1 for IPK */
Expr *pX; /* An expression being tested */
WhereClause *pWC; /* Shorthand for pScan->pWC */
WhereTerm *pTerm; /* The term being tested */
int k = pScan->k; /* Where to start scanning */
- assert( pScan->iEquiv<=pScan->nEquiv );
- pWC = pScan->pWC;
- while(1){
- iColumn = pScan->aiColumn[pScan->iEquiv-1];
- iCur = pScan->aiCur[pScan->iEquiv-1];
- assert( pWC!=0 );
+ assert( pScan->iEquiv<=pScan->nEquiv );
+ pWC = pScan->pWC;
+ while(1){
+ iColumn = pScan->aiColumn[pScan->iEquiv-1];
+ iCur = pScan->aiCur[pScan->iEquiv-1];
+ assert( pWC!=0 );
assert( iCur>=0 );
- do{
+ do{
for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 || pTerm->leftCursor<0 );
if( pTerm->leftCursor==iCur
&& pTerm->u.x.leftColumn==iColumn
- && (iColumn!=XN_EXPR
- || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
- pScan->pIdxExpr,iCur)==0)
- && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+ && (iColumn!=XN_EXPR
+ || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
+ pScan->pIdxExpr,iCur)==0)
+ && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
){
if( (pTerm->eOperator & WO_EQUIV)!=0
- && pScan->nEquiv<ArraySize(pScan->aiCur)
+ && pScan->nEquiv<ArraySize(pScan->aiCur)
&& (pX = whereRightSubexprIsColumn(pTerm->pExpr))!=0
){
int j;
- for(j=0; j<pScan->nEquiv; j++){
- if( pScan->aiCur[j]==pX->iTable
- && pScan->aiColumn[j]==pX->iColumn ){
+ for(j=0; j<pScan->nEquiv; j++){
+ if( pScan->aiCur[j]==pX->iTable
+ && pScan->aiColumn[j]==pX->iColumn ){
break;
}
}
if( j==pScan->nEquiv ){
- pScan->aiCur[j] = pX->iTable;
- pScan->aiColumn[j] = pX->iColumn;
- pScan->nEquiv++;
+ pScan->aiCur[j] = pX->iTable;
+ pScan->aiColumn[j] = pX->iColumn;
+ pScan->nEquiv++;
}
}
if( (pTerm->eOperator & pScan->opMask)!=0 ){
@@ -150972,13 +150972,13 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
&& (pX = pTerm->pExpr->pRight, ALWAYS(pX!=0))
&& pX->op==TK_COLUMN
- && pX->iTable==pScan->aiCur[0]
- && pX->iColumn==pScan->aiColumn[0]
+ && pX->iTable==pScan->aiCur[0]
+ && pX->iColumn==pScan->aiColumn[0]
){
testcase( pTerm->eOperator & WO_IS );
continue;
}
- pScan->pWC = pWC;
+ pScan->pWC = pWC;
pScan->k = k+1;
#ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace & 0x20000 ){
@@ -150996,13 +150996,13 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
}
}
}
- pWC = pWC->pOuter;
+ pWC = pWC->pOuter;
k = 0;
- }while( pWC!=0 );
- if( pScan->iEquiv>=pScan->nEquiv ) break;
- pWC = pScan->pOrigWC;
+ }while( pWC!=0 );
+ if( pScan->iEquiv>=pScan->nEquiv ) break;
+ pWC = pScan->pOrigWC;
k = 0;
- pScan->iEquiv++;
+ pScan->iEquiv++;
}
return 0;
}
@@ -151024,11 +151024,11 @@ static SQLITE_NOINLINE WhereTerm *whereScanInitIndexExpr(WhereScan *pScan){
**
** The scanner will be searching the WHERE clause pWC. It will look
** for terms of the form "X <op> <expr>" where X is column iColumn of table
-** iCur. Or if pIdx!=0 then X is column iColumn of index pIdx. pIdx
-** must be one of the indexes of table iCur.
+** iCur. Or if pIdx!=0 then X is column iColumn of index pIdx. pIdx
+** must be one of the indexes of table iCur.
+**
+** The <op> must be one of the operators described by opMask.
**
-** The <op> must be one of the operators described by opMask.
-**
** If the search is for X and the WHERE clause contains terms of the
** form X=Y then this routine might also return terms of the form
** "Y <op> <expr>". The number of levels of transitivity is limited,
@@ -151047,52 +151047,52 @@ static WhereTerm *whereScanInit(
){
pScan->pOrigWC = pWC;
pScan->pWC = pWC;
- pScan->pIdxExpr = 0;
- pScan->idxaff = 0;
- pScan->zCollName = 0;
+ pScan->pIdxExpr = 0;
+ pScan->idxaff = 0;
+ pScan->zCollName = 0;
pScan->opMask = opMask;
pScan->k = 0;
pScan->aiCur[0] = iCur;
pScan->nEquiv = 1;
pScan->iEquiv = 1;
- if( pIdx ){
- int j = iColumn;
- iColumn = pIdx->aiColumn[j];
- if( iColumn==XN_EXPR ){
- pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
- pScan->zCollName = pIdx->azColl[j];
+ if( pIdx ){
+ int j = iColumn;
+ iColumn = pIdx->aiColumn[j];
+ if( iColumn==XN_EXPR ){
+ pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
+ pScan->zCollName = pIdx->azColl[j];
pScan->aiColumn[0] = XN_EXPR;
return whereScanInitIndexExpr(pScan);
- }else if( iColumn==pIdx->pTable->iPKey ){
- iColumn = XN_ROWID;
- }else if( iColumn>=0 ){
- pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
- pScan->zCollName = pIdx->azColl[j];
+ }else if( iColumn==pIdx->pTable->iPKey ){
+ iColumn = XN_ROWID;
+ }else if( iColumn>=0 ){
+ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
+ pScan->zCollName = pIdx->azColl[j];
}
- }else if( iColumn==XN_EXPR ){
- return 0;
+ }else if( iColumn==XN_EXPR ){
+ return 0;
}
- pScan->aiColumn[0] = iColumn;
+ pScan->aiColumn[0] = iColumn;
return whereScanNext(pScan);
}
/*
** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
-** where X is a reference to the iColumn of table iCur or of index pIdx
-** if pIdx!=0 and <op> is one of the WO_xx operator codes specified by
-** the op parameter. Return a pointer to the term. Return 0 if not found.
+** where X is a reference to the iColumn of table iCur or of index pIdx
+** if pIdx!=0 and <op> is one of the WO_xx operator codes specified by
+** the op parameter. Return a pointer to the term. Return 0 if not found.
**
** If pIdx!=0 then it must be one of the indexes of table iCur.
-** Search for terms matching the iColumn-th column of pIdx
-** rather than the iColumn-th column of table iCur.
-**
+** Search for terms matching the iColumn-th column of pIdx
+** rather than the iColumn-th column of table iCur.
+**
** The term returned might by Y=<expr> if there is another constraint in
** the WHERE clause that specifies that X=Y. Any such constraints will be
** identified by the WO_EQUIV bit in the pTerm->eOperator field. The
-** aiCur[]/iaColumn[] arrays hold X and all its equivalents. There are 11
-** slots in aiCur[]/aiColumn[] so that means we can look for X plus up to 10
-** other equivalent values. Hence a search for X will return <expr> if X=A1
-** and A1=A2 and A2=A3 and ... and A9=A10 and A10=<expr>.
+** aiCur[]/iaColumn[] arrays hold X and all its equivalents. There are 11
+** slots in aiCur[]/aiColumn[] so that means we can look for X plus up to 10
+** other equivalent values. Hence a search for X will return <expr> if X=A1
+** and A1=A2 and A2=A3 and ... and A9=A10 and A10=<expr>.
**
** If there are multiple terms in the WHERE clause of the form "X <op> <expr>"
** then try for the one with no dependencies on <expr> - in other words where
@@ -151152,8 +151152,8 @@ static int findIndexCol(
&& p->iColumn==pIdx->aiColumn[iCol]
&& p->iTable==iBase
){
- CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr);
- if( 0==sqlite3StrICmp(pColl->zName, zColl) ){
+ CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr);
+ if( 0==sqlite3StrICmp(pColl->zName, zColl) ){
return i;
}
}
@@ -151163,25 +151163,25 @@ static int findIndexCol(
}
/*
-** Return TRUE if the iCol-th column of index pIdx is NOT NULL
-*/
-static int indexColumnNotNull(Index *pIdx, int iCol){
- int j;
- assert( pIdx!=0 );
- assert( iCol>=0 && iCol<pIdx->nColumn );
- j = pIdx->aiColumn[iCol];
- if( j>=0 ){
- return pIdx->pTable->aCol[j].notNull;
- }else if( j==(-1) ){
- return 1;
- }else{
- assert( j==(-2) );
- return 0; /* Assume an indexed expression can always yield a NULL */
-
- }
-}
-
-/*
+** Return TRUE if the iCol-th column of index pIdx is NOT NULL
+*/
+static int indexColumnNotNull(Index *pIdx, int iCol){
+ int j;
+ assert( pIdx!=0 );
+ assert( iCol>=0 && iCol<pIdx->nColumn );
+ j = pIdx->aiColumn[iCol];
+ if( j>=0 ){
+ return pIdx->pTable->aCol[j].notNull;
+ }else if( j==(-1) ){
+ return 1;
+ }else{
+ assert( j==(-2) );
+ return 0; /* Assume an indexed expression can always yield a NULL */
+
+ }
+}
+
+/*
** Return true if the DISTINCT expression-list passed as the third argument
** is redundant.
**
@@ -151234,9 +151234,9 @@ static int isDistinctRedundant(
if( !IsUniqueIndex(pIdx) ) continue;
if( pIdx->pPartIdxWhere ) continue;
for(i=0; i<pIdx->nKeyCol; i++){
- if( 0==sqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask)0, WO_EQ, pIdx) ){
- if( findIndexCol(pParse, pDistinct, iBase, pIdx, i)<0 ) break;
- if( indexColumnNotNull(pIdx, i)==0 ) break;
+ if( 0==sqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask)0, WO_EQ, pIdx) ){
+ if( findIndexCol(pParse, pDistinct, iBase, pIdx, i)<0 ) break;
+ if( indexColumnNotNull(pIdx, i)==0 ) break;
}
}
if( i==pIdx->nKeyCol ){
@@ -151261,24 +151261,24 @@ static LogEst estLog(LogEst N){
**
** This routine runs over generated VDBE code and translates OP_Column
** opcodes into OP_Copy when the table is being accessed via co-routine
-** instead of via table lookup.
-**
+** instead of via table lookup.
+**
** If the iAutoidxCur is not zero, then any OP_Rowid instructions on
** cursor iTabCur are transformed into OP_Sequence opcode for the
** iAutoidxCur cursor, in order to generate unique rowids for the
** automatic index being generated.
*/
static void translateColumnToCopy(
- Parse *pParse, /* Parsing context */
+ Parse *pParse, /* Parsing context */
int iStart, /* Translate from this opcode to the end */
int iTabCur, /* OP_Column/OP_Rowid references to this table */
- int iRegister, /* The first column is in this register */
+ int iRegister, /* The first column is in this register */
int iAutoidxCur /* If non-zero, cursor of autoindex being generated */
){
- Vdbe *v = pParse->pVdbe;
+ Vdbe *v = pParse->pVdbe;
VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
int iEnd = sqlite3VdbeCurrentAddr(v);
- if( pParse->db->mallocFailed ) return;
+ if( pParse->db->mallocFailed ) return;
for(; iStart<iEnd; iStart++, pOp++){
if( pOp->p1!=iTabCur ) continue;
if( pOp->opcode==OP_Column ){
@@ -151291,9 +151291,9 @@ static void translateColumnToCopy(
pOp->p1 = iAutoidxCur;
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
if( iAutoidxCur==0 ){
- pOp->opcode = OP_Null;
- pOp->p3 = 0;
- }
+ pOp->opcode = OP_Null;
+ pOp->p3 = 0;
+ }
#endif
}
}
@@ -151359,14 +151359,14 @@ static int termCanDriveIndex(
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
if( (pSrc->fg.jointype & JT_LEFT)
- && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
- && (pTerm->eOperator & WO_IS)
- ){
- /* Cannot use an IS term from the WHERE clause as an index driver for
- ** the RHS of a LEFT JOIN. Such a term can only be used if it is from
- ** the ON clause. */
- return 0;
- }
+ && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+ && (pTerm->eOperator & WO_IS)
+ ){
+ /* Cannot use an IS term from the WHERE clause as an index driver for
+ ** the RHS of a LEFT JOIN. Such a term can only be used if it is from
+ ** the ON clause. */
+ return 0;
+ }
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
if( pTerm->u.x.leftColumn<0 ) return 0;
@@ -151412,14 +151412,14 @@ static void constructAutomaticIndex(
Expr *pPartial = 0; /* Partial Index Expression */
int iContinue = 0; /* Jump here to skip excluded rows */
SrcItem *pTabItem; /* FROM clause term being indexed */
- int addrCounter = 0; /* Address where integer counter is initialized */
- int regBase; /* Array of registers where record is assembled */
+ int addrCounter = 0; /* Address where integer counter is initialized */
+ int regBase; /* Array of registers where record is assembled */
/* Generate code to skip over the creation and initialization of the
** transient index on 2nd and subsequent iterations of the loop. */
v = pParse->pVdbe;
assert( v!=0 );
- addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
/* Count the number of columns that will be added to the index
** and used to match WHERE clause constraints */
@@ -151510,7 +151510,7 @@ static void constructAutomaticIndex(
pIdx->aiColumn[n] = pTerm->u.x.leftColumn;
pColl = sqlite3ExprCompareCollSeq(pParse, pX);
assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */
- pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY;
+ pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY;
n++;
}
}
@@ -151522,20 +151522,20 @@ static void constructAutomaticIndex(
for(i=0; i<mxBitCol; i++){
if( extraCols & MASKBIT(i) ){
pIdx->aiColumn[n] = i;
- pIdx->azColl[n] = sqlite3StrBINARY;
+ pIdx->azColl[n] = sqlite3StrBINARY;
n++;
}
}
if( pSrc->colUsed & MASKBIT(BMS-1) ){
for(i=BMS-1; i<pTable->nCol; i++){
pIdx->aiColumn[n] = i;
- pIdx->azColl[n] = sqlite3StrBINARY;
+ pIdx->azColl[n] = sqlite3StrBINARY;
n++;
}
}
assert( n==nKeyCol );
- pIdx->aiColumn[n] = XN_ROWID;
- pIdx->azColl[n] = sqlite3StrBINARY;
+ pIdx->aiColumn[n] = XN_ROWID;
+ pIdx->azColl[n] = sqlite3StrBINARY;
/* Create the automatic index */
assert( pLevel->iIdxCur>=0 );
@@ -151546,9 +151546,9 @@ static void constructAutomaticIndex(
/* Fill the automatic index with content */
pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
- if( pTabItem->fg.viaCoroutine ){
+ if( pTabItem->fg.viaCoroutine ){
int regYield = pTabItem->regReturn;
- addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
+ addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
VdbeCoverage(v);
@@ -151562,20 +151562,20 @@ static void constructAutomaticIndex(
pLoop->wsFlags |= WHERE_PARTIALIDX;
}
regRecord = sqlite3GetTempReg(pParse);
- regBase = sqlite3GenerateIndexKey(
- pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0
- );
+ regBase = sqlite3GenerateIndexKey(
+ pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0
+ );
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
- if( pTabItem->fg.viaCoroutine ){
- sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
- testcase( pParse->db->mallocFailed );
+ if( pTabItem->fg.viaCoroutine ){
+ sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
+ testcase( pParse->db->mallocFailed );
assert( pLevel->iIdxCur>0 );
- translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
+ translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
pTabItem->regResult, pLevel->iIdxCur);
- sqlite3VdbeGoto(v, addrTop);
- pTabItem->fg.viaCoroutine = 0;
+ sqlite3VdbeGoto(v, addrTop);
+ pTabItem->fg.viaCoroutine = 0;
}else{
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
@@ -151598,23 +151598,23 @@ end_auto_index_create:
** by passing the pointer returned by this function to sqlite3_free().
*/
static sqlite3_index_info *allocateIndexInfo(
- Parse *pParse, /* The parsing context */
- WhereClause *pWC, /* The WHERE clause being analyzed */
+ Parse *pParse, /* The parsing context */
+ WhereClause *pWC, /* The WHERE clause being analyzed */
Bitmask mUnusable, /* Ignore terms with these prereqs */
SrcItem *pSrc, /* The FROM clause term that is the vtab */
- ExprList *pOrderBy, /* The ORDER BY clause */
- u16 *pmNoOmit /* Mask of terms not to omit */
+ ExprList *pOrderBy, /* The ORDER BY clause */
+ u16 *pmNoOmit /* Mask of terms not to omit */
){
int i, j;
int nTerm;
struct sqlite3_index_constraint *pIdxCons;
struct sqlite3_index_orderby *pIdxOrderBy;
struct sqlite3_index_constraint_usage *pUsage;
- struct HiddenIndexInfo *pHidden;
+ struct HiddenIndexInfo *pHidden;
WhereTerm *pTerm;
int nOrderBy;
sqlite3_index_info *pIdxInfo;
- u16 mNoOmit = 0;
+ u16 mNoOmit = 0;
/* Count the number of possible WHERE clause constraints referring
** to this virtual table */
@@ -151626,7 +151626,7 @@ static sqlite3_index_info *allocateIndexInfo(
testcase( pTerm->eOperator & WO_ISNULL );
testcase( pTerm->eOperator & WO_IS );
testcase( pTerm->eOperator & WO_ALL );
- if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
+ if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
assert( pTerm->u.x.leftColumn>=(-1) );
@@ -151654,23 +151654,23 @@ static sqlite3_index_info *allocateIndexInfo(
*/
pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
+ (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
- + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) );
+ + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) );
if( pIdxInfo==0 ){
sqlite3ErrorMsg(pParse, "out of memory");
return 0;
}
- pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1];
- pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1];
+ pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1];
+ pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1];
pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];
pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
pIdxInfo->nOrderBy = nOrderBy;
pIdxInfo->aConstraint = pIdxCons;
pIdxInfo->aOrderBy = pIdxOrderBy;
pIdxInfo->aConstraintUsage = pUsage;
- pHidden->pWC = pWC;
- pHidden->pParse = pParse;
+ pHidden->pWC = pWC;
+ pHidden->pParse = pParse;
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
- u16 op;
+ u16 op;
if( pTerm->leftCursor != pSrc->iCursor ) continue;
if( pTerm->prereqRight & mUnusable ) continue;
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
@@ -151678,7 +151678,7 @@ static sqlite3_index_info *allocateIndexInfo(
testcase( pTerm->eOperator & WO_IS );
testcase( pTerm->eOperator & WO_ISNULL );
testcase( pTerm->eOperator & WO_ALL );
- if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
+ if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
/* tag-20191211-002: WHERE-clause constraints are not useful to the
@@ -151693,38 +151693,38 @@ static sqlite3_index_info *allocateIndexInfo(
assert( pTerm->u.x.leftColumn>=(-1) );
pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
pIdxCons[j].iTermOffset = i;
- op = pTerm->eOperator & WO_ALL;
+ op = pTerm->eOperator & WO_ALL;
if( op==WO_IN ) op = WO_EQ;
- if( op==WO_AUX ){
- pIdxCons[j].op = pTerm->eMatchOp;
- }else if( op & (WO_ISNULL|WO_IS) ){
- if( op==WO_ISNULL ){
- pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
- }else{
- pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS;
- }
- }else{
- pIdxCons[j].op = (u8)op;
- /* The direct assignment in the previous line is possible only because
- ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
- ** following asserts verify this fact. */
- assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
- assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
- assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
- assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
- assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
- assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) );
-
- if( op & (WO_LT|WO_LE|WO_GT|WO_GE)
+ if( op==WO_AUX ){
+ pIdxCons[j].op = pTerm->eMatchOp;
+ }else if( op & (WO_ISNULL|WO_IS) ){
+ if( op==WO_ISNULL ){
+ pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
+ }else{
+ pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS;
+ }
+ }else{
+ pIdxCons[j].op = (u8)op;
+ /* The direct assignment in the previous line is possible only because
+ ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
+ ** following asserts verify this fact. */
+ assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
+ assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
+ assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
+ assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
+ assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
+ assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) );
+
+ if( op & (WO_LT|WO_LE|WO_GT|WO_GE)
&& sqlite3ExprIsVector(pTerm->pExpr->pRight)
- ){
+ ){
testcase( j!=i );
if( j<16 ) mNoOmit |= (1 << j);
- if( op==WO_LT ) pIdxCons[j].op = WO_LE;
- if( op==WO_GT ) pIdxCons[j].op = WO_GE;
- }
- }
-
+ if( op==WO_LT ) pIdxCons[j].op = WO_LE;
+ if( op==WO_GT ) pIdxCons[j].op = WO_GE;
+ }
+ }
+
j++;
}
pIdxInfo->nConstraint = j;
@@ -151734,7 +151734,7 @@ static sqlite3_index_info *allocateIndexInfo(
pIdxOrderBy[i].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC;
}
- *pmNoOmit = mNoOmit;
+ *pmNoOmit = mNoOmit;
return pIdxInfo;
}
@@ -151764,7 +151764,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
if( rc==SQLITE_NOMEM ){
- sqlite3OomFault(pParse->db);
+ sqlite3OomFault(pParse->db);
}else if( !pVtab->zErrMsg ){
sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
}else{
@@ -151963,7 +151963,7 @@ static int whereKeyStats(
iGap = iGap/3;
}
aStat[0] = iLower + iGap;
- aStat[1] = pIdx->aAvgEq[nField-1];
+ aStat[1] = pIdx->aAvgEq[nField-1];
}
/* Restore the pRec->nField value before returning. */
@@ -151995,22 +151995,22 @@ static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){
return nRet;
}
-
+
#ifdef SQLITE_ENABLE_STAT4
-/*
-** Return the affinity for a single column of an index.
-*/
-SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
- assert( iCol>=0 && iCol<pIdx->nColumn );
- if( !pIdx->zColAff ){
- if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB;
- }
+/*
+** Return the affinity for a single column of an index.
+*/
+SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
+ assert( iCol>=0 && iCol<pIdx->nColumn );
+ if( !pIdx->zColAff ){
+ if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB;
+ }
assert( pIdx->zColAff[iCol]!=0 );
- return pIdx->zColAff[iCol];
-}
-#endif
-
-
+ return pIdx->zColAff[iCol];
+}
+#endif
+
+
#ifdef SQLITE_ENABLE_STAT4
/*
** This function is called to estimate the number of rows visited by a
@@ -152060,7 +152060,7 @@ static int whereRangeSkipScanEst(
int nLower = -1;
int nUpper = p->nSample+1;
int rc = SQLITE_OK;
- u8 aff = sqlite3IndexColumnAffinity(db, p, nEq);
+ u8 aff = sqlite3IndexColumnAffinity(db, p, nEq);
CollSeq *pColl;
sqlite3_value *p1 = 0; /* Value extracted from pLower */
@@ -152180,8 +152180,8 @@ static int whereRangeScanEst(
if( nEq==pBuilder->nRecValid ){
UnpackedRecord *pRec = pBuilder->pRec;
tRowcnt a[2];
- int nBtm = pLoop->u.btree.nBtm;
- int nTop = pLoop->u.btree.nTop;
+ int nBtm = pLoop->u.btree.nBtm;
+ int nTop = pLoop->u.btree.nTop;
/* Variable iLower will be set to the estimate of the number of rows in
** the index that are less than the lower bound of the range query. The
@@ -152229,20 +152229,20 @@ static int whereRangeScanEst(
if( p->aSortOrder[nEq] ){
/* The roles of pLower and pUpper are swapped for a DESC index */
SWAP(WhereTerm*, pLower, pUpper);
- SWAP(int, nBtm, nTop);
+ SWAP(int, nBtm, nTop);
}
/* If possible, improve on the iLower estimate using ($P:$L). */
if( pLower ){
- int n; /* Values extracted from pExpr */
+ int n; /* Values extracted from pExpr */
Expr *pExpr = pLower->pExpr->pRight;
- rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nBtm, nEq, &n);
- if( rc==SQLITE_OK && n ){
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nBtm, nEq, &n);
+ if( rc==SQLITE_OK && n ){
tRowcnt iNew;
- u16 mask = WO_GT|WO_LE;
- if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT);
+ u16 mask = WO_GT|WO_LE;
+ if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT);
iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a);
- iNew = a[0] + ((pLower->eOperator & mask) ? a[1] : 0);
+ iNew = a[0] + ((pLower->eOperator & mask) ? a[1] : 0);
if( iNew>iLower ) iLower = iNew;
nOut--;
pLower = 0;
@@ -152251,15 +152251,15 @@ static int whereRangeScanEst(
/* If possible, improve on the iUpper estimate using ($P:$U). */
if( pUpper ){
- int n; /* Values extracted from pExpr */
+ int n; /* Values extracted from pExpr */
Expr *pExpr = pUpper->pExpr->pRight;
- rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nTop, nEq, &n);
- if( rc==SQLITE_OK && n ){
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nTop, nEq, &n);
+ if( rc==SQLITE_OK && n ){
tRowcnt iNew;
- u16 mask = WO_GT|WO_LE;
- if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT);
+ u16 mask = WO_GT|WO_LE;
+ if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT);
iUprIdx = whereKeyStats(pParse, p, pRec, 1, a);
- iNew = a[0] + ((pUpper->eOperator & mask) ? a[1] : 0);
+ iNew = a[0] + ((pUpper->eOperator & mask) ? a[1] : 0);
if( iNew<iUpper ) iUpper = iNew;
nOut--;
pUpper = 0;
@@ -152372,15 +152372,15 @@ static int whereEqualScanEst(
return SQLITE_OK;
}
- rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, 1, nEq-1, &bOk);
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, 1, nEq-1, &bOk);
pBuilder->pRec = pRec;
if( rc!=SQLITE_OK ) return rc;
if( bOk==0 ) return SQLITE_NOTFOUND;
pBuilder->nRecValid = nEq;
whereKeyStats(pParse, p, pRec, 0, a);
- WHERETRACE(0x10,("equality scan regions %s(%d): %d\n",
- p->zName, nEq-1, (int)a[1]));
+ WHERETRACE(0x10,("equality scan regions %s(%d): %d\n",
+ p->zName, nEq-1, (int)a[1]));
*pnRow = a[1];
return rc;
@@ -152446,22 +152446,22 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm);
}else{
char zType[8];
- char zLeft[50];
+ char zLeft[50];
memcpy(zType, "....", 5);
if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C';
- if( pTerm->eOperator & WO_SINGLE ){
+ if( pTerm->eOperator & WO_SINGLE ){
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
- sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
+ sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
pTerm->leftCursor, pTerm->u.x.leftColumn);
- }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
+ }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx",
- pTerm->u.pOrInfo->indexable);
- }else{
- sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor);
- }
+ pTerm->u.pOrInfo->indexable);
+ }else{
+ sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor);
+ }
sqlite3DebugPrintf(
"TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x",
iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags);
@@ -152470,7 +152470,7 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
if( sqlite3WhereTrace & 0x10000 ){
sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx",
pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight);
- }
+ }
if( (pTerm->eOperator & (WO_OR|WO_AND))==0 && pTerm->u.x.iField ){
sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField);
}
@@ -152485,28 +152485,28 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
#ifdef WHERETRACE_ENABLED
/*
-** Show the complete content of a WhereClause
-*/
-SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){
- int i;
- for(i=0; i<pWC->nTerm; i++){
+** Show the complete content of a WhereClause
+*/
+SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){
+ int i;
+ for(i=0; i<pWC->nTerm; i++){
sqlite3WhereTermPrint(&pWC->a[i], i);
- }
-}
-#endif
-
-#ifdef WHERETRACE_ENABLED
-/*
+ }
+}
+#endif
+
+#ifdef WHERETRACE_ENABLED
+/*
** Print a WhereLoop object for debugging purposes
*/
SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){
WhereInfo *pWInfo = pWC->pWInfo;
- int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
+ int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
Table *pTab = pItem->pTab;
- Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
+ Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
- p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
+ p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
sqlite3DebugPrintf(" %12s",
pItem->zAlias ? pItem->zAlias : pTab->zName);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
@@ -152569,7 +152569,7 @@ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
p->u.vtab.idxStr = 0;
}else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
- sqlite3DbFreeNN(db, p->u.btree.pIndex);
+ sqlite3DbFreeNN(db, p->u.btree.pIndex);
p->u.btree.pIndex = 0;
}
}
@@ -152579,7 +152579,7 @@ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
** Deallocate internal memory used by a WhereLoop object
*/
static void whereLoopClear(sqlite3 *db, WhereLoop *p){
- if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
+ if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
whereLoopClearUnion(db, p);
whereLoopInit(p);
}
@@ -152591,10 +152591,10 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){
WhereTerm **paNew;
if( p->nLSlot>=n ) return SQLITE_OK;
n = (n+7)&~7;
- paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n);
- if( paNew==0 ) return SQLITE_NOMEM_BKPT;
+ paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n);
+ if( paNew==0 ) return SQLITE_NOMEM_BKPT;
memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
- if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
+ if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm);
p->aLTerm = paNew;
p->nLSlot = n;
return SQLITE_OK;
@@ -152607,7 +152607,7 @@ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
whereLoopClearUnion(db, pTo);
if( whereLoopResize(db, pTo, pFrom->nLTerm) ){
memset(pTo, 0, WHERE_LOOP_XFER_SZ);
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ);
memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0]));
@@ -152624,30 +152624,30 @@ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
*/
static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
whereLoopClear(db, p);
- sqlite3DbFreeNN(db, p);
+ sqlite3DbFreeNN(db, p);
}
/*
** Free a WhereInfo structure
*/
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
- int i;
- assert( pWInfo!=0 );
- for(i=0; i<pWInfo->nLevel; i++){
- WhereLevel *pLevel = &pWInfo->a[i];
+ int i;
+ assert( pWInfo!=0 );
+ for(i=0; i<pWInfo->nLevel; i++){
+ WhereLevel *pLevel = &pWInfo->a[i];
if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE)!=0 ){
assert( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 );
- sqlite3DbFree(db, pLevel->u.in.aInLoop);
+ sqlite3DbFree(db, pLevel->u.in.aInLoop);
}
}
- sqlite3WhereClauseClear(&pWInfo->sWC);
- while( pWInfo->pLoops ){
- WhereLoop *p = pWInfo->pLoops;
- pWInfo->pLoops = p->pNextLoop;
- whereLoopDelete(db, p);
- }
+ sqlite3WhereClauseClear(&pWInfo->sWC);
+ while( pWInfo->pLoops ){
+ WhereLoop *p = pWInfo->pLoops;
+ pWInfo->pLoops = p->pNextLoop;
+ whereLoopDelete(db, p);
+ }
assert( pWInfo->pExprMods==0 );
- sqlite3DbFreeNN(db, pWInfo);
+ sqlite3DbFreeNN(db, pWInfo);
}
/* Undo all Expr node modifications
@@ -152666,19 +152666,19 @@ static void whereUndoExprMods(WhereInfo *pWInfo){
**
** (1) X has the same or lower cost, or returns the same or fewer rows,
** than Y.
-** (2) X uses fewer WHERE clause terms than Y
-** (3) Every WHERE clause term used by X is also used by Y
-** (4) X skips at least as many columns as Y
-** (5) If X is a covering index, than Y is too
+** (2) X uses fewer WHERE clause terms than Y
+** (3) Every WHERE clause term used by X is also used by Y
+** (4) X skips at least as many columns as Y
+** (5) If X is a covering index, than Y is too
**
-** Conditions (2) and (3) mean that X is a "proper subset" of Y.
+** Conditions (2) and (3) mean that X is a "proper subset" of Y.
** If X is a proper subset of Y then Y is a better choice and ought
** to have a lower cost. This routine returns TRUE when that cost
-** relationship is inverted and needs to be adjusted. Constraint (4)
+** relationship is inverted and needs to be adjusted. Constraint (4)
** was added because if X uses skip-scan less than Y it still might
-** deserve a lower cost even if it is a proper subset of Y. Constraint (5)
-** was added because a covering index probably deserves to have a lower cost
-** than a non-covering index even if it is a proper subset.
+** deserve a lower cost even if it is a proper subset of Y. Constraint (5)
+** was added because a covering index probably deserves to have a lower cost
+** than a non-covering index even if it is a proper subset.
*/
static int whereLoopCheaperProperSubset(
const WhereLoop *pX, /* First WhereLoop to compare */
@@ -152698,9 +152698,9 @@ static int whereLoopCheaperProperSubset(
if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */
}
if( (pX->wsFlags&WHERE_IDX_ONLY)!=0
- && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){
- return 0; /* Constraint (5) */
- }
+ && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){
+ return 0; /* Constraint (5) */
+ }
return 1; /* All conditions meet */
}
@@ -152747,17 +152747,17 @@ static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){
/*
** Search the list of WhereLoops in *ppPrev looking for one that can be
-** replaced by pTemplate.
+** replaced by pTemplate.
**
-** Return NULL if pTemplate does not belong on the WhereLoop list.
-** In other words if pTemplate ought to be dropped from further consideration.
+** Return NULL if pTemplate does not belong on the WhereLoop list.
+** In other words if pTemplate ought to be dropped from further consideration.
**
-** If pX is a WhereLoop that pTemplate can replace, then return the
+** If pX is a WhereLoop that pTemplate can replace, then return the
** link that points to pX.
**
-** If pTemplate cannot replace any existing element of the list but needs
-** to be added to the list as a new entry, then return a pointer to the
-** tail of the list.
+** If pTemplate cannot replace any existing element of the list but needs
+** to be added to the list as a new entry, then return a pointer to the
+** tail of the list.
*/
static WhereLoop **whereLoopFindLesser(
WhereLoop **ppPrev,
@@ -152851,7 +152851,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
WhereLoop **ppPrev, *p;
WhereInfo *pWInfo = pBuilder->pWInfo;
sqlite3 *db = pWInfo->pParse->db;
- int rc;
+ int rc;
/* Stop the search once we hit the query planner search limit */
if( pBuilder->iPlanLimit==0 ){
@@ -152867,19 +152867,19 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
** and prereqs.
*/
if( pBuilder->pOrSet!=0 ){
- if( pTemplate->nLTerm ){
+ if( pTemplate->nLTerm ){
#if WHERETRACE_ENABLED
- u16 n = pBuilder->pOrSet->n;
- int x =
+ u16 n = pBuilder->pOrSet->n;
+ int x =
#endif
- whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
+ whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
pTemplate->nOut);
#if WHERETRACE_ENABLED /* 0x8 */
- if( sqlite3WhereTrace & 0x8 ){
- sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n);
+ if( sqlite3WhereTrace & 0x8 ){
+ sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n);
sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC);
- }
-#endif
+ }
+#endif
}
return SQLITE_OK;
}
@@ -152911,17 +152911,17 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
if( p!=0 ){
sqlite3DebugPrintf("replace: ");
sqlite3WhereLoopPrint(p, pBuilder->pWC);
- sqlite3DebugPrintf(" with: ");
- }else{
- sqlite3DebugPrintf(" add: ");
+ sqlite3DebugPrintf(" with: ");
+ }else{
+ sqlite3DebugPrintf(" add: ");
}
sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC);
}
#endif
if( p==0 ){
/* Allocate a new WhereLoop to add to the end of the list */
- *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop));
- if( p==0 ) return SQLITE_NOMEM_BKPT;
+ *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop));
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
whereLoopInit(p);
p->pNextLoop = 0;
}else{
@@ -152945,14 +152945,14 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
whereLoopDelete(db, pToDel);
}
}
- rc = whereLoopXfer(db, p, pTemplate);
+ rc = whereLoopXfer(db, p, pTemplate);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
Index *pIndex = p->u.btree.pIndex;
if( pIndex && pIndex->idxType==SQLITE_IDXTYPE_IPK ){
p->u.btree.pIndex = 0;
}
}
- return rc;
+ return rc;
}
/*
@@ -153038,74 +153038,74 @@ static void whereLoopOutputAdjust(
}
/*
-** Term pTerm is a vector range comparison operation. The first comparison
-** in the vector can be optimized using column nEq of the index. This
-** function returns the total number of vector elements that can be used
-** as part of the range comparison.
-**
-** For example, if the query is:
-**
-** WHERE a = ? AND (b, c, d) > (?, ?, ?)
-**
-** and the index:
-**
-** CREATE INDEX ... ON (a, b, c, d, e)
-**
-** then this function would be invoked with nEq=1. The value returned in
-** this case is 3.
-*/
-static int whereRangeVectorLen(
- Parse *pParse, /* Parsing context */
- int iCur, /* Cursor open on pIdx */
- Index *pIdx, /* The index to be used for a inequality constraint */
- int nEq, /* Number of prior equality constraints on same index */
- WhereTerm *pTerm /* The vector inequality constraint */
-){
- int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft);
- int i;
-
- nCmp = MIN(nCmp, (pIdx->nColumn - nEq));
- for(i=1; i<nCmp; i++){
+** Term pTerm is a vector range comparison operation. The first comparison
+** in the vector can be optimized using column nEq of the index. This
+** function returns the total number of vector elements that can be used
+** as part of the range comparison.
+**
+** For example, if the query is:
+**
+** WHERE a = ? AND (b, c, d) > (?, ?, ?)
+**
+** and the index:
+**
+** CREATE INDEX ... ON (a, b, c, d, e)
+**
+** then this function would be invoked with nEq=1. The value returned in
+** this case is 3.
+*/
+static int whereRangeVectorLen(
+ Parse *pParse, /* Parsing context */
+ int iCur, /* Cursor open on pIdx */
+ Index *pIdx, /* The index to be used for a inequality constraint */
+ int nEq, /* Number of prior equality constraints on same index */
+ WhereTerm *pTerm /* The vector inequality constraint */
+){
+ int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft);
+ int i;
+
+ nCmp = MIN(nCmp, (pIdx->nColumn - nEq));
+ for(i=1; i<nCmp; i++){
/* Test if comparison i of pTerm is compatible with column (i+nEq)
- ** of the index. If not, exit the loop. */
- char aff; /* Comparison affinity */
- char idxaff = 0; /* Indexed columns affinity */
- CollSeq *pColl; /* Comparison collation sequence */
+ ** of the index. If not, exit the loop. */
+ char aff; /* Comparison affinity */
+ char idxaff = 0; /* Indexed columns affinity */
+ CollSeq *pColl; /* Comparison collation sequence */
Expr *pLhs, *pRhs;
assert( ExprUseXList(pTerm->pExpr->pLeft) );
pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr;
pRhs = pTerm->pExpr->pRight;
if( ExprUseXSelect(pRhs) ){
- pRhs = pRhs->x.pSelect->pEList->a[i].pExpr;
- }else{
- pRhs = pRhs->x.pList->a[i].pExpr;
- }
-
- /* Check that the LHS of the comparison is a column reference to
- ** the right column of the right source table. And that the sort
- ** order of the index column is the same as the sort order of the
- ** leftmost index column. */
+ pRhs = pRhs->x.pSelect->pEList->a[i].pExpr;
+ }else{
+ pRhs = pRhs->x.pList->a[i].pExpr;
+ }
+
+ /* Check that the LHS of the comparison is a column reference to
+ ** the right column of the right source table. And that the sort
+ ** order of the index column is the same as the sort order of the
+ ** leftmost index column. */
if( pLhs->op!=TK_COLUMN
|| pLhs->iTable!=iCur
|| pLhs->iColumn!=pIdx->aiColumn[i+nEq]
- || pIdx->aSortOrder[i+nEq]!=pIdx->aSortOrder[nEq]
- ){
- break;
- }
-
- testcase( pLhs->iColumn==XN_ROWID );
- aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs));
- idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn);
- if( aff!=idxaff ) break;
-
- pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
- if( pColl==0 ) break;
- if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break;
- }
- return i;
-}
-
+ || pIdx->aSortOrder[i+nEq]!=pIdx->aSortOrder[nEq]
+ ){
+ break;
+ }
+
+ testcase( pLhs->iColumn==XN_ROWID );
+ aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs));
+ idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn);
+ if( aff!=idxaff ) break;
+
+ pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
+ if( pColl==0 ) break;
+ if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break;
+ }
+ return i;
+}
+
/*
** Adjust the cost C by the costMult facter T. This only occurs if
** compiled with -DSQLITE_ENABLE_COSTMULT
@@ -153144,8 +153144,8 @@ static int whereLoopAddBtreeIndex(
Bitmask saved_prereq; /* Original value of pNew->prereq */
u16 saved_nLTerm; /* Original value of pNew->nLTerm */
u16 saved_nEq; /* Original value of pNew->u.btree.nEq */
- u16 saved_nBtm; /* Original value of pNew->u.btree.nBtm */
- u16 saved_nTop; /* Original value of pNew->u.btree.nTop */
+ u16 saved_nBtm; /* Original value of pNew->u.btree.nBtm */
+ u16 saved_nTop; /* Original value of pNew->u.btree.nTop */
u16 saved_nSkip; /* Original value of pNew->nSkip */
u32 saved_wsFlags; /* Original value of pNew->wsFlags */
LogEst saved_nOut; /* Original value of pNew->nOut */
@@ -153155,7 +153155,7 @@ static int whereLoopAddBtreeIndex(
WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
pNew = pBuilder->pNew;
- if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
+ if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n",
pProbe->pTable->zName,pProbe->zName,
pNew->u.btree.nEq, pNew->nSkip, pNew->rRun));
@@ -153165,7 +153165,7 @@ static int whereLoopAddBtreeIndex(
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
opMask = WO_LT|WO_LE;
}else{
- assert( pNew->u.btree.nBtm==0 );
+ assert( pNew->u.btree.nBtm==0 );
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
}
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
@@ -153175,15 +153175,15 @@ static int whereLoopAddBtreeIndex(
|| pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY );
saved_nEq = pNew->u.btree.nEq;
- saved_nBtm = pNew->u.btree.nBtm;
- saved_nTop = pNew->u.btree.nTop;
+ saved_nBtm = pNew->u.btree.nBtm;
+ saved_nTop = pNew->u.btree.nTop;
saved_nSkip = pNew->nSkip;
saved_nLTerm = pNew->nLTerm;
saved_wsFlags = pNew->wsFlags;
saved_prereq = pNew->prereq;
saved_nOut = pNew->nOut;
- pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, saved_nEq,
- opMask, pProbe);
+ pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, saved_nEq,
+ opMask, pProbe);
pNew->rSetup = 0;
rSize = pProbe->aiRowLogEst[0];
rLogSize = estLog(rSize);
@@ -153196,7 +153196,7 @@ static int whereLoopAddBtreeIndex(
int nRecValid = pBuilder->nRecValid;
#endif
if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
- && indexColumnNotNull(pProbe, saved_nEq)
+ && indexColumnNotNull(pProbe, saved_nEq)
){
continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */
}
@@ -153209,21 +153209,21 @@ static int whereLoopAddBtreeIndex(
/* tag-20191211-001: Do not allow constraints from the WHERE clause to
** be used by the right table of a LEFT JOIN. Only constraints in the
** ON clause are allowed. See tag-20191211-002 for the vtab equivalent. */
- if( (pSrc->fg.jointype & JT_LEFT)!=0
- && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
- ){
- continue;
- }
-
- if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
+ if( (pSrc->fg.jointype & JT_LEFT)!=0
+ && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+ ){
+ continue;
+ }
+
+ if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE;
- }else{
+ }else{
pBuilder->bldFlags1 |= SQLITE_BLDF1_INDEXED;
- }
+ }
pNew->wsFlags = saved_wsFlags;
pNew->u.btree.nEq = saved_nEq;
- pNew->u.btree.nBtm = saved_nBtm;
- pNew->u.btree.nTop = saved_nTop;
+ pNew->u.btree.nBtm = saved_nBtm;
+ pNew->u.btree.nTop = saved_nTop;
pNew->nLTerm = saved_nLTerm;
if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
pNew->aLTerm[pNew->nLTerm++] = pTerm;
@@ -153239,17 +153239,17 @@ static int whereLoopAddBtreeIndex(
Expr *pExpr = pTerm->pExpr;
if( ExprUseXSelect(pExpr) ){
/* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
- int i;
+ int i;
nIn = 46; assert( 46==sqlite3LogEst(25) );
-
- /* The expression may actually be of the form (x, y) IN (SELECT...).
- ** In this case there is a separate term for each of (x) and (y).
- ** However, the nIn multiplier should only be applied once, not once
- ** for each such term. The following loop checks that pTerm is the
- ** first such term in use, and sets nIn back to 0 if it is not. */
- for(i=0; i<pNew->nLTerm-1; i++){
- if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0;
- }
+
+ /* The expression may actually be of the form (x, y) IN (SELECT...).
+ ** In this case there is a separate term for each of (x) and (y).
+ ** However, the nIn multiplier should only be applied once, not once
+ ** for each such term. The following loop checks that pTerm is the
+ ** first such term in use, and sets nIn back to 0 if it is not. */
+ for(i=0; i<pNew->nLTerm-1; i++){
+ if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0;
+ }
}else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
/* "x IN (value, value, ...)" */
nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
@@ -153301,12 +153301,12 @@ static int whereLoopAddBtreeIndex(
}
pNew->wsFlags |= WHERE_COLUMN_IN;
}else if( eOp & (WO_EQ|WO_IS) ){
- int iCol = pProbe->aiColumn[saved_nEq];
+ int iCol = pProbe->aiColumn[saved_nEq];
pNew->wsFlags |= WHERE_COLUMN_EQ;
- assert( saved_nEq==pNew->u.btree.nEq );
+ assert( saved_nEq==pNew->u.btree.nEq );
if( iCol==XN_ROWID
- || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
- ){
+ || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
+ ){
if( iCol==XN_ROWID || pProbe->uniqNotNull
|| (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ)
){
@@ -153322,9 +153322,9 @@ static int whereLoopAddBtreeIndex(
testcase( eOp & WO_GT );
testcase( eOp & WO_GE );
pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
- pNew->u.btree.nBtm = whereRangeVectorLen(
- pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm
- );
+ pNew->u.btree.nBtm = whereRangeVectorLen(
+ pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm
+ );
pBtm = pTerm;
pTop = 0;
if( pTerm->wtFlags & TERM_LIKEOPT ){
@@ -153337,16 +153337,16 @@ static int whereLoopAddBtreeIndex(
if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
pNew->aLTerm[pNew->nLTerm++] = pTop;
pNew->wsFlags |= WHERE_TOP_LIMIT;
- pNew->u.btree.nTop = 1;
+ pNew->u.btree.nTop = 1;
}
}else{
assert( eOp & (WO_LT|WO_LE) );
testcase( eOp & WO_LT );
testcase( eOp & WO_LE );
pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
- pNew->u.btree.nTop = whereRangeVectorLen(
- pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm
- );
+ pNew->u.btree.nTop = whereRangeVectorLen(
+ pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm
+ );
pTop = pTerm;
pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
pNew->aLTerm[pNew->nLTerm-2] : 0;
@@ -153367,7 +153367,7 @@ static int whereLoopAddBtreeIndex(
assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) );
assert( pNew->nOut==saved_nOut );
- if( pTerm->truthProb<=0 && pProbe->aiColumn[saved_nEq]>=0 ){
+ if( pTerm->truthProb<=0 && pProbe->aiColumn[saved_nEq]>=0 ){
assert( (eOp & WO_IN) || nIn==0 );
testcase( eOp & WO_IN );
pNew->nOut += pTerm->truthProb;
@@ -153471,8 +153471,8 @@ static int whereLoopAddBtreeIndex(
}
pNew->prereq = saved_prereq;
pNew->u.btree.nEq = saved_nEq;
- pNew->u.btree.nBtm = saved_nBtm;
- pNew->u.btree.nTop = saved_nTop;
+ pNew->u.btree.nBtm = saved_nBtm;
+ pNew->u.btree.nTop = saved_nTop;
pNew->nSkip = saved_nSkip;
pNew->wsFlags = saved_wsFlags;
pNew->nOut = saved_nOut;
@@ -153534,7 +153534,7 @@ static int indexMightHelpWithOrderBy(
int iCursor
){
ExprList *pOB;
- ExprList *aColExpr;
+ ExprList *aColExpr;
int ii, jj;
if( pIndex->bUnordered ) return 0;
@@ -153542,18 +153542,18 @@ static int indexMightHelpWithOrderBy(
for(ii=0; ii<pOB->nExpr; ii++){
Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr);
if( NEVER(pExpr==0) ) continue;
- if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){
+ if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){
if( pExpr->iColumn<0 ) return 1;
for(jj=0; jj<pIndex->nKeyCol; jj++){
if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
}
- }else if( (aColExpr = pIndex->aColExpr)!=0 ){
- for(jj=0; jj<pIndex->nKeyCol; jj++){
- if( pIndex->aiColumn[jj]!=XN_EXPR ) continue;
- if( sqlite3ExprCompareSkip(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
- return 1;
- }
- }
+ }else if( (aColExpr = pIndex->aColExpr)!=0 ){
+ for(jj=0; jj<pIndex->nKeyCol; jj++){
+ if( pIndex->aiColumn[jj]!=XN_EXPR ) continue;
+ if( sqlite3ExprCompareSkip(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
+ return 1;
+ }
+ }
}
}
return 0;
@@ -153570,16 +153570,16 @@ static int whereUsablePartialIndex(
){
int i;
WhereTerm *pTerm;
- Parse *pParse = pWC->pWInfo->pParse;
- while( pWhere->op==TK_AND ){
+ Parse *pParse = pWC->pWInfo->pParse;
+ while( pWhere->op==TK_AND ){
if( !whereUsablePartialIndex(iTab,isLeft,pWC,pWhere->pLeft) ) return 0;
- pWhere = pWhere->pRight;
- }
- if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
+ pWhere = pWhere->pRight;
+ }
+ if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
Expr *pExpr;
pExpr = pTerm->pExpr;
- if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
+ if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
&& (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
&& (pTerm->wtFlags & TERM_VNULL)==0
@@ -153592,7 +153592,7 @@ static int whereUsablePartialIndex(
/*
** Add all WhereLoop objects for a single table of the join where the table
-** is identified by pBuilder->pNew->iTab. That table is guaranteed to be
+** is identified by pBuilder->pNew->iTab. That table is guaranteed to be
** a b-tree table, not a virtual table.
**
** The costs (WhereLoop.rRun) of the b-tree loops added by this function
@@ -153628,7 +153628,7 @@ static int whereUsablePartialIndex(
*/
static int whereLoopAddBtree(
WhereLoopBuilder *pBuilder, /* WHERE clause information */
- Bitmask mPrereq /* Extra prerequesites for using this table */
+ Bitmask mPrereq /* Extra prerequesites for using this table */
){
WhereInfo *pWInfo; /* WHERE analysis context */
Index *pProbe; /* An index we are evaluating */
@@ -153677,7 +153677,7 @@ static int whereLoopAddBtree(
aiRowEstPk[0] = pTab->nRowLogEst;
aiRowEstPk[1] = 0;
pFirst = pSrc->pTab->pIndex;
- if( pSrc->fg.notIndexed==0 ){
+ if( pSrc->fg.notIndexed==0 ){
/* The real indices of the table are only considered if the
** NOT INDEXED qualifier is omitted from the FROM clause */
sPk.pNext = pFirst;
@@ -153688,14 +153688,14 @@ static int whereLoopAddBtree(
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/* Automatic indexes */
- if( !pBuilder->pOrSet /* Not part of an OR optimization */
- && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
+ if( !pBuilder->pOrSet /* Not part of an OR optimization */
+ && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
&& !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */
- && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */
- && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */
- && !pSrc->fg.isCorrelated /* Not a correlated subquery */
- && !pSrc->fg.isRecursive /* Not a recursive common table expression. */
+ && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */
+ && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */
+ && !pSrc->fg.isCorrelated /* Not a correlated subquery */
+ && !pSrc->fg.isRecursive /* Not a recursive common table expression. */
){
/* Generate auto-index WhereLoops */
LogEst rLogSize; /* Logarithm of the number of rows in the table */
@@ -153725,7 +153725,7 @@ static int whereLoopAddBtree(
pNew->rSetup -= 10;
}
ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
- if( pNew->rSetup<0 ) pNew->rSetup = 0;
+ if( pNew->rSetup<0 ) pNew->rSetup = 0;
/* TUNING: Each index lookup yields 20 rows in the table. This
** is more than the usual guess of 10 rows, since we have no way
** of knowing how selective the index will ultimately be. It would
@@ -153733,7 +153733,7 @@ static int whereLoopAddBtree(
pNew->nOut = 43; assert( 43==sqlite3LogEst(20) );
pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut);
pNew->wsFlags = WHERE_AUTO_INDEX;
- pNew->prereq = mPrereq | pTerm->prereqRight;
+ pNew->prereq = mPrereq | pTerm->prereqRight;
rc = whereLoopInsert(pBuilder, pNew);
}
}
@@ -153741,10 +153741,10 @@ static int whereLoopAddBtree(
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
/* Loop over all indices. If there was an INDEXED BY clause, then only
- ** consider index pProbe. */
+ ** consider index pProbe. */
for(; rc==SQLITE_OK && pProbe;
pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++
- ){
+ ){
int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0;
if( pProbe->pPartIdxWhere!=0
&& !whereUsablePartialIndex(pSrc->iCursor, isLeft, pWC,
@@ -153753,16 +153753,16 @@ static int whereLoopAddBtree(
testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */
continue; /* Partial index inappropriate for this query */
}
- if( pProbe->bNoQuery ) continue;
+ if( pProbe->bNoQuery ) continue;
rSize = pProbe->aiRowLogEst[0];
pNew->u.btree.nEq = 0;
- pNew->u.btree.nBtm = 0;
- pNew->u.btree.nTop = 0;
+ pNew->u.btree.nBtm = 0;
+ pNew->u.btree.nTop = 0;
pNew->nSkip = 0;
pNew->nLTerm = 0;
pNew->iSortIdx = 0;
pNew->rSetup = 0;
- pNew->prereq = mPrereq;
+ pNew->prereq = mPrereq;
pNew->nOut = rSize;
pNew->u.btree.pIndex = pProbe;
b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
@@ -153810,7 +153810,7 @@ static int whereLoopAddBtree(
/* Full scan via index */
if( b
|| !HasRowid(pTab)
- || pProbe->pPartIdxWhere!=0
+ || pProbe->pPartIdxWhere!=0
|| pSrc->fg.isIndexedBy
|| ( m==0
&& pProbe->bUnordered==0
@@ -153824,34 +153824,34 @@ static int whereLoopAddBtree(
/* The cost of visiting the index rows is N*K, where K is
** between 1.1 and 3.0, depending on the relative sizes of the
- ** index and table rows. */
+ ** index and table rows. */
pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow;
if( m!=0 ){
- /* If this is a non-covering index scan, add in the cost of
- ** doing table lookups. The cost will be 3x the number of
- ** lookups. Take into account WHERE clause terms that can be
- ** satisfied using just the index, and that do not require a
- ** table lookup. */
- LogEst nLookup = rSize + 16; /* Base cost: N*3 */
- int ii;
- int iCur = pSrc->iCursor;
- WhereClause *pWC2 = &pWInfo->sWC;
- for(ii=0; ii<pWC2->nTerm; ii++){
- WhereTerm *pTerm = &pWC2->a[ii];
- if( !sqlite3ExprCoveredByIndex(pTerm->pExpr, iCur, pProbe) ){
- break;
- }
- /* pTerm can be evaluated using just the index. So reduce
- ** the expected number of table lookups accordingly */
- if( pTerm->truthProb<=0 ){
- nLookup += pTerm->truthProb;
- }else{
- nLookup--;
- if( pTerm->eOperator & (WO_EQ|WO_IS) ) nLookup -= 19;
- }
- }
-
- pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup);
+ /* If this is a non-covering index scan, add in the cost of
+ ** doing table lookups. The cost will be 3x the number of
+ ** lookups. Take into account WHERE clause terms that can be
+ ** satisfied using just the index, and that do not require a
+ ** table lookup. */
+ LogEst nLookup = rSize + 16; /* Base cost: N*3 */
+ int ii;
+ int iCur = pSrc->iCursor;
+ WhereClause *pWC2 = &pWInfo->sWC;
+ for(ii=0; ii<pWC2->nTerm; ii++){
+ WhereTerm *pTerm = &pWC2->a[ii];
+ if( !sqlite3ExprCoveredByIndex(pTerm->pExpr, iCur, pProbe) ){
+ break;
+ }
+ /* pTerm can be evaluated using just the index. So reduce
+ ** the expected number of table lookups accordingly */
+ if( pTerm->truthProb<=0 ){
+ nLookup += pTerm->truthProb;
+ }else{
+ nLookup--;
+ if( pTerm->eOperator & (WO_EQ|WO_IS) ) nLookup -= 19;
+ }
+ }
+
+ pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup);
}
ApplyCostMultiplier(pNew->rRun, pTab->costMult);
whereLoopOutputAdjust(pWC, pNew, rSize);
@@ -153864,12 +153864,12 @@ static int whereLoopAddBtree(
pBuilder->bldFlags1 = 0;
rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
if( pBuilder->bldFlags1==SQLITE_BLDF1_INDEXED ){
- /* If a non-unique index is used, or if a prefix of the key for
- ** unique index is used (making the index functionally non-unique)
- ** then the sqlite_stat1 data becomes important for scoring the
- ** plan */
- pTab->tabFlags |= TF_StatsUsed;
- }
+ /* If a non-unique index is used, or if a prefix of the key for
+ ** unique index is used (making the index functionally non-unique)
+ ** then the sqlite_stat1 data becomes important for scoring the
+ ** plan */
+ pTab->tabFlags |= TF_StatsUsed;
+ }
#ifdef SQLITE_ENABLE_STAT4
sqlite3Stat4ProbeFree(pBuilder->pRec);
pBuilder->nRecValid = 0;
@@ -153880,77 +153880,77 @@ static int whereLoopAddBtree(
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
-
-/*
-** Argument pIdxInfo is already populated with all constraints that may
-** be used by the virtual table identified by pBuilder->pNew->iTab. This
-** function marks a subset of those constraints usable, invokes the
-** xBestIndex method and adds the returned plan to pBuilder.
-**
-** A constraint is marked usable if:
-**
-** * Argument mUsable indicates that its prerequisites are available, and
-**
-** * It is not one of the operators specified in the mExclude mask passed
-** as the fourth argument (which in practice is either WO_IN or 0).
-**
-** Argument mPrereq is a mask of tables that must be scanned before the
-** virtual table in question. These are added to the plans prerequisites
-** before it is added to pBuilder.
-**
-** Output parameter *pbIn is set to true if the plan added to pBuilder
-** uses one or more WO_IN terms, or false otherwise.
-*/
-static int whereLoopAddVirtualOne(
- WhereLoopBuilder *pBuilder,
- Bitmask mPrereq, /* Mask of tables that must be used. */
- Bitmask mUsable, /* Mask of usable tables */
- u16 mExclude, /* Exclude terms using these operators */
- sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
- u16 mNoOmit, /* Do not omit these constraints */
- int *pbIn /* OUT: True if plan uses an IN(...) op */
-){
- WhereClause *pWC = pBuilder->pWC;
- struct sqlite3_index_constraint *pIdxCons;
- struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
- int i;
- int mxTerm;
- int rc = SQLITE_OK;
- WhereLoop *pNew = pBuilder->pNew;
- Parse *pParse = pBuilder->pWInfo->pParse;
+
+/*
+** Argument pIdxInfo is already populated with all constraints that may
+** be used by the virtual table identified by pBuilder->pNew->iTab. This
+** function marks a subset of those constraints usable, invokes the
+** xBestIndex method and adds the returned plan to pBuilder.
+**
+** A constraint is marked usable if:
+**
+** * Argument mUsable indicates that its prerequisites are available, and
+**
+** * It is not one of the operators specified in the mExclude mask passed
+** as the fourth argument (which in practice is either WO_IN or 0).
+**
+** Argument mPrereq is a mask of tables that must be scanned before the
+** virtual table in question. These are added to the plans prerequisites
+** before it is added to pBuilder.
+**
+** Output parameter *pbIn is set to true if the plan added to pBuilder
+** uses one or more WO_IN terms, or false otherwise.
+*/
+static int whereLoopAddVirtualOne(
+ WhereLoopBuilder *pBuilder,
+ Bitmask mPrereq, /* Mask of tables that must be used. */
+ Bitmask mUsable, /* Mask of usable tables */
+ u16 mExclude, /* Exclude terms using these operators */
+ sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
+ u16 mNoOmit, /* Do not omit these constraints */
+ int *pbIn /* OUT: True if plan uses an IN(...) op */
+){
+ WhereClause *pWC = pBuilder->pWC;
+ struct sqlite3_index_constraint *pIdxCons;
+ struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
+ int i;
+ int mxTerm;
+ int rc = SQLITE_OK;
+ WhereLoop *pNew = pBuilder->pNew;
+ Parse *pParse = pBuilder->pWInfo->pParse;
SrcItem *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab];
- int nConstraint = pIdxInfo->nConstraint;
-
- assert( (mUsable & mPrereq)==mPrereq );
- *pbIn = 0;
- pNew->prereq = mPrereq;
-
+ int nConstraint = pIdxInfo->nConstraint;
+
+ assert( (mUsable & mPrereq)==mPrereq );
+ *pbIn = 0;
+ pNew->prereq = mPrereq;
+
/* Set the usable flag on the subset of constraints identified by
- ** arguments mUsable and mExclude. */
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
- for(i=0; i<nConstraint; i++, pIdxCons++){
- WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset];
- pIdxCons->usable = 0;
+ ** arguments mUsable and mExclude. */
+ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+ for(i=0; i<nConstraint; i++, pIdxCons++){
+ WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset];
+ pIdxCons->usable = 0;
if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight
- && (pTerm->eOperator & mExclude)==0
- ){
- pIdxCons->usable = 1;
- }
- }
-
- /* Initialize the output fields of the sqlite3_index_info structure */
- memset(pUsage, 0, sizeof(pUsage[0])*nConstraint);
- assert( pIdxInfo->needToFreeIdxStr==0 );
- pIdxInfo->idxStr = 0;
- pIdxInfo->idxNum = 0;
- pIdxInfo->orderByConsumed = 0;
- pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
- pIdxInfo->estimatedRows = 25;
- pIdxInfo->idxFlags = 0;
- pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
-
- /* Invoke the virtual table xBestIndex() method */
- rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
+ && (pTerm->eOperator & mExclude)==0
+ ){
+ pIdxCons->usable = 1;
+ }
+ }
+
+ /* Initialize the output fields of the sqlite3_index_info structure */
+ memset(pUsage, 0, sizeof(pUsage[0])*nConstraint);
+ assert( pIdxInfo->needToFreeIdxStr==0 );
+ pIdxInfo->idxStr = 0;
+ pIdxInfo->idxNum = 0;
+ pIdxInfo->orderByConsumed = 0;
+ pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
+ pIdxInfo->estimatedRows = 25;
+ pIdxInfo->idxFlags = 0;
+ pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
+
+ /* Invoke the virtual table xBestIndex() method */
+ rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
if( rc ){
if( rc==SQLITE_CONSTRAINT ){
/* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
@@ -153962,37 +153962,37 @@ static int whereLoopAddVirtualOne(
}
return rc;
}
-
- mxTerm = -1;
- assert( pNew->nLSlot>=nConstraint );
- for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
- pNew->u.vtab.omitMask = 0;
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
- for(i=0; i<nConstraint; i++, pIdxCons++){
- int iTerm;
- if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
- WhereTerm *pTerm;
- int j = pIdxCons->iTermOffset;
- if( iTerm>=nConstraint
- || j<0
- || j>=pWC->nTerm
- || pNew->aLTerm[iTerm]!=0
- || pIdxCons->usable==0
- ){
- sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
+
+ mxTerm = -1;
+ assert( pNew->nLSlot>=nConstraint );
+ for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
+ pNew->u.vtab.omitMask = 0;
+ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+ for(i=0; i<nConstraint; i++, pIdxCons++){
+ int iTerm;
+ if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
+ WhereTerm *pTerm;
+ int j = pIdxCons->iTermOffset;
+ if( iTerm>=nConstraint
+ || j<0
+ || j>=pWC->nTerm
+ || pNew->aLTerm[iTerm]!=0
+ || pIdxCons->usable==0
+ ){
+ sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
testcase( pIdxInfo->needToFreeIdxStr );
return SQLITE_ERROR;
- }
- testcase( iTerm==nConstraint-1 );
- testcase( j==0 );
- testcase( j==pWC->nTerm-1 );
- pTerm = &pWC->a[j];
- pNew->prereq |= pTerm->prereqRight;
- assert( iTerm<pNew->nLSlot );
- pNew->aLTerm[iTerm] = pTerm;
- if( iTerm>mxTerm ) mxTerm = iTerm;
- testcase( iTerm==15 );
- testcase( iTerm==16 );
+ }
+ testcase( iTerm==nConstraint-1 );
+ testcase( j==0 );
+ testcase( j==pWC->nTerm-1 );
+ pTerm = &pWC->a[j];
+ pNew->prereq |= pTerm->prereqRight;
+ assert( iTerm<pNew->nLSlot );
+ pNew->aLTerm[iTerm] = pTerm;
+ if( iTerm>mxTerm ) mxTerm = iTerm;
+ testcase( iTerm==15 );
+ testcase( iTerm==16 );
if( pUsage[i].omit ){
if( i<16 && ((1<<i)&mNoOmit)==0 ){
testcase( i!=iTerm );
@@ -154001,20 +154001,20 @@ static int whereLoopAddVirtualOne(
testcase( i!=iTerm );
}
}
- if( (pTerm->eOperator & WO_IN)!=0 ){
- /* A virtual table that is constrained by an IN clause may not
- ** consume the ORDER BY clause because (1) the order of IN terms
- ** is not necessarily related to the order of output terms and
- ** (2) Multiple outputs from a single IN value will not merge
- ** together. */
- pIdxInfo->orderByConsumed = 0;
- pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
- *pbIn = 1; assert( (mExclude & WO_IN)==0 );
- }
- }
- }
-
- pNew->nLTerm = mxTerm+1;
+ if( (pTerm->eOperator & WO_IN)!=0 ){
+ /* A virtual table that is constrained by an IN clause may not
+ ** consume the ORDER BY clause because (1) the order of IN terms
+ ** is not necessarily related to the order of output terms and
+ ** (2) Multiple outputs from a single IN value will not merge
+ ** together. */
+ pIdxInfo->orderByConsumed = 0;
+ pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
+ *pbIn = 1; assert( (mExclude & WO_IN)==0 );
+ }
+ }
+ }
+
+ pNew->nLTerm = mxTerm+1;
for(i=0; i<=mxTerm; i++){
if( pNew->aLTerm[i]==0 ){
/* The non-zero argvIdx values must be contiguous. Raise an
@@ -154024,64 +154024,64 @@ static int whereLoopAddVirtualOne(
return SQLITE_ERROR;
}
}
- assert( pNew->nLTerm<=pNew->nLSlot );
- pNew->u.vtab.idxNum = pIdxInfo->idxNum;
- pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
- pIdxInfo->needToFreeIdxStr = 0;
- pNew->u.vtab.idxStr = pIdxInfo->idxStr;
- pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
- pIdxInfo->nOrderBy : 0);
- pNew->rSetup = 0;
- pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
- pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
-
- /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
- ** that the scan will visit at most one row. Clear it otherwise. */
- if( pIdxInfo->idxFlags & SQLITE_INDEX_SCAN_UNIQUE ){
- pNew->wsFlags |= WHERE_ONEROW;
- }else{
- pNew->wsFlags &= ~WHERE_ONEROW;
- }
- rc = whereLoopInsert(pBuilder, pNew);
- if( pNew->u.vtab.needFree ){
- sqlite3_free(pNew->u.vtab.idxStr);
- pNew->u.vtab.needFree = 0;
- }
- WHERETRACE(0xffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n",
- *pbIn, (sqlite3_uint64)mPrereq,
- (sqlite3_uint64)(pNew->prereq & ~mPrereq)));
-
- return rc;
-}
-
-/*
-** If this function is invoked from within an xBestIndex() callback, it
-** returns a pointer to a buffer containing the name of the collation
-** sequence associated with element iCons of the sqlite3_index_info.aConstraint
-** array. Or, if iCons is out of range or there is no active xBestIndex
-** call, return NULL.
-*/
-SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){
- HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
- const char *zRet = 0;
- if( iCons>=0 && iCons<pIdxInfo->nConstraint ){
- CollSeq *pC = 0;
- int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset;
- Expr *pX = pHidden->pWC->a[iTerm].pExpr;
- if( pX->pLeft ){
+ assert( pNew->nLTerm<=pNew->nLSlot );
+ pNew->u.vtab.idxNum = pIdxInfo->idxNum;
+ pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
+ pIdxInfo->needToFreeIdxStr = 0;
+ pNew->u.vtab.idxStr = pIdxInfo->idxStr;
+ pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
+ pIdxInfo->nOrderBy : 0);
+ pNew->rSetup = 0;
+ pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
+ pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
+
+ /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
+ ** that the scan will visit at most one row. Clear it otherwise. */
+ if( pIdxInfo->idxFlags & SQLITE_INDEX_SCAN_UNIQUE ){
+ pNew->wsFlags |= WHERE_ONEROW;
+ }else{
+ pNew->wsFlags &= ~WHERE_ONEROW;
+ }
+ rc = whereLoopInsert(pBuilder, pNew);
+ if( pNew->u.vtab.needFree ){
+ sqlite3_free(pNew->u.vtab.idxStr);
+ pNew->u.vtab.needFree = 0;
+ }
+ WHERETRACE(0xffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n",
+ *pbIn, (sqlite3_uint64)mPrereq,
+ (sqlite3_uint64)(pNew->prereq & ~mPrereq)));
+
+ return rc;
+}
+
+/*
+** If this function is invoked from within an xBestIndex() callback, it
+** returns a pointer to a buffer containing the name of the collation
+** sequence associated with element iCons of the sqlite3_index_info.aConstraint
+** array. Or, if iCons is out of range or there is no active xBestIndex
+** call, return NULL.
+*/
+SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){
+ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
+ const char *zRet = 0;
+ if( iCons>=0 && iCons<pIdxInfo->nConstraint ){
+ CollSeq *pC = 0;
+ int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset;
+ Expr *pX = pHidden->pWC->a[iTerm].pExpr;
+ if( pX->pLeft ){
pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX);
- }
+ }
zRet = (pC ? pC->zName : sqlite3StrBINARY);
- }
- return zRet;
-}
-
-/*
+ }
+ return zRet;
+}
+
+/*
** Add all WhereLoop objects for a table of the join identified by
** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
**
-** If there are no LEFT or CROSS JOIN joins in the query, both mPrereq and
-** mUnusable are set to 0. Otherwise, mPrereq is a mask of all FROM clause
+** If there are no LEFT or CROSS JOIN joins in the query, both mPrereq and
+** mUnusable are set to 0. Otherwise, mPrereq is a mask of all FROM clause
** entries that occur before the virtual table in the FROM clause and are
** separated from it by at least one LEFT or CROSS JOIN. Similarly, the
** mUnusable mask contains all FROM clause entries that occur after the
@@ -154092,7 +154092,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int
**
** ... FROM t1, t2 LEFT JOIN t3, t4, vt CROSS JOIN t5, t6;
**
-** then mPrereq corresponds to (t1, t2) and mUnusable to (t5, t6).
+** then mPrereq corresponds to (t1, t2) and mUnusable to (t5, t6).
**
** All the tables in mPrereq must be scanned before the current virtual
** table. So any terms for which all prerequisites are satisfied by
@@ -154103,118 +154103,118 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int
*/
static int whereLoopAddVirtual(
WhereLoopBuilder *pBuilder, /* WHERE clause information */
- Bitmask mPrereq, /* Tables that must be scanned before this one */
+ Bitmask mPrereq, /* Tables that must be scanned before this one */
Bitmask mUnusable /* Tables that must be scanned after this one */
){
- int rc = SQLITE_OK; /* Return code */
+ int rc = SQLITE_OK; /* Return code */
WhereInfo *pWInfo; /* WHERE analysis context */
Parse *pParse; /* The parsing context */
WhereClause *pWC; /* The WHERE clause */
SrcItem *pSrc; /* The FROM clause term to search */
- sqlite3_index_info *p; /* Object to pass to xBestIndex() */
- int nConstraint; /* Number of constraints in p */
- int bIn; /* True if plan uses IN(...) operator */
+ sqlite3_index_info *p; /* Object to pass to xBestIndex() */
+ int nConstraint; /* Number of constraints in p */
+ int bIn; /* True if plan uses IN(...) operator */
WhereLoop *pNew;
- Bitmask mBest; /* Tables used by best possible plan */
- u16 mNoOmit;
+ Bitmask mBest; /* Tables used by best possible plan */
+ u16 mNoOmit;
- assert( (mPrereq & mUnusable)==0 );
+ assert( (mPrereq & mUnusable)==0 );
pWInfo = pBuilder->pWInfo;
pParse = pWInfo->pParse;
pWC = pBuilder->pWC;
pNew = pBuilder->pNew;
pSrc = &pWInfo->pTabList->a[pNew->iTab];
- assert( IsVirtual(pSrc->pTab) );
+ assert( IsVirtual(pSrc->pTab) );
p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy,
- &mNoOmit);
- if( p==0 ) return SQLITE_NOMEM_BKPT;
+ &mNoOmit);
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
pNew->rSetup = 0;
pNew->wsFlags = WHERE_VIRTUALTABLE;
pNew->nLTerm = 0;
pNew->u.vtab.needFree = 0;
- nConstraint = p->nConstraint;
- if( whereLoopResize(pParse->db, pNew, nConstraint) ){
- sqlite3DbFree(pParse->db, p);
- return SQLITE_NOMEM_BKPT;
+ nConstraint = p->nConstraint;
+ if( whereLoopResize(pParse->db, pNew, nConstraint) ){
+ sqlite3DbFree(pParse->db, p);
+ return SQLITE_NOMEM_BKPT;
}
- /* First call xBestIndex() with all constraints usable. */
+ /* First call xBestIndex() with all constraints usable. */
WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
- WHERETRACE(0x40, (" VirtualOne: all usable\n"));
- rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
-
- /* If the call to xBestIndex() with all terms enabled produced a plan
+ WHERETRACE(0x40, (" VirtualOne: all usable\n"));
+ rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
+
+ /* If the call to xBestIndex() with all terms enabled produced a plan
** that does not require any source tables (IOW: a plan with mBest==0)
** and does not use an IN(...) operator, then there is no point in making
** any further calls to xBestIndex() since they will all return the same
** result (if the xBestIndex() implementation is sane). */
if( rc==SQLITE_OK && ((mBest = (pNew->prereq & ~mPrereq))!=0 || bIn) ){
- int seenZero = 0; /* True if a plan with no prereqs seen */
- int seenZeroNoIN = 0; /* Plan with no prereqs and no IN(...) seen */
- Bitmask mPrev = 0;
- Bitmask mBestNoIn = 0;
-
- /* If the plan produced by the earlier call uses an IN(...) term, call
- ** xBestIndex again, this time with IN(...) terms disabled. */
- if( bIn ){
- WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
- rc = whereLoopAddVirtualOne(
- pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn);
- assert( bIn==0 );
- mBestNoIn = pNew->prereq & ~mPrereq;
- if( mBestNoIn==0 ){
- seenZero = 1;
- seenZeroNoIN = 1;
- }
- }
-
+ int seenZero = 0; /* True if a plan with no prereqs seen */
+ int seenZeroNoIN = 0; /* Plan with no prereqs and no IN(...) seen */
+ Bitmask mPrev = 0;
+ Bitmask mBestNoIn = 0;
+
+ /* If the plan produced by the earlier call uses an IN(...) term, call
+ ** xBestIndex again, this time with IN(...) terms disabled. */
+ if( bIn ){
+ WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
+ rc = whereLoopAddVirtualOne(
+ pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn);
+ assert( bIn==0 );
+ mBestNoIn = pNew->prereq & ~mPrereq;
+ if( mBestNoIn==0 ){
+ seenZero = 1;
+ seenZeroNoIN = 1;
+ }
+ }
+
/* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq)
- ** in the set of terms that apply to the current virtual table. */
- while( rc==SQLITE_OK ){
- int i;
- Bitmask mNext = ALLBITS;
- assert( mNext>0 );
- for(i=0; i<nConstraint; i++){
- Bitmask mThis = (
- pWC->a[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq
- );
- if( mThis>mPrev && mThis<mNext ) mNext = mThis;
- }
- mPrev = mNext;
- if( mNext==ALLBITS ) break;
- if( mNext==mBest || mNext==mBestNoIn ) continue;
- WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
- (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
- rc = whereLoopAddVirtualOne(
- pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn);
- if( pNew->prereq==mPrereq ){
- seenZero = 1;
- if( bIn==0 ) seenZeroNoIN = 1;
- }
- }
-
- /* If the calls to xBestIndex() in the above loop did not find a plan
- ** that requires no source tables at all (i.e. one guaranteed to be
- ** usable), make a call here with all source tables disabled */
- if( rc==SQLITE_OK && seenZero==0 ){
- WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
- rc = whereLoopAddVirtualOne(
- pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn);
- if( bIn==0 ) seenZeroNoIN = 1;
- }
-
- /* If the calls to xBestIndex() have so far failed to find a plan
- ** that requires no source tables at all and does not use an IN(...)
- ** operator, make a final call to obtain one here. */
- if( rc==SQLITE_OK && seenZeroNoIN==0 ){
- WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
- rc = whereLoopAddVirtualOne(
- pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
- }
- }
-
- if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
- sqlite3DbFreeNN(pParse->db, p);
+ ** in the set of terms that apply to the current virtual table. */
+ while( rc==SQLITE_OK ){
+ int i;
+ Bitmask mNext = ALLBITS;
+ assert( mNext>0 );
+ for(i=0; i<nConstraint; i++){
+ Bitmask mThis = (
+ pWC->a[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq
+ );
+ if( mThis>mPrev && mThis<mNext ) mNext = mThis;
+ }
+ mPrev = mNext;
+ if( mNext==ALLBITS ) break;
+ if( mNext==mBest || mNext==mBestNoIn ) continue;
+ WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
+ (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
+ rc = whereLoopAddVirtualOne(
+ pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn);
+ if( pNew->prereq==mPrereq ){
+ seenZero = 1;
+ if( bIn==0 ) seenZeroNoIN = 1;
+ }
+ }
+
+ /* If the calls to xBestIndex() in the above loop did not find a plan
+ ** that requires no source tables at all (i.e. one guaranteed to be
+ ** usable), make a call here with all source tables disabled */
+ if( rc==SQLITE_OK && seenZero==0 ){
+ WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
+ rc = whereLoopAddVirtualOne(
+ pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn);
+ if( bIn==0 ) seenZeroNoIN = 1;
+ }
+
+ /* If the calls to xBestIndex() have so far failed to find a plan
+ ** that requires no source tables at all and does not use an IN(...)
+ ** operator, make a final call to obtain one here. */
+ if( rc==SQLITE_OK && seenZeroNoIN==0 ){
+ WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
+ rc = whereLoopAddVirtualOne(
+ pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
+ }
+ }
+
+ if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
+ sqlite3DbFreeNN(pParse->db, p);
WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc));
return rc;
}
@@ -154280,19 +154280,19 @@ static int whereLoopAddOr(
WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n",
(int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm));
if( sqlite3WhereTrace & 0x400 ){
- sqlite3WhereClausePrint(sSubBuild.pWC);
+ sqlite3WhereClausePrint(sSubBuild.pWC);
}
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pItem->pTab) ){
- rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable);
+ rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable);
}else
#endif
{
- rc = whereLoopAddBtree(&sSubBuild, mPrereq);
+ rc = whereLoopAddBtree(&sSubBuild, mPrereq);
}
if( rc==SQLITE_OK ){
- rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable);
+ rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable);
}
assert( rc==SQLITE_OK || rc==SQLITE_DONE || sCur.n==0
|| rc==SQLITE_NOMEM );
@@ -154352,7 +154352,7 @@ static int whereLoopAddOr(
*/
static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
WhereInfo *pWInfo = pBuilder->pWInfo;
- Bitmask mPrereq = 0;
+ Bitmask mPrereq = 0;
Bitmask mPrior = 0;
int iTab;
SrcList *pTabList = pWInfo->pTabList;
@@ -154374,26 +154374,26 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
if( (pItem->fg.jointype & (JT_LEFT|JT_CROSS))!=0 ){
/* This condition is true when pItem is the FROM clause term on the
** right-hand-side of a LEFT or CROSS JOIN. */
- mPrereq = mPrior;
+ mPrereq = mPrior;
}else{
mPrereq = 0;
}
-#ifndef SQLITE_OMIT_VIRTUALTABLE
+#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pItem->pTab) ){
SrcItem *p;
for(p=&pItem[1]; p<pEnd; p++){
- if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){
+ if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){
mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
}
}
- rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable);
- }else
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
- {
- rc = whereLoopAddBtree(pBuilder, mPrereq);
+ rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable);
+ }else
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+ {
+ rc = whereLoopAddBtree(pBuilder, mPrereq);
}
if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){
- rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
+ rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
}
mPrior |= pNew->maskSelf;
if( rc || db->mallocFailed ){
@@ -154412,7 +154412,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
}
/*
-** Examine a WherePath (with the addition of the extra WhereLoop of the 6th
+** Examine a WherePath (with the addition of the extra WhereLoop of the 6th
** parameters) to see if it outputs rows in the requested ORDER BY
** (or GROUP BY) without requiring a separate sort operation. Return N:
**
@@ -154432,7 +154432,7 @@ static i8 wherePathSatisfiesOrderBy(
WhereInfo *pWInfo, /* The WHERE clause */
ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */
WherePath *pPath, /* The WherePath to check */
- u16 wctrlFlags, /* WHERE_GROUPBY or _DISTINCTBY or _ORDERBY_LIMIT */
+ u16 wctrlFlags, /* WHERE_GROUPBY or _DISTINCTBY or _ORDERBY_LIMIT */
u16 nLoop, /* Number of entries in pPath->aLoop[] */
WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */
Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */
@@ -154443,7 +154443,7 @@ static i8 wherePathSatisfiesOrderBy(
u8 isOrderDistinct; /* All prior WhereLoops are order-distinct */
u8 distinctColumns; /* True if the loop has UNIQUE NOT NULL columns */
u8 isMatch; /* iColumn matches a term of the ORDER BY clause */
- u16 eqOpMask; /* Allowed equality operators */
+ u16 eqOpMask; /* Allowed equality operators */
u16 nKeyCol; /* Number of key columns in pIndex */
u16 nColumn; /* Total number of ordered columns in the index */
u16 nOrderBy; /* Number terms in the ORDER BY clause */
@@ -154494,18 +154494,18 @@ static i8 wherePathSatisfiesOrderBy(
obDone = MASKBIT(nOrderBy)-1;
orderDistinctMask = 0;
ready = 0;
- eqOpMask = WO_EQ | WO_IS | WO_ISNULL;
+ eqOpMask = WO_EQ | WO_IS | WO_ISNULL;
if( wctrlFlags & (WHERE_ORDERBY_LIMIT|WHERE_ORDERBY_MAX|WHERE_ORDERBY_MIN) ){
eqOpMask |= WO_IN;
}
for(iLoop=0; isOrderDistinct && obSat<obDone && iLoop<=nLoop; iLoop++){
if( iLoop>0 ) ready |= pLoop->maskSelf;
- if( iLoop<nLoop ){
- pLoop = pPath->aLoop[iLoop];
- if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue;
- }else{
- pLoop = pLast;
- }
+ if( iLoop<nLoop ){
+ pLoop = pPath->aLoop[iLoop];
+ if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue;
+ }else{
+ pLoop = pLast;
+ }
if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
if( pLoop->u.vtab.isOrdered && (wctrlFlags & WHERE_DISTINCTBY)==0 ){
obSat = obDone;
@@ -154528,25 +154528,25 @@ static i8 wherePathSatisfiesOrderBy(
if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) continue;
if( pOBExpr->iTable!=iCur ) continue;
pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
- ~ready, eqOpMask, 0);
+ ~ready, eqOpMask, 0);
if( pTerm==0 ) continue;
- if( pTerm->eOperator==WO_IN ){
+ if( pTerm->eOperator==WO_IN ){
/* IN terms are only valid for sorting in the ORDER BY LIMIT
- ** optimization, and then only if they are actually used
- ** by the query plan */
+ ** optimization, and then only if they are actually used
+ ** by the query plan */
assert( wctrlFlags &
(WHERE_ORDERBY_LIMIT|WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) );
- for(j=0; j<pLoop->nLTerm && pTerm!=pLoop->aLTerm[j]; j++){}
- if( j>=pLoop->nLTerm ) continue;
- }
+ for(j=0; j<pLoop->nLTerm && pTerm!=pLoop->aLTerm[j]; j++){}
+ if( j>=pLoop->nLTerm ) continue;
+ }
if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){
Parse *pParse = pWInfo->pParse;
CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[i].pExpr);
CollSeq *pColl2 = sqlite3ExprCompareCollSeq(pParse, pTerm->pExpr);
assert( pColl1 );
if( pColl2==0 || sqlite3StrICmp(pColl1->zName, pColl2->zName) ){
- continue;
- }
+ continue;
+ }
testcase( pTerm->pExpr->op==TK_IS );
}
obSat |= MASKBIT(i);
@@ -154563,8 +154563,8 @@ static i8 wherePathSatisfiesOrderBy(
nKeyCol = pIndex->nKeyCol;
nColumn = pIndex->nColumn;
assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) );
- assert( pIndex->aiColumn[nColumn-1]==XN_ROWID
- || !HasRowid(pIndex->pTable));
+ assert( pIndex->aiColumn[nColumn-1]==XN_ROWID
+ || !HasRowid(pIndex->pTable));
/* All relevant terms of the index must also be non-NULL in order
** for isOrderDistinct to be true. So the isOrderDistint value
** computed here might be a false positive. Corrections will be
@@ -154579,47 +154579,47 @@ static i8 wherePathSatisfiesOrderBy(
rev = revSet = 0;
distinctColumns = 0;
for(j=0; j<nColumn; j++){
- u8 bOnce = 1; /* True to run the ORDER BY search loop */
+ u8 bOnce = 1; /* True to run the ORDER BY search loop */
assert( j>=pLoop->u.btree.nEq
- || (pLoop->aLTerm[j]==0)==(j<pLoop->nSkip)
- );
- if( j<pLoop->u.btree.nEq && j>=pLoop->nSkip ){
- u16 eOp = pLoop->aLTerm[j]->eOperator;
-
- /* Skip over == and IS and ISNULL terms. (Also skip IN terms when
+ || (pLoop->aLTerm[j]==0)==(j<pLoop->nSkip)
+ );
+ if( j<pLoop->u.btree.nEq && j>=pLoop->nSkip ){
+ u16 eOp = pLoop->aLTerm[j]->eOperator;
+
+ /* Skip over == and IS and ISNULL terms. (Also skip IN terms when
** doing WHERE_ORDERBY_LIMIT processing). Except, IS and ISNULL
** terms imply that the index is not UNIQUE NOT NULL in which case
** the loop need to be marked as not order-distinct because it can
** have repeated NULL rows.
- **
+ **
** If the current term is a column of an ((?,?) IN (SELECT...))
- ** expression for which the SELECT returns more than one column,
- ** check that it is the only column used by this loop. Otherwise,
- ** if it is one of two or more, none of the columns can be
+ ** expression for which the SELECT returns more than one column,
+ ** check that it is the only column used by this loop. Otherwise,
+ ** if it is one of two or more, none of the columns can be
** considered to match an ORDER BY term.
*/
- if( (eOp & eqOpMask)!=0 ){
+ if( (eOp & eqOpMask)!=0 ){
if( eOp & (WO_ISNULL|WO_IS) ){
testcase( eOp & WO_ISNULL );
testcase( eOp & WO_IS );
- testcase( isOrderDistinct );
- isOrderDistinct = 0;
- }
+ testcase( isOrderDistinct );
+ isOrderDistinct = 0;
+ }
continue;
- }else if( ALWAYS(eOp & WO_IN) ){
- /* ALWAYS() justification: eOp is an equality operator due to the
- ** j<pLoop->u.btree.nEq constraint above. Any equality other
- ** than WO_IN is captured by the previous "if". So this one
- ** always has to be WO_IN. */
- Expr *pX = pLoop->aLTerm[j]->pExpr;
- for(i=j+1; i<pLoop->u.btree.nEq; i++){
- if( pLoop->aLTerm[i]->pExpr==pX ){
- assert( (pLoop->aLTerm[i]->eOperator & WO_IN) );
- bOnce = 0;
- break;
- }
- }
+ }else if( ALWAYS(eOp & WO_IN) ){
+ /* ALWAYS() justification: eOp is an equality operator due to the
+ ** j<pLoop->u.btree.nEq constraint above. Any equality other
+ ** than WO_IN is captured by the previous "if". So this one
+ ** always has to be WO_IN. */
+ Expr *pX = pLoop->aLTerm[j]->pExpr;
+ for(i=j+1; i<pLoop->u.btree.nEq; i++){
+ if( pLoop->aLTerm[i]->pExpr==pX ){
+ assert( (pLoop->aLTerm[i]->eOperator & WO_IN) );
+ bOnce = 0;
+ break;
+ }
+ }
}
}
@@ -154629,9 +154629,9 @@ static i8 wherePathSatisfiesOrderBy(
if( pIndex ){
iColumn = pIndex->aiColumn[j];
revIdx = pIndex->aSortOrder[j] & KEYINFO_ORDER_DESC;
- if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID;
+ if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID;
}else{
- iColumn = XN_ROWID;
+ iColumn = XN_ROWID;
revIdx = 0;
}
@@ -154661,18 +154661,18 @@ static i8 wherePathSatisfiesOrderBy(
testcase( wctrlFlags & WHERE_DISTINCTBY );
if( NEVER(pOBExpr==0) ) continue;
if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
- if( iColumn>=XN_ROWID ){
+ if( iColumn>=XN_ROWID ){
if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) continue;
- if( pOBExpr->iTable!=iCur ) continue;
- if( pOBExpr->iColumn!=iColumn ) continue;
- }else{
- Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr;
- if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){
- continue;
- }
- }
- if( iColumn!=XN_ROWID ){
- pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+ if( pOBExpr->iTable!=iCur ) continue;
+ if( pOBExpr->iColumn!=iColumn ) continue;
+ }else{
+ Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr;
+ if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){
+ continue;
+ }
+ }
+ if( iColumn!=XN_ROWID ){
+ pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
}
if( wctrlFlags & WHERE_DISTINCTBY ){
@@ -154702,7 +154702,7 @@ static i8 wherePathSatisfiesOrderBy(
}
}
if( isMatch ){
- if( iColumn==XN_ROWID ){
+ if( iColumn==XN_ROWID ){
testcase( distinctColumns==0 );
distinctColumns = 1;
}
@@ -154819,21 +154819,21 @@ static LogEst whereSortingCost(
LogEst rScale, rSortCost;
assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
- rSortCost = nRow + rScale + 16;
+ rSortCost = nRow + rScale + 16;
- /* Multiple by log(M) where M is the number of output rows.
+ /* Multiple by log(M) where M is the number of output rows.
** Use the LIMIT for M if it is smaller. Or if this sort is for
** a DISTINCT operator, M will be the number of distinct output
** rows, so fudge it downwards a bit.
*/
- if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){
- nRow = pWInfo->iLimit;
+ if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){
+ nRow = pWInfo->iLimit;
}else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){
/* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT
** reduces the number of output rows by a factor of 2 */
if( nRow>10 ){ nRow -= 10; assert( 10==sqlite3LogEst(2) ); }
}
- rSortCost += estLog(nRow);
+ rSortCost += estLog(nRow);
return rSortCost;
}
@@ -154895,8 +154895,8 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
/* Allocate and initialize space for aTo, aFrom and aSortCost[] */
nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
nSpace += sizeof(LogEst) * nOrderBy;
- pSpace = sqlite3DbMallocRawNN(db, nSpace);
- if( pSpace==0 ) return SQLITE_NOMEM_BKPT;
+ pSpace = sqlite3DbMallocRawNN(db, nSpace);
+ if( pSpace==0 ) return SQLITE_NOMEM_BKPT;
aTo = (WherePath*)pSpace;
aFrom = aTo+mxChoice;
memset(aFrom, 0, sizeof(aFrom[0]));
@@ -154952,13 +154952,13 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){
- /* Do not use an automatic index if the this loop is expected
+ /* Do not use an automatic index if the this loop is expected
** to run less than 1.25 times. It is tempting to also exclude
** automatic index usage on an outer loop, but sometimes an automatic
** index is useful in the outer loop of a correlated subquery. */
- assert( 10==sqlite3LogEst(2) );
- continue;
- }
+ assert( 10==sqlite3LogEst(2) );
+ continue;
+ }
/* At this point, pWLoop is a candidate to be the next loop.
** Compute its cost */
@@ -154991,7 +154991,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
rUnsorted, rCost));
}else{
rCost = rUnsorted;
- rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */
+ rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */
}
/* Check to see if pWLoop should be added to the set of
@@ -155023,8 +155023,8 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
** this candidate as not viable. */
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
- sqlite3DebugPrintf("Skip %s cost=%-3d,%3d,%3d order=%c\n",
- wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
+ sqlite3DebugPrintf("Skip %s cost=%-3d,%3d,%3d order=%c\n",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
isOrdered>=0 ? isOrdered+'0' : '?');
}
#endif
@@ -155042,36 +155042,36 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pTo = &aTo[jj];
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
- sqlite3DebugPrintf("New %s cost=%-3d,%3d,%3d order=%c\n",
- wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
+ sqlite3DebugPrintf("New %s cost=%-3d,%3d,%3d order=%c\n",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
isOrdered>=0 ? isOrdered+'0' : '?');
}
#endif
}else{
/* Control reaches here if best-so-far path pTo=aTo[jj] covers the
- ** same set of loops and has the same isOrdered setting as the
+ ** same set of loops and has the same isOrdered setting as the
** candidate path. Check to see if the candidate should replace
- ** pTo or if the candidate should be skipped.
+ ** pTo or if the candidate should be skipped.
**
- ** The conditional is an expanded vector comparison equivalent to:
- ** (pTo->rCost,pTo->nRow,pTo->rUnsorted) <= (rCost,nOut,rUnsorted)
- */
+ ** The conditional is an expanded vector comparison equivalent to:
+ ** (pTo->rCost,pTo->nRow,pTo->rUnsorted) <= (rCost,nOut,rUnsorted)
+ */
if( pTo->rCost<rCost
- || (pTo->rCost==rCost
- && (pTo->nRow<nOut
- || (pTo->nRow==nOut && pTo->rUnsorted<=rUnsorted)
- )
- )
- ){
+ || (pTo->rCost==rCost
+ && (pTo->nRow<nOut
+ || (pTo->nRow==nOut && pTo->rUnsorted<=rUnsorted)
+ )
+ )
+ ){
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf(
- "Skip %s cost=%-3d,%3d,%3d order=%c",
- wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
+ "Skip %s cost=%-3d,%3d,%3d order=%c",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
isOrdered>=0 ? isOrdered+'0' : '?');
- sqlite3DebugPrintf(" vs %s cost=%-3d,%3d,%3d order=%c\n",
+ sqlite3DebugPrintf(" vs %s cost=%-3d,%3d,%3d order=%c\n",
wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
- pTo->rUnsorted, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
+ pTo->rUnsorted, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
}
#endif
/* Discard the candidate path from further consideration */
@@ -155084,12 +155084,12 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf(
- "Update %s cost=%-3d,%3d,%3d order=%c",
- wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
+ "Update %s cost=%-3d,%3d,%3d order=%c",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
isOrdered>=0 ? isOrdered+'0' : '?');
- sqlite3DebugPrintf(" was %s cost=%-3d,%3d,%3d order=%c\n",
+ sqlite3DebugPrintf(" was %s cost=%-3d,%3d,%3d order=%c\n",
wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
- pTo->rUnsorted, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
+ pTo->rUnsorted, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
}
#endif
}
@@ -155144,7 +155144,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
if( nFrom==0 ){
sqlite3ErrorMsg(pParse, "no query solution");
- sqlite3DbFreeNN(db, pSpace);
+ sqlite3DbFreeNN(db, pSpace);
return SQLITE_ERROR;
}
@@ -155182,30 +155182,30 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
}else{
pWInfo->nOBSat = pFrom->isOrdered;
pWInfo->revMask = pFrom->revLoop;
- if( pWInfo->nOBSat<=0 ){
- pWInfo->nOBSat = 0;
- if( nLoop>0 ){
- u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
+ if( pWInfo->nOBSat<=0 ){
+ pWInfo->nOBSat = 0;
+ if( nLoop>0 ){
+ u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
if( (wsFlags & WHERE_ONEROW)==0
- && (wsFlags&(WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN)
- ){
- Bitmask m = 0;
- int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
- WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m);
- testcase( wsFlags & WHERE_IPK );
- testcase( wsFlags & WHERE_COLUMN_IN );
- if( rc==pWInfo->pOrderBy->nExpr ){
- pWInfo->bOrderedInnerLoop = 1;
- pWInfo->revMask = m;
- }
- }
- }
+ && (wsFlags&(WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN)
+ ){
+ Bitmask m = 0;
+ int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
+ WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m);
+ testcase( wsFlags & WHERE_IPK );
+ testcase( wsFlags & WHERE_COLUMN_IN );
+ if( rc==pWInfo->pOrderBy->nExpr ){
+ pWInfo->bOrderedInnerLoop = 1;
+ pWInfo->revMask = m;
+ }
+ }
+ }
}else if( nLoop
&& pWInfo->nOBSat==1
&& (pWInfo->wctrlFlags & (WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX))!=0
){
pWInfo->bOrderedInnerLoop = 1;
- }
+ }
}
if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
&& pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0
@@ -155226,7 +155226,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pWInfo->nRowOut = pFrom->nRow;
/* Free temporary memory and return success */
- sqlite3DbFreeNN(db, pSpace);
+ sqlite3DbFreeNN(db, pSpace);
return SQLITE_OK;
}
@@ -155252,14 +155252,14 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
Table *pTab;
Index *pIdx;
WhereScan scan;
-
+
pWInfo = pBuilder->pWInfo;
- if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0;
+ if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0;
assert( pWInfo->pTabList->nSrc>=1 );
pItem = pWInfo->pTabList->a;
pTab = pItem->pTab;
if( IsVirtual(pTab) ) return 0;
- if( pItem->fg.isIndexedBy ) return 0;
+ if( pItem->fg.isIndexedBy ) return 0;
iCur = pItem->iCursor;
pWC = &pWInfo->sWC;
pLoop = pBuilder->pNew;
@@ -155307,8 +155307,8 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
if( pLoop->wsFlags ){
pLoop->nOut = (LogEst)1;
pWInfo->a[0].pWLoop = pLoop;
- assert( pWInfo->sMaskSet.n==1 && iCur==pWInfo->sMaskSet.ix[0] );
- pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */
+ assert( pWInfo->sMaskSet.n==1 && iCur==pWInfo->sMaskSet.ix[0] );
+ pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */
pWInfo->a[0].iTabCur = iCur;
pWInfo->nRowOut = 1;
if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr;
@@ -155330,34 +155330,34 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
}
/*
-** Helper function for exprIsDeterministic().
-*/
-static int exprNodeIsDeterministic(Walker *pWalker, Expr *pExpr){
- if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_ConstFunc)==0 ){
- pWalker->eCode = 0;
- return WRC_Abort;
- }
- return WRC_Continue;
-}
-
-/*
+** Helper function for exprIsDeterministic().
+*/
+static int exprNodeIsDeterministic(Walker *pWalker, Expr *pExpr){
+ if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_ConstFunc)==0 ){
+ pWalker->eCode = 0;
+ return WRC_Abort;
+ }
+ return WRC_Continue;
+}
+
+/*
** Return true if the expression contains no non-deterministic SQL
** functions. Do not consider non-deterministic SQL functions that are
-** part of sub-select statements.
-*/
-static int exprIsDeterministic(Expr *p){
- Walker w;
- memset(&w, 0, sizeof(w));
- w.eCode = 1;
- w.xExprCallback = exprNodeIsDeterministic;
- w.xSelectCallback = sqlite3SelectWalkFail;
- sqlite3WalkExpr(&w, p);
- return w.eCode;
-}
-
+** part of sub-select statements.
+*/
+static int exprIsDeterministic(Expr *p){
+ Walker w;
+ memset(&w, 0, sizeof(w));
+ w.eCode = 1;
+ w.xExprCallback = exprNodeIsDeterministic;
+ w.xSelectCallback = sqlite3SelectWalkFail;
+ sqlite3WalkExpr(&w, p);
+ return w.eCode;
+}
+
#ifdef WHERETRACE_ENABLED
-/*
+/*
** Display all WhereLoops in pWInfo
*/
static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){
@@ -155458,7 +155458,7 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){
** is called from an UPDATE or DELETE statement, then pOrderBy is NULL.
**
** The iIdxCur parameter is the cursor number of an index. If
-** WHERE_OR_SUBCLAUSE is set, iIdxCur is the cursor number of an index
+** WHERE_OR_SUBCLAUSE is set, iIdxCur is the cursor number of an index
** to use for OR clause processing. The WHERE clause should use this
** specific cursor. If WHERE_ONEPASS_DESIRED is set, then iIdxCur is
** the first cursor in an array of cursors for all indices. iIdxCur should
@@ -155466,14 +155466,14 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){
** used.
*/
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
- Parse *pParse, /* The parser context */
- SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
- Expr *pWhere, /* The WHERE clause */
- ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
- ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
- u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
- int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
- ** If WHERE_USE_LIMIT, then the limit amount */
+ Parse *pParse, /* The parser context */
+ SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
+ Expr *pWhere, /* The WHERE clause */
+ ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
+ ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
+ u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
+ int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
+ ** If WHERE_USE_LIMIT, then the limit amount */
){
int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
int nTabList; /* Number of elements in pTabList */
@@ -155487,17 +155487,17 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
int ii; /* Loop counter */
sqlite3 *db; /* Database connection */
int rc; /* Return code */
- u8 bFordelete = 0; /* OPFLAG_FORDELETE or zero, as appropriate */
+ u8 bFordelete = 0; /* OPFLAG_FORDELETE or zero, as appropriate */
- assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || (
+ assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || (
(wctrlFlags & WHERE_ONEPASS_DESIRED)!=0
&& (wctrlFlags & WHERE_OR_SUBCLAUSE)==0
- ));
+ ));
+
+ /* Only one of WHERE_OR_SUBCLAUSE or WHERE_USE_LIMIT */
+ assert( (wctrlFlags & WHERE_OR_SUBCLAUSE)==0
+ || (wctrlFlags & WHERE_USE_LIMIT)==0 );
- /* Only one of WHERE_OR_SUBCLAUSE or WHERE_USE_LIMIT */
- assert( (wctrlFlags & WHERE_OR_SUBCLAUSE)==0
- || (wctrlFlags & WHERE_USE_LIMIT)==0 );
-
/* Variable initialization */
db = pParse->db;
memset(&sWLB, 0, sizeof(sWLB));
@@ -155523,11 +155523,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
}
/* This function normally generates a nested loop for all tables in
- ** pTabList. But if the WHERE_OR_SUBCLAUSE flag is set, then we should
+ ** pTabList. But if the WHERE_OR_SUBCLAUSE flag is set, then we should
** only generate code for the first table in pTabList and assume that
** any cursors associated with subsequent tables are uninitialized.
*/
- nTabList = (wctrlFlags & WHERE_OR_SUBCLAUSE) ? 1 : pTabList->nSrc;
+ nTabList = (wctrlFlags & WHERE_OR_SUBCLAUSE) ? 1 : pTabList->nSrc;
/* Allocate and initialize the WhereInfo structure that will become the
** return value. A single allocation is used to store the WhereInfo
@@ -155537,7 +155537,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
** some architectures. Hence the ROUND8() below.
*/
nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
- pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
+ pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
if( db->mallocFailed ){
sqlite3DbFree(db, pWInfo);
pWInfo = 0;
@@ -155546,18 +155546,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
pWInfo->pOrderBy = pOrderBy;
- pWInfo->pWhere = pWhere;
+ pWInfo->pWhere = pWhere;
pWInfo->pResultSet = pResultSet;
- pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
- pWInfo->nLevel = nTabList;
+ pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
+ pWInfo->nLevel = nTabList;
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse);
pWInfo->wctrlFlags = wctrlFlags;
- pWInfo->iLimit = iAuxArg;
+ pWInfo->iLimit = iAuxArg;
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
memset(&pWInfo->nOBSat, 0,
- offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
- memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
- assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
+ offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
+ memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
+ assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
pMaskSet = &pWInfo->sMaskSet;
sWLB.pWInfo = pWInfo;
sWLB.pWC = &pWInfo->sWC;
@@ -155583,59 +155583,59 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
}
ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
- }else{
- /* Assign a bit from the bitmask to every term in the FROM clause.
- **
- ** The N-th term of the FROM clause is assigned a bitmask of 1<<N.
- **
- ** The rule of the previous sentence ensures thta if X is the bitmask for
- ** a table T, then X-1 is the bitmask for all other tables to the left of T.
- ** Knowing the bitmask for all tables to the left of a left join is
- ** important. Ticket #3015.
- **
- ** Note that bitmasks are created for all pTabList->nSrc tables in
- ** pTabList, not just the first nTabList tables. nTabList is normally
- ** equal to pTabList->nSrc but might be shortened to 1 if the
- ** WHERE_OR_SUBCLAUSE flag is set.
- */
- ii = 0;
- do{
- createMask(pMaskSet, pTabList->a[ii].iCursor);
- sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC);
- }while( (++ii)<pTabList->nSrc );
- #ifdef SQLITE_DEBUG
- {
- Bitmask mx = 0;
- for(ii=0; ii<pTabList->nSrc; ii++){
- Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor);
- assert( m>=mx );
- mx = m;
- }
- }
- #endif
- }
-
- /* Analyze all of the subexpressions. */
- sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
- if( db->mallocFailed ) goto whereBeginError;
-
- /* Special case: WHERE terms that do not refer to any tables in the join
- ** (constant expressions). Evaluate each such term, and jump over all the
+ }else{
+ /* Assign a bit from the bitmask to every term in the FROM clause.
+ **
+ ** The N-th term of the FROM clause is assigned a bitmask of 1<<N.
+ **
+ ** The rule of the previous sentence ensures thta if X is the bitmask for
+ ** a table T, then X-1 is the bitmask for all other tables to the left of T.
+ ** Knowing the bitmask for all tables to the left of a left join is
+ ** important. Ticket #3015.
+ **
+ ** Note that bitmasks are created for all pTabList->nSrc tables in
+ ** pTabList, not just the first nTabList tables. nTabList is normally
+ ** equal to pTabList->nSrc but might be shortened to 1 if the
+ ** WHERE_OR_SUBCLAUSE flag is set.
+ */
+ ii = 0;
+ do{
+ createMask(pMaskSet, pTabList->a[ii].iCursor);
+ sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC);
+ }while( (++ii)<pTabList->nSrc );
+ #ifdef SQLITE_DEBUG
+ {
+ Bitmask mx = 0;
+ for(ii=0; ii<pTabList->nSrc; ii++){
+ Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor);
+ assert( m>=mx );
+ mx = m;
+ }
+ }
+ #endif
+ }
+
+ /* Analyze all of the subexpressions. */
+ sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
+ if( db->mallocFailed ) goto whereBeginError;
+
+ /* Special case: WHERE terms that do not refer to any tables in the join
+ ** (constant expressions). Evaluate each such term, and jump over all the
** generated code if the result is not true.
**
- ** Do not do this if the expression contains non-deterministic functions
- ** that are not within a sub-select. This is not strictly required, but
- ** preserves SQLite's legacy behaviour in the following two cases:
+ ** Do not do this if the expression contains non-deterministic functions
+ ** that are not within a sub-select. This is not strictly required, but
+ ** preserves SQLite's legacy behaviour in the following two cases:
**
- ** FROM ... WHERE random()>0; -- eval random() once per row
- ** FROM ... WHERE (SELECT random())>0; -- eval random() once overall
+ ** FROM ... WHERE random()>0; -- eval random() once per row
+ ** FROM ... WHERE (SELECT random())>0; -- eval random() once overall
*/
- for(ii=0; ii<sWLB.pWC->nTerm; ii++){
- WhereTerm *pT = &sWLB.pWC->a[ii];
+ for(ii=0; ii<sWLB.pWC->nTerm; ii++){
+ WhereTerm *pT = &sWLB.pWC->a[ii];
if( pT->wtFlags & TERM_VIRTUAL ) continue;
- if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){
- sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL);
- pT->wtFlags |= TERM_CODED;
+ if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){
+ sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL);
+ pT->wtFlags |= TERM_CODED;
}
}
@@ -155652,12 +155652,12 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
/* Construct the WhereLoop objects */
#if defined(WHERETRACE_ENABLED)
- if( sqlite3WhereTrace & 0xffff ){
- sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags);
- if( wctrlFlags & WHERE_USE_LIMIT ){
- sqlite3DebugPrintf(", limit: %d", iAuxArg);
+ if( sqlite3WhereTrace & 0xffff ){
+ sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags);
+ if( wctrlFlags & WHERE_USE_LIMIT ){
+ sqlite3DebugPrintf(", limit: %d", iAuxArg);
}
- sqlite3DebugPrintf(")\n");
+ sqlite3DebugPrintf(")\n");
if( sqlite3WhereTrace & 0x100 ){
Select sSelect;
memset(&sSelect, 0, sizeof(sSelect));
@@ -155669,10 +155669,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
sqlite3TreeViewSelect(0, &sSelect, 0);
}
}
- if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
+ if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n");
- sqlite3WhereClausePrint(sWLB.pWC);
- }
+ sqlite3WhereClausePrint(sWLB.pWC);
+ }
#endif
if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
@@ -155709,7 +155709,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
}
}
if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
- pWInfo->revMask = ALLBITS;
+ pWInfo->revMask = ALLBITS;
}
if( pParse->nErr || db->mallocFailed ){
goto whereBeginError;
@@ -155740,81 +155740,81 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
}
}
#endif
-
- /* Attempt to omit tables from the join that do not affect the result.
- ** For a table to not affect the result, the following must be true:
- **
- ** 1) The query must not be an aggregate.
- ** 2) The table must be the RHS of a LEFT JOIN.
- ** 3) Either the query must be DISTINCT, or else the ON or USING clause
+
+ /* Attempt to omit tables from the join that do not affect the result.
+ ** For a table to not affect the result, the following must be true:
+ **
+ ** 1) The query must not be an aggregate.
+ ** 2) The table must be the RHS of a LEFT JOIN.
+ ** 3) Either the query must be DISTINCT, or else the ON or USING clause
** must contain a constraint that limits the scan of the table to
- ** at most a single row.
- ** 4) The table must not be referenced by any part of the query apart
- ** from its own USING or ON clause.
- **
- ** For example, given:
- **
- ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
- ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
- ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);
- **
- ** then table t2 can be omitted from the following:
- **
+ ** at most a single row.
+ ** 4) The table must not be referenced by any part of the query apart
+ ** from its own USING or ON clause.
+ **
+ ** For example, given:
+ **
+ ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
+ ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
+ ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);
+ **
+ ** then table t2 can be omitted from the following:
+ **
** SELECT v1, v3 FROM t1
** LEFT JOIN t2 ON (t1.ipk=t2.ipk)
** LEFT JOIN t3 ON (t1.ipk=t3.ipk)
- **
- ** or from:
- **
+ **
+ ** or from:
+ **
** SELECT DISTINCT v1, v3 FROM t1
- ** LEFT JOIN t2
+ ** LEFT JOIN t2
** LEFT JOIN t3 ON (t1.ipk=t3.ipk)
- */
- notReady = ~(Bitmask)0;
+ */
+ notReady = ~(Bitmask)0;
if( pWInfo->nLevel>=2
&& pResultSet!=0 /* these two combine to guarantee */
&& 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
){
- int i;
+ int i;
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
if( sWLB.pOrderBy ){
tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
}
- for(i=pWInfo->nLevel-1; i>=1; i--){
+ for(i=pWInfo->nLevel-1; i>=1; i--){
WhereTerm *pTerm, *pEnd;
SrcItem *pItem;
- pLoop = pWInfo->a[i].pWLoop;
- pItem = &pWInfo->pTabList->a[pLoop->iTab];
- if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
+ pLoop = pWInfo->a[i].pWLoop;
+ pItem = &pWInfo->pTabList->a[pLoop->iTab];
+ if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
&& (pLoop->wsFlags & WHERE_ONEROW)==0
){
- continue;
+ continue;
}
- if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
+ if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
pEnd = sWLB.pWC->a + sWLB.pWC->nTerm;
for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
- if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
- if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
- || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
- ){
- break;
- }
+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
+ if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+ || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
+ ){
+ break;
+ }
}
}
- if( pTerm<pEnd ) continue;
+ if( pTerm<pEnd ) continue;
WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
- notReady &= ~pLoop->maskSelf;
- for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
- if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
- pTerm->wtFlags |= TERM_CODED;
- }
- }
- if( i!=pWInfo->nLevel-1 ){
- int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel);
- memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte);
- }
+ notReady &= ~pLoop->maskSelf;
+ for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
+ pTerm->wtFlags |= TERM_CODED;
+ }
+ }
+ if( i!=pWInfo->nLevel-1 ){
+ int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel);
+ memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte);
+ }
pWInfo->nLevel--;
nTabList--;
}
@@ -155830,40 +155830,40 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
/* If the caller is an UPDATE or DELETE statement that is requesting
** to use a one-pass algorithm, determine if this is appropriate.
- **
- ** A one-pass approach can be used if the caller has requested one
- ** and either (a) the scan visits at most one row or (b) each
- ** of the following are true:
- **
- ** * the caller has indicated that a one-pass approach can be used
- ** with multiple rows (by setting WHERE_ONEPASS_MULTIROW), and
- ** * the table is not a virtual table, and
- ** * either the scan does not use the OR optimization or the caller
- ** is a DELETE operation (WHERE_DUPLICATES_OK is only specified
- ** for DELETE).
- **
- ** The last qualification is because an UPDATE statement uses
- ** WhereInfo.aiCurOnePass[1] to determine whether or not it really can
- ** use a one-pass approach, and this is not set accurately for scans
- ** that use the OR optimization.
+ **
+ ** A one-pass approach can be used if the caller has requested one
+ ** and either (a) the scan visits at most one row or (b) each
+ ** of the following are true:
+ **
+ ** * the caller has indicated that a one-pass approach can be used
+ ** with multiple rows (by setting WHERE_ONEPASS_MULTIROW), and
+ ** * the table is not a virtual table, and
+ ** * either the scan does not use the OR optimization or the caller
+ ** is a DELETE operation (WHERE_DUPLICATES_OK is only specified
+ ** for DELETE).
+ **
+ ** The last qualification is because an UPDATE statement uses
+ ** WhereInfo.aiCurOnePass[1] to determine whether or not it really can
+ ** use a one-pass approach, and this is not set accurately for scans
+ ** that use the OR optimization.
*/
assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
- if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
- int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
- int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
+ if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
+ int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
+ int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) );
- if( bOnerow || (
- 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
+ if( bOnerow || (
+ 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
&& !IsVirtual(pTabList->a[0].pTab)
- && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
- )){
- pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
- if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
- if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
- bFordelete = OPFLAG_FORDELETE;
- }
- pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY);
- }
+ && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
+ )){
+ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
+ if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
+ if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
+ bFordelete = OPFLAG_FORDELETE;
+ }
+ pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY);
+ }
}
}
@@ -155892,16 +155892,16 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
}else
#endif
if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
- && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
+ && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
int op = OP_OpenRead;
- if( pWInfo->eOnePass!=ONEPASS_OFF ){
+ if( pWInfo->eOnePass!=ONEPASS_OFF ){
op = OP_OpenWrite;
pWInfo->aiCurOnePass[0] = pTabItem->iCursor;
};
sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
assert( pTabItem->iCursor==pLevel->iTabCur );
- testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
- testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
+ testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
+ testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
if( pWInfo->eOnePass==ONEPASS_OFF
&& pTab->nCol<BMS
&& (pTab->tabFlags & (TF_HasGenerated|TF_WithoutRowid))==0
@@ -155912,17 +155912,17 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
Bitmask b = pTabItem->colUsed;
int n = 0;
for(; b; b=b>>1, n++){}
- sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(n), P4_INT32);
+ sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(n), P4_INT32);
assert( n<=pTab->nCol );
}
-#ifdef SQLITE_ENABLE_CURSOR_HINTS
- if( pLoop->u.btree.pIndex!=0 ){
- sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete);
- }else
-#endif
- {
- sqlite3VdbeChangeP5(v, bFordelete);
- }
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+ if( pLoop->u.btree.pIndex!=0 ){
+ sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete);
+ }else
+#endif
+ {
+ sqlite3VdbeChangeP5(v, bFordelete);
+ }
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0,
(const u8*)&pTabItem->colUsed, P4_INT64);
@@ -155934,18 +155934,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
Index *pIx = pLoop->u.btree.pIndex;
int iIndexCur;
int op = OP_OpenRead;
- /* iAuxArg is always set to a positive value if ONEPASS is possible */
- assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
+ /* iAuxArg is always set to a positive value if ONEPASS is possible */
+ assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx)
- && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0
+ && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0
){
/* This is one term of an OR-optimization using the PRIMARY KEY of a
** WITHOUT ROWID table. No need for a separate index */
iIndexCur = pLevel->iTabCur;
op = 0;
- }else if( pWInfo->eOnePass!=ONEPASS_OFF ){
+ }else if( pWInfo->eOnePass!=ONEPASS_OFF ){
Index *pJ = pTabItem->pTab->pIndex;
- iIndexCur = iAuxArg;
+ iIndexCur = iAuxArg;
assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
while( ALWAYS(pJ) && pJ!=pIx ){
iIndexCur++;
@@ -155953,9 +155953,9 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
}
op = OP_OpenWrite;
pWInfo->aiCurOnePass[1] = iIndexCur;
- }else if( iAuxArg && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){
- iIndexCur = iAuxArg;
- op = OP_ReopenIdx;
+ }else if( iAuxArg && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){
+ iIndexCur = iAuxArg;
+ op = OP_ReopenIdx;
}else{
iIndexCur = pParse->nTab++;
}
@@ -155970,7 +155970,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
&& (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0
&& (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0
&& (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
- && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
+ && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
){
sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ);
}
@@ -156020,7 +156020,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady);
pWInfo->iContinue = pLevel->addrCont;
- if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){
+ if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){
sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain);
}
}
@@ -156083,32 +156083,32 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
pLevel = &pWInfo->a[i];
pLoop = pLevel->pWLoop;
if( pLevel->op!=OP_Noop ){
-#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
- int addrSeek = 0;
- Index *pIdx;
- int n;
- if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
- && i==pWInfo->nLevel-1 /* Ticket [ef9318757b152e3] 2017-10-21 */
- && (pLoop->wsFlags & WHERE_INDEXED)!=0
- && (pIdx = pLoop->u.btree.pIndex)->hasStat1
+#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
+ int addrSeek = 0;
+ Index *pIdx;
+ int n;
+ if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
+ && i==pWInfo->nLevel-1 /* Ticket [ef9318757b152e3] 2017-10-21 */
+ && (pLoop->wsFlags & WHERE_INDEXED)!=0
+ && (pIdx = pLoop->u.btree.pIndex)->hasStat1
&& (n = pLoop->u.btree.nDistinctCol)>0
- && pIdx->aiRowLogEst[n]>=36
- ){
- int r1 = pParse->nMem+1;
- int j, op;
- for(j=0; j<n; j++){
- sqlite3VdbeAddOp3(v, OP_Column, pLevel->iIdxCur, j, r1+j);
- }
- pParse->nMem += n+1;
- op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT;
- addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n);
- VdbeCoverageIf(v, op==OP_SeekLT);
- VdbeCoverageIf(v, op==OP_SeekGT);
- sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
- }
-#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
- /* The common case: Advance to the next row */
- sqlite3VdbeResolveLabel(v, pLevel->addrCont);
+ && pIdx->aiRowLogEst[n]>=36
+ ){
+ int r1 = pParse->nMem+1;
+ int j, op;
+ for(j=0; j<n; j++){
+ sqlite3VdbeAddOp3(v, OP_Column, pLevel->iIdxCur, j, r1+j);
+ }
+ pParse->nMem += n+1;
+ op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT;
+ addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n);
+ VdbeCoverageIf(v, op==OP_SeekLT);
+ VdbeCoverageIf(v, op==OP_SeekGT);
+ sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
+ }
+#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
+ /* The common case: Advance to the next row */
+ sqlite3VdbeResolveLabel(v, pLevel->addrCont);
sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
sqlite3VdbeChangeP5(v, pLevel->p5);
VdbeCoverage(v);
@@ -156120,11 +156120,11 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1);
VdbeCoverage(v);
}
-#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
- if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
-#endif
- }else{
- sqlite3VdbeResolveLabel(v, pLevel->addrCont);
+#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
+ if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
+#endif
+ }else{
+ sqlite3VdbeResolveLabel(v, pLevel->addrCont);
}
if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){
struct InLoop *pIn;
@@ -156134,7 +156134,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
assert( sqlite3VdbeGetOp(v, pIn->addrInTop+1)->opcode==OP_IsNull
|| pParse->db->mallocFailed );
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
- if( pIn->eEndLoopOp!=OP_Noop ){
+ if( pIn->eEndLoopOp!=OP_Noop ){
if( pIn->nPrefix ){
int bEarlyOut =
(pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
@@ -156164,39 +156164,39 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
}
}
- sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
- VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
+ VdbeCoverage(v);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next);
- }
+ }
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
}
}
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
if( pLevel->addrSkip ){
- sqlite3VdbeGoto(v, pLevel->addrSkip);
+ sqlite3VdbeGoto(v, pLevel->addrSkip);
VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
sqlite3VdbeJumpHere(v, pLevel->addrSkip);
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
}
-#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( pLevel->addrLikeRep ){
- sqlite3VdbeAddOp2(v, OP_DecrJumpZero, (int)(pLevel->iLikeRepCntr>>1),
- pLevel->addrLikeRep);
+ sqlite3VdbeAddOp2(v, OP_DecrJumpZero, (int)(pLevel->iLikeRepCntr>>1),
+ pLevel->addrLikeRep);
VdbeCoverage(v);
}
-#endif
+#endif
if( pLevel->iLeftJoin ){
- int ws = pLoop->wsFlags;
+ int ws = pLoop->wsFlags;
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
- assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 );
- if( (ws & WHERE_IDX_ONLY)==0 ){
- assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor );
- sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
+ assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 );
+ if( (ws & WHERE_IDX_ONLY)==0 ){
+ assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor );
+ sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
}
if( (ws & WHERE_INDEXED)
|| ((ws & WHERE_MULTI_OR) && pLevel->u.pCoveringIdx)
- ){
+ ){
if( ws & WHERE_MULTI_OR ){
Index *pIx = pLevel->u.pCoveringIdx;
int iDb = sqlite3SchemaToIndex(db, pIx->pSchema);
@@ -156208,7 +156208,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
if( pLevel->op==OP_Return ){
sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
}else{
- sqlite3VdbeGoto(v, pLevel->addrFirst);
+ sqlite3VdbeGoto(v, pLevel->addrFirst);
}
sqlite3VdbeJumpHere(v, addr);
}
@@ -156235,10 +156235,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
** the co-routine into OP_Copy of result contained in a register.
** OP_Rowid becomes OP_Null.
*/
- if( pTabItem->fg.viaCoroutine ){
- testcase( pParse->db->mallocFailed );
- translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
- pTabItem->regResult, 0);
+ if( pTabItem->fg.viaCoroutine ){
+ testcase( pParse->db->mallocFailed );
+ translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
+ pTabItem->regResult, 0);
continue;
}
@@ -156281,9 +156281,9 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
}else if( pLoop->wsFlags & WHERE_MULTI_OR ){
pIdx = pLevel->u.pCoveringIdx;
}
- if( pIdx
- && !db->mallocFailed
- ){
+ if( pIdx
+ && !db->mallocFailed
+ ){
if( pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable) ){
last = iEnd;
}else{
@@ -156307,16 +156307,16 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
if( pOp->p1!=pLevel->iTabCur ){
/* no-op */
}else if( pOp->opcode==OP_Column
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
- || pOp->opcode==OP_Offset
-#endif
- ){
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+ || pOp->opcode==OP_Offset
+#endif
+ ){
int x = pOp->p2;
assert( pIdx->pTable==pTab );
if( !HasRowid(pTab) ){
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
x = pPk->aiColumn[x];
- assert( x>=0 );
+ assert( x>=0 );
}else{
testcase( x!=sqlite3StorageColumnToTable(pTab,x) );
x = sqlite3StorageColumnToTable(pTab,x);
@@ -156328,13 +156328,13 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
OpcodeRewriteTrace(db, k, pOp);
}
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0
- || pWInfo->eOnePass );
+ || pWInfo->eOnePass );
}else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur;
pOp->opcode = OP_IdxRowid;
OpcodeRewriteTrace(db, k, pOp);
- }else if( pOp->opcode==OP_IfNullRow ){
- pOp->p1 = pLevel->iIdxCur;
+ }else if( pOp->opcode==OP_IfNullRow ){
+ pOp->p1 = pLevel->iIdxCur;
OpcodeRewriteTrace(db, k, pOp);
}
#ifdef SQLITE_DEBUG
@@ -159467,19 +159467,19 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep(
/************** Begin file parse.c *******************************************/
/* This file is automatically generated by Lemon from input grammar
** source file "parse.y". */
-/*
+/*
** 2001-09-15
**
-** 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.
-**
-*************************************************************************
+** 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 SQLite's SQL parser.
-**
+**
** The canonical source code to this file ("parse.y") is a Lemon grammar
** file that specifies the input grammar and actions to take while parsing.
** That input file is processed by Lemon to generate a C-language
@@ -159502,31 +159502,31 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep(
#define yytestcase(X) testcase(X)
/*
-** Indicate that sqlite3ParserFree() will never be called with a null
-** pointer.
+** Indicate that sqlite3ParserFree() will never be called with a null
+** pointer.
+*/
+#define YYPARSEFREENEVERNULL 1
+
+/*
+** In the amalgamation, the parse.c file generated by lemon and the
+** tokenize.c file are concatenated. In that case, sqlite3RunParser()
+** has access to the the size of the yyParser object and so the parser
+** engine can be allocated from stack. In that case, only the
+** sqlite3ParserInit() and sqlite3ParserFinalize() routines are invoked
+** and the sqlite3ParserAlloc() and sqlite3ParserFree() routines can be
+** omitted.
*/
-#define YYPARSEFREENEVERNULL 1
+#ifdef SQLITE_AMALGAMATION
+# define sqlite3Parser_ENGINEALWAYSONSTACK 1
+#endif
/*
-** In the amalgamation, the parse.c file generated by lemon and the
-** tokenize.c file are concatenated. In that case, sqlite3RunParser()
-** has access to the the size of the yyParser object and so the parser
-** engine can be allocated from stack. In that case, only the
-** sqlite3ParserInit() and sqlite3ParserFinalize() routines are invoked
-** and the sqlite3ParserAlloc() and sqlite3ParserFree() routines can be
-** omitted.
+** Alternative datatype for the argument to the malloc() routine passed
+** into sqlite3ParserAlloc(). The default is size_t.
*/
-#ifdef SQLITE_AMALGAMATION
-# define sqlite3Parser_ENGINEALWAYSONSTACK 1
-#endif
+#define YYMALLOCARGTYPE u64
/*
-** Alternative datatype for the argument to the malloc() routine passed
-** into sqlite3ParserAlloc(). The default is size_t.
-*/
-#define YYMALLOCARGTYPE u64
-
-/*
** An instance of the following structure describes the event of a
** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT,
** TK_DELETE, or TK_INSTEAD. If the event is of the form
@@ -159540,14 +159540,14 @@ struct TrigEvent { int a; IdList * b; };
struct FrameBound { int eType; Expr *pExpr; };
/*
-** Disable lookaside memory allocation for objects that might be
-** shared across database connections.
+** Disable lookaside memory allocation for objects that might be
+** shared across database connections.
*/
-static void disableLookaside(Parse *pParse){
+static void disableLookaside(Parse *pParse){
sqlite3 *db = pParse->db;
- pParse->disableLookaside++;
+ pParse->disableLookaside++;
DisableLookaside;
-}
+}
#if !defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) \
&& defined(SQLITE_UDL_CAPABLE_PARSER)
@@ -159622,15 +159622,15 @@ static void updateDeleteLimitError(
** new Expr to populate pOut. Set the span of pOut to be the identifier
** that created the expression.
*/
- static Expr *tokenExpr(Parse *pParse, int op, Token t){
- Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
- if( p ){
+ static Expr *tokenExpr(Parse *pParse, int op, Token t){
+ Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
+ if( p ){
/* memset(p, 0, sizeof(Expr)); */
- p->op = (u8)op;
+ p->op = (u8)op;
p->affExpr = 0;
- p->flags = EP_Leaf;
+ p->flags = EP_Leaf;
ExprClearVVAProperties(p);
- p->iAgg = -1;
+ p->iAgg = -1;
p->pLeft = p->pRight = 0;
p->pAggInfo = 0;
memset(&p->x, 0, sizeof(p->x));
@@ -159638,20 +159638,20 @@ static void updateDeleteLimitError(
p->op2 = 0;
p->iTable = 0;
p->iColumn = 0;
- p->u.zToken = (char*)&p[1];
- memcpy(p->u.zToken, t.z, t.n);
- p->u.zToken[t.n] = 0;
- if( sqlite3Isquote(p->u.zToken[0]) ){
+ p->u.zToken = (char*)&p[1];
+ memcpy(p->u.zToken, t.z, t.n);
+ p->u.zToken[t.n] = 0;
+ if( sqlite3Isquote(p->u.zToken[0]) ){
sqlite3DequoteExpr(p);
- }
-#if SQLITE_MAX_EXPR_DEPTH>0
- p->nHeight = 1;
+ }
+#if SQLITE_MAX_EXPR_DEPTH>0
+ p->nHeight = 1;
#endif
if( IN_RENAME_OBJECT ){
return (Expr*)sqlite3RenameTokenMap(pParse, (void*)p, &t);
}
- }
- return p;
+ }
+ return p;
}
@@ -159666,33 +159666,33 @@ static void updateDeleteLimitError(
}
}
- /* Add a single new term to an ExprList that is used to store a
- ** list of identifiers. Report an error if the ID list contains
- ** a COLLATE clause or an ASC or DESC keyword, except ignore the
- ** error while parsing a legacy schema.
+ /* Add a single new term to an ExprList that is used to store a
+ ** list of identifiers. Report an error if the ID list contains
+ ** a COLLATE clause or an ASC or DESC keyword, except ignore the
+ ** error while parsing a legacy schema.
*/
- static ExprList *parserAddExprIdListTerm(
- Parse *pParse,
- ExprList *pPrior,
- Token *pIdToken,
- int hasCollate,
- int sortOrder
+ static ExprList *parserAddExprIdListTerm(
+ Parse *pParse,
+ ExprList *pPrior,
+ Token *pIdToken,
+ int hasCollate,
+ int sortOrder
){
- ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0);
- if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED)
- && pParse->db->init.busy==0
- ){
- sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"",
- pIdToken->n, pIdToken->z);
- }
- sqlite3ExprListSetName(pParse, p, pIdToken, 1);
- return p;
+ ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0);
+ if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED)
+ && pParse->db->init.busy==0
+ ){
+ sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"",
+ pIdToken->n, pIdToken->z);
+ }
+ sqlite3ExprListSetName(pParse, p, pIdToken, 1);
+ return p;
}
#if TK_SPAN>255
# error too many tokens in the grammar
#endif
-/**************** End of %include directives **********************************/
+/**************** End of %include directives **********************************/
/* These constants specify the various numeric values for terminal symbols.
***************** Begin token definitions *************************************/
#ifndef TK_SEMI
@@ -159881,36 +159881,36 @@ static void updateDeleteLimitError(
#define TK_ILLEGAL 183
#endif
/**************** End token definitions ***************************************/
-
-/* The next sections is a series of control #defines.
+
+/* The next sections is a series of control #defines.
** various aspects of the generated parser.
-** YYCODETYPE is the data type used to store the integer codes
-** that represent terminal and non-terminal symbols.
-** "unsigned char" is used if there are fewer than
-** 256 symbols. Larger types otherwise.
-** YYNOCODE is a number of type YYCODETYPE that is not used for
-** any terminal or nonterminal symbol.
+** YYCODETYPE is the data type used to store the integer codes
+** that represent terminal and non-terminal symbols.
+** "unsigned char" is used if there are fewer than
+** 256 symbols. Larger types otherwise.
+** YYNOCODE is a number of type YYCODETYPE that is not used for
+** any terminal or nonterminal symbol.
** YYFALLBACK If defined, this indicates that one or more tokens
-** (also known as: "terminal symbols") have fall-back
-** values which should be used if the original symbol
-** would not parse. This permits keywords to sometimes
-** be used as identifiers, for example.
-** YYACTIONTYPE is the data type used for "action codes" - numbers
-** that indicate what to do in response to the next
-** token.
-** sqlite3ParserTOKENTYPE is the data type used for minor type for terminal
-** symbols. Background: A "minor type" is a semantic
-** value associated with a terminal or non-terminal
-** symbols. For example, for an "ID" terminal symbol,
-** the minor type might be the name of the identifier.
-** Each non-terminal can have a different minor type.
-** Terminal symbols all have the same minor type, though.
+** (also known as: "terminal symbols") have fall-back
+** values which should be used if the original symbol
+** would not parse. This permits keywords to sometimes
+** be used as identifiers, for example.
+** YYACTIONTYPE is the data type used for "action codes" - numbers
+** that indicate what to do in response to the next
+** token.
+** sqlite3ParserTOKENTYPE is the data type used for minor type for terminal
+** symbols. Background: A "minor type" is a semantic
+** value associated with a terminal or non-terminal
+** symbols. For example, for an "ID" terminal symbol,
+** the minor type might be the name of the identifier.
+** Each non-terminal can have a different minor type.
+** Terminal symbols all have the same minor type, though.
** This macros defines the minor type for terminal
-** symbols.
-** YYMINORTYPE is the data type used for all minor types.
+** symbols.
+** YYMINORTYPE is the data type used for all minor types.
** This is typically a union of many types, one of
** which is sqlite3ParserTOKENTYPE. The entry in the union
-** for terminal symbols is called "yy0".
+** for terminal symbols is called "yy0".
** YYSTACKDEPTH is the maximum depth of the parser's stack. If
** zero the stack is dynamically sized using realloc()
** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument
@@ -159919,24 +159919,24 @@ static void updateDeleteLimitError(
** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser
** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser
** sqlite3ParserCTX_* As sqlite3ParserARG_ except for %extra_context
-** YYERRORSYMBOL is the code number of the error symbol. If not
-** defined, then do no error processing.
+** YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
** YYNSTATE the combined number of states.
** YYNRULE the number of rules in the grammar
-** YYNTOKEN Number of terminal symbols
-** YY_MAX_SHIFT Maximum value for shift actions
-** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
-** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
-** YY_ERROR_ACTION The yy_action[] code for syntax error
-** YY_ACCEPT_ACTION The yy_action[] code for accept
-** YY_NO_ACTION The yy_action[] code for no-op
-** YY_MIN_REDUCE Minimum value for reduce actions
-** YY_MAX_REDUCE Maximum value for reduce actions
-*/
-#ifndef INTERFACE
-# define INTERFACE 1
-#endif
-/************* Begin control #defines *****************************************/
+** YYNTOKEN Number of terminal symbols
+** YY_MAX_SHIFT Maximum value for shift actions
+** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
+** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
+** YY_ERROR_ACTION The yy_action[] code for syntax error
+** YY_ACCEPT_ACTION The yy_action[] code for accept
+** YY_NO_ACTION The yy_action[] code for no-op
+** YY_MIN_REDUCE Minimum value for reduce actions
+** YY_MAX_REDUCE Maximum value for reduce actions
+*/
+#ifndef INTERFACE
+# define INTERFACE 1
+#endif
+/************* Begin control #defines *****************************************/
#define YYCODETYPE unsigned short int
#define YYNOCODE 318
#define YYACTIONTYPE unsigned short int
@@ -159989,7 +159989,7 @@ typedef union {
#define YY_NO_ACTION 1236
#define YY_MIN_REDUCE 1237
#define YY_MAX_REDUCE 1637
-/************* End control #defines *******************************************/
+/************* End control #defines *******************************************/
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
/* Define the yytestcase() macro to be a no-op if is not already defined
@@ -160013,35 +160013,35 @@ typedef union {
** Suppose the action integer is N. Then the action is determined as
** follows
**
-** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead
+** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead
** token onto the stack and goto state N.
**
-** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
-** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE.
+** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
+** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE.
**
-** N == YY_ERROR_ACTION A syntax error has occurred.
+** N == YY_ERROR_ACTION A syntax error has occurred.
**
-** N == YY_ACCEPT_ACTION The parser accepts its input.
+** N == YY_ACCEPT_ACTION The parser accepts its input.
**
-** N == YY_NO_ACTION No such action. Denotes unused
+** N == YY_NO_ACTION No such action. Denotes unused
** slots in the yy_action[] table.
**
-** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
-** and YY_MAX_REDUCE
-**
+** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
+** and YY_MAX_REDUCE
+**
** The action table is constructed as a single large table named yy_action[].
-** Given state S and lookahead X, the action is computed as either:
+** Given state S and lookahead X, the action is computed as either:
**
-** (A) N = yy_action[ yy_shift_ofst[S] + X ]
-** (B) N = yy_default[S]
+** (A) N = yy_action[ yy_shift_ofst[S] + X ]
+** (B) N = yy_default[S]
**
-** The (A) formula is preferred. The B formula is used instead if
-** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X.
+** The (A) formula is preferred. The B formula is used instead if
+** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X.
**
-** The formulas above are for computing the action when the lookahead is
+** The formulas above are for computing the action when the lookahead is
** a terminal symbol. If the lookahead is a non-terminal (as occurs after
** a reduce action) then the yy_reduce_ofst[] array is used in place of
-** the yy_shift_ofst[] array.
+** the yy_shift_ofst[] array.
**
** The following are the tables generated in this section:
**
@@ -160053,8 +160053,8 @@ typedef union {
** yy_reduce_ofst[] For each state, the offset into yy_action for
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
-**
-*********** Begin parsing tables **********************************************/
+**
+*********** Begin parsing tables **********************************************/
#define YY_ACTTAB_COUNT (2041)
static const YYACTIONTYPE yy_action[] = {
/* 0 */ 568, 115, 112, 220, 169, 199, 115, 112, 220, 568,
@@ -160489,9 +160489,9 @@ static const YYCODETYPE yy_lookahead[] = {
/* 2220 */ 318, 318, 318, 318, 318,
};
#define YY_SHIFT_COUNT (575)
-#define YY_SHIFT_MIN (0)
+#define YY_SHIFT_MIN (0)
#define YY_SHIFT_MAX (2022)
-static const unsigned short int yy_shift_ofst[] = {
+static const unsigned short int yy_shift_ofst[] = {
/* 0 */ 1423, 1409, 1454, 1192, 1192, 610, 1252, 1410, 1517, 1684,
/* 10 */ 1684, 1684, 276, 0, 0, 180, 1015, 1684, 1684, 1684,
/* 20 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684,
@@ -160658,10 +160658,10 @@ static const YYACTIONTYPE yy_default[] = {
/* 560 */ 1234, 1234, 1234, 1234, 1234, 1610, 1326, 1417, 1234, 1416,
/* 570 */ 1420, 1256, 1234, 1246, 1234, 1234,
};
-/********** End of lemon-generated parsing tables *****************************/
+/********** End of lemon-generated parsing tables *****************************/
/* The next table maps tokens (terminal symbols) into fallback tokens.
-** If a construct like the following:
+** If a construct like the following:
**
** %fallback ID X Y Z.
**
@@ -160669,95 +160669,95 @@ static const YYACTIONTYPE yy_default[] = {
** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
** but it does not parse, the type of the token is changed to ID and
** the parse is retried before an error is thrown.
-**
-** This feature can be used, for example, to cause some keywords in a language
-** to revert to identifiers if they keyword does not apply in the context where
-** it appears.
+**
+** This feature can be used, for example, to cause some keywords in a language
+** to revert to identifiers if they keyword does not apply in the context where
+** it appears.
*/
#ifdef YYFALLBACK
static const YYCODETYPE yyFallback[] = {
0, /* $ => nothing */
0, /* SEMI => nothing */
- 59, /* EXPLAIN => ID */
- 59, /* QUERY => ID */
- 59, /* PLAN => ID */
- 59, /* BEGIN => ID */
+ 59, /* EXPLAIN => ID */
+ 59, /* QUERY => ID */
+ 59, /* PLAN => ID */
+ 59, /* BEGIN => ID */
0, /* TRANSACTION => nothing */
- 59, /* DEFERRED => ID */
- 59, /* IMMEDIATE => ID */
- 59, /* EXCLUSIVE => ID */
+ 59, /* DEFERRED => ID */
+ 59, /* IMMEDIATE => ID */
+ 59, /* EXCLUSIVE => ID */
0, /* COMMIT => nothing */
- 59, /* END => ID */
- 59, /* ROLLBACK => ID */
- 59, /* SAVEPOINT => ID */
- 59, /* RELEASE => ID */
+ 59, /* END => ID */
+ 59, /* ROLLBACK => ID */
+ 59, /* SAVEPOINT => ID */
+ 59, /* RELEASE => ID */
0, /* TO => nothing */
0, /* TABLE => nothing */
0, /* CREATE => nothing */
- 59, /* IF => ID */
+ 59, /* IF => ID */
0, /* NOT => nothing */
0, /* EXISTS => nothing */
- 59, /* TEMP => ID */
+ 59, /* TEMP => ID */
0, /* LP => nothing */
0, /* RP => nothing */
0, /* AS => nothing */
0, /* COMMA => nothing */
- 59, /* WITHOUT => ID */
- 59, /* ABORT => ID */
- 59, /* ACTION => ID */
- 59, /* AFTER => ID */
- 59, /* ANALYZE => ID */
- 59, /* ASC => ID */
- 59, /* ATTACH => ID */
- 59, /* BEFORE => ID */
- 59, /* BY => ID */
- 59, /* CASCADE => ID */
- 59, /* CAST => ID */
- 59, /* CONFLICT => ID */
- 59, /* DATABASE => ID */
- 59, /* DESC => ID */
- 59, /* DETACH => ID */
- 59, /* EACH => ID */
- 59, /* FAIL => ID */
- 0, /* OR => nothing */
- 0, /* AND => nothing */
- 0, /* IS => nothing */
- 59, /* MATCH => ID */
- 59, /* LIKE_KW => ID */
- 0, /* BETWEEN => nothing */
- 0, /* IN => nothing */
- 0, /* ISNULL => nothing */
- 0, /* NOTNULL => nothing */
- 0, /* NE => nothing */
- 0, /* EQ => nothing */
- 0, /* GT => nothing */
- 0, /* LE => nothing */
- 0, /* LT => nothing */
- 0, /* GE => nothing */
- 0, /* ESCAPE => nothing */
+ 59, /* WITHOUT => ID */
+ 59, /* ABORT => ID */
+ 59, /* ACTION => ID */
+ 59, /* AFTER => ID */
+ 59, /* ANALYZE => ID */
+ 59, /* ASC => ID */
+ 59, /* ATTACH => ID */
+ 59, /* BEFORE => ID */
+ 59, /* BY => ID */
+ 59, /* CASCADE => ID */
+ 59, /* CAST => ID */
+ 59, /* CONFLICT => ID */
+ 59, /* DATABASE => ID */
+ 59, /* DESC => ID */
+ 59, /* DETACH => ID */
+ 59, /* EACH => ID */
+ 59, /* FAIL => ID */
+ 0, /* OR => nothing */
+ 0, /* AND => nothing */
+ 0, /* IS => nothing */
+ 59, /* MATCH => ID */
+ 59, /* LIKE_KW => ID */
+ 0, /* BETWEEN => nothing */
+ 0, /* IN => nothing */
+ 0, /* ISNULL => nothing */
+ 0, /* NOTNULL => nothing */
+ 0, /* NE => nothing */
+ 0, /* EQ => nothing */
+ 0, /* GT => nothing */
+ 0, /* LE => nothing */
+ 0, /* LT => nothing */
+ 0, /* GE => nothing */
+ 0, /* ESCAPE => nothing */
0, /* ID => nothing */
- 59, /* COLUMNKW => ID */
+ 59, /* COLUMNKW => ID */
59, /* DO => ID */
- 59, /* FOR => ID */
- 59, /* IGNORE => ID */
- 59, /* INITIALLY => ID */
- 59, /* INSTEAD => ID */
- 59, /* NO => ID */
- 59, /* KEY => ID */
- 59, /* OF => ID */
- 59, /* OFFSET => ID */
- 59, /* PRAGMA => ID */
- 59, /* RAISE => ID */
- 59, /* RECURSIVE => ID */
- 59, /* REPLACE => ID */
- 59, /* RESTRICT => ID */
- 59, /* ROW => ID */
+ 59, /* FOR => ID */
+ 59, /* IGNORE => ID */
+ 59, /* INITIALLY => ID */
+ 59, /* INSTEAD => ID */
+ 59, /* NO => ID */
+ 59, /* KEY => ID */
+ 59, /* OF => ID */
+ 59, /* OFFSET => ID */
+ 59, /* PRAGMA => ID */
+ 59, /* RAISE => ID */
+ 59, /* RECURSIVE => ID */
+ 59, /* REPLACE => ID */
+ 59, /* RESTRICT => ID */
+ 59, /* ROW => ID */
59, /* ROWS => ID */
- 59, /* TRIGGER => ID */
- 59, /* VACUUM => ID */
- 59, /* VIEW => ID */
- 59, /* VIRTUAL => ID */
- 59, /* WITH => ID */
+ 59, /* TRIGGER => ID */
+ 59, /* VACUUM => ID */
+ 59, /* VIEW => ID */
+ 59, /* VIRTUAL => ID */
+ 59, /* WITH => ID */
59, /* NULLS => ID */
59, /* FIRST => ID */
59, /* LAST => ID */
@@ -160774,9 +160774,9 @@ static const YYCODETYPE yyFallback[] = {
59, /* GENERATED => ID */
59, /* ALWAYS => ID */
59, /* MATERIALIZED => ID */
- 59, /* REINDEX => ID */
- 59, /* RENAME => ID */
- 59, /* CTIME_KW => ID */
+ 59, /* REINDEX => ID */
+ 59, /* RENAME => ID */
+ 59, /* CTIME_KW => ID */
0, /* ANY => nothing */
0, /* BITAND => nothing */
0, /* BITOR => nothing */
@@ -160874,13 +160874,13 @@ static const YYCODETYPE yyFallback[] = {
** + The semantic value stored at this level of the stack. This is
** the information used by the action routines in the grammar.
** It is sometimes called the "minor" token.
-**
-** After the "shift" half of a SHIFTREDUCE action, the stateno field
-** actually contains the reduce action for the second half of the
-** SHIFTREDUCE.
+**
+** After the "shift" half of a SHIFTREDUCE action, the stateno field
+** actually contains the reduce action for the second half of the
+** SHIFTREDUCE.
*/
struct yyStackEntry {
- YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
+ YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
YYCODETYPE major; /* The major token value. This is the code
** number for the token at this stack level */
YYMINORTYPE minor; /* The user-supplied minor token value. This
@@ -160891,22 +160891,22 @@ typedef struct yyStackEntry yyStackEntry;
/* The state of the parser is completely contained in an instance of
** the following structure */
struct yyParser {
- yyStackEntry *yytos; /* Pointer to top element of the stack */
+ yyStackEntry *yytos; /* Pointer to top element of the stack */
#ifdef YYTRACKMAXSTACKDEPTH
- int yyhwm; /* High-water mark of the stack */
+ int yyhwm; /* High-water mark of the stack */
#endif
-#ifndef YYNOERRORRECOVERY
+#ifndef YYNOERRORRECOVERY
int yyerrcnt; /* Shifts left before out of the error */
-#endif
+#endif
sqlite3ParserARG_SDECL /* A place to hold %extra_argument */
sqlite3ParserCTX_SDECL /* A place to hold %extra_context */
#if YYSTACKDEPTH<=0
int yystksz; /* Current side of the stack */
yyStackEntry *yystack; /* The parser's stack */
- yyStackEntry yystk0; /* First stack entry */
+ yyStackEntry yystk0; /* First stack entry */
#else
yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
- yyStackEntry *yystackEnd; /* Last entry in the stack */
+ yyStackEntry *yystackEnd; /* Last entry in the stack */
#endif
};
typedef struct yyParser yyParser;
@@ -160944,71 +160944,71 @@ SQLITE_PRIVATE void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){
}
#endif /* NDEBUG */
-#if defined(YYCOVERAGE) || !defined(NDEBUG)
+#if defined(YYCOVERAGE) || !defined(NDEBUG)
/* For tracing shifts, the names of all terminals and nonterminals
** are required. The following table supplies these names */
static const char *const yyTokenName[] = {
- /* 0 */ "$",
- /* 1 */ "SEMI",
- /* 2 */ "EXPLAIN",
- /* 3 */ "QUERY",
- /* 4 */ "PLAN",
- /* 5 */ "BEGIN",
- /* 6 */ "TRANSACTION",
- /* 7 */ "DEFERRED",
- /* 8 */ "IMMEDIATE",
- /* 9 */ "EXCLUSIVE",
- /* 10 */ "COMMIT",
- /* 11 */ "END",
- /* 12 */ "ROLLBACK",
- /* 13 */ "SAVEPOINT",
- /* 14 */ "RELEASE",
- /* 15 */ "TO",
- /* 16 */ "TABLE",
- /* 17 */ "CREATE",
- /* 18 */ "IF",
- /* 19 */ "NOT",
- /* 20 */ "EXISTS",
- /* 21 */ "TEMP",
- /* 22 */ "LP",
- /* 23 */ "RP",
- /* 24 */ "AS",
+ /* 0 */ "$",
+ /* 1 */ "SEMI",
+ /* 2 */ "EXPLAIN",
+ /* 3 */ "QUERY",
+ /* 4 */ "PLAN",
+ /* 5 */ "BEGIN",
+ /* 6 */ "TRANSACTION",
+ /* 7 */ "DEFERRED",
+ /* 8 */ "IMMEDIATE",
+ /* 9 */ "EXCLUSIVE",
+ /* 10 */ "COMMIT",
+ /* 11 */ "END",
+ /* 12 */ "ROLLBACK",
+ /* 13 */ "SAVEPOINT",
+ /* 14 */ "RELEASE",
+ /* 15 */ "TO",
+ /* 16 */ "TABLE",
+ /* 17 */ "CREATE",
+ /* 18 */ "IF",
+ /* 19 */ "NOT",
+ /* 20 */ "EXISTS",
+ /* 21 */ "TEMP",
+ /* 22 */ "LP",
+ /* 23 */ "RP",
+ /* 24 */ "AS",
/* 25 */ "COMMA",
/* 26 */ "WITHOUT",
- /* 27 */ "ABORT",
- /* 28 */ "ACTION",
- /* 29 */ "AFTER",
- /* 30 */ "ANALYZE",
- /* 31 */ "ASC",
- /* 32 */ "ATTACH",
- /* 33 */ "BEFORE",
- /* 34 */ "BY",
- /* 35 */ "CASCADE",
- /* 36 */ "CAST",
- /* 37 */ "CONFLICT",
- /* 38 */ "DATABASE",
- /* 39 */ "DESC",
- /* 40 */ "DETACH",
- /* 41 */ "EACH",
- /* 42 */ "FAIL",
- /* 43 */ "OR",
- /* 44 */ "AND",
- /* 45 */ "IS",
- /* 46 */ "MATCH",
- /* 47 */ "LIKE_KW",
- /* 48 */ "BETWEEN",
- /* 49 */ "IN",
- /* 50 */ "ISNULL",
- /* 51 */ "NOTNULL",
- /* 52 */ "NE",
- /* 53 */ "EQ",
- /* 54 */ "GT",
- /* 55 */ "LE",
- /* 56 */ "LT",
- /* 57 */ "GE",
- /* 58 */ "ESCAPE",
- /* 59 */ "ID",
- /* 60 */ "COLUMNKW",
+ /* 27 */ "ABORT",
+ /* 28 */ "ACTION",
+ /* 29 */ "AFTER",
+ /* 30 */ "ANALYZE",
+ /* 31 */ "ASC",
+ /* 32 */ "ATTACH",
+ /* 33 */ "BEFORE",
+ /* 34 */ "BY",
+ /* 35 */ "CASCADE",
+ /* 36 */ "CAST",
+ /* 37 */ "CONFLICT",
+ /* 38 */ "DATABASE",
+ /* 39 */ "DESC",
+ /* 40 */ "DETACH",
+ /* 41 */ "EACH",
+ /* 42 */ "FAIL",
+ /* 43 */ "OR",
+ /* 44 */ "AND",
+ /* 45 */ "IS",
+ /* 46 */ "MATCH",
+ /* 47 */ "LIKE_KW",
+ /* 48 */ "BETWEEN",
+ /* 49 */ "IN",
+ /* 50 */ "ISNULL",
+ /* 51 */ "NOTNULL",
+ /* 52 */ "NE",
+ /* 53 */ "EQ",
+ /* 54 */ "GT",
+ /* 55 */ "LE",
+ /* 56 */ "LT",
+ /* 57 */ "GE",
+ /* 58 */ "ESCAPE",
+ /* 59 */ "ID",
+ /* 60 */ "COLUMNKW",
/* 61 */ "DO",
/* 62 */ "FOR",
/* 63 */ "IGNORE",
@@ -161267,33 +161267,33 @@ static const char *const yyTokenName[] = {
/* 316 */ "frame_exclude_opt",
/* 317 */ "frame_exclude",
};
-#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
+#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
*/
static const char *const yyRuleName[] = {
- /* 0 */ "explain ::= EXPLAIN",
- /* 1 */ "explain ::= EXPLAIN QUERY PLAN",
- /* 2 */ "cmdx ::= cmd",
- /* 3 */ "cmd ::= BEGIN transtype trans_opt",
- /* 4 */ "transtype ::=",
- /* 5 */ "transtype ::= DEFERRED",
- /* 6 */ "transtype ::= IMMEDIATE",
- /* 7 */ "transtype ::= EXCLUSIVE",
- /* 8 */ "cmd ::= COMMIT|END trans_opt",
- /* 9 */ "cmd ::= ROLLBACK trans_opt",
- /* 10 */ "cmd ::= SAVEPOINT nm",
- /* 11 */ "cmd ::= RELEASE savepoint_opt nm",
- /* 12 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm",
- /* 13 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm",
- /* 14 */ "createkw ::= CREATE",
- /* 15 */ "ifnotexists ::=",
- /* 16 */ "ifnotexists ::= IF NOT EXISTS",
- /* 17 */ "temp ::= TEMP",
- /* 18 */ "temp ::=",
+ /* 0 */ "explain ::= EXPLAIN",
+ /* 1 */ "explain ::= EXPLAIN QUERY PLAN",
+ /* 2 */ "cmdx ::= cmd",
+ /* 3 */ "cmd ::= BEGIN transtype trans_opt",
+ /* 4 */ "transtype ::=",
+ /* 5 */ "transtype ::= DEFERRED",
+ /* 6 */ "transtype ::= IMMEDIATE",
+ /* 7 */ "transtype ::= EXCLUSIVE",
+ /* 8 */ "cmd ::= COMMIT|END trans_opt",
+ /* 9 */ "cmd ::= ROLLBACK trans_opt",
+ /* 10 */ "cmd ::= SAVEPOINT nm",
+ /* 11 */ "cmd ::= RELEASE savepoint_opt nm",
+ /* 12 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm",
+ /* 13 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm",
+ /* 14 */ "createkw ::= CREATE",
+ /* 15 */ "ifnotexists ::=",
+ /* 16 */ "ifnotexists ::= IF NOT EXISTS",
+ /* 17 */ "temp ::= TEMP",
+ /* 18 */ "temp ::=",
/* 19 */ "create_table_args ::= LP columnlist conslist_opt RP table_option_set",
- /* 20 */ "create_table_args ::= AS select",
+ /* 20 */ "create_table_args ::= AS select",
/* 21 */ "table_option_set ::=",
/* 22 */ "table_option_set ::= table_option_set COMMA table_option",
/* 23 */ "table_option ::= WITHOUT nm",
@@ -161680,75 +161680,75 @@ static const char *const yyRuleName[] = {
#if YYSTACKDEPTH<=0
/*
-** Try to increase the size of the parser stack. Return the number
-** of errors. Return 0 on success.
+** Try to increase the size of the parser stack. Return the number
+** of errors. Return 0 on success.
*/
-static int yyGrowStack(yyParser *p){
+static int yyGrowStack(yyParser *p){
int newSize;
- int idx;
+ int idx;
yyStackEntry *pNew;
newSize = p->yystksz*2 + 100;
- idx = p->yytos ? (int)(p->yytos - p->yystack) : 0;
- if( p->yystack==&p->yystk0 ){
- pNew = malloc(newSize*sizeof(pNew[0]));
- if( pNew ) pNew[0] = p->yystk0;
- }else{
- pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
- }
+ idx = p->yytos ? (int)(p->yytos - p->yystack) : 0;
+ if( p->yystack==&p->yystk0 ){
+ pNew = malloc(newSize*sizeof(pNew[0]));
+ if( pNew ) pNew[0] = p->yystk0;
+ }else{
+ pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
+ }
if( pNew ){
p->yystack = pNew;
- p->yytos = &p->yystack[idx];
+ p->yytos = &p->yystack[idx];
#ifndef NDEBUG
if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
- yyTracePrompt, p->yystksz, newSize);
+ fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
+ yyTracePrompt, p->yystksz, newSize);
}
#endif
- p->yystksz = newSize;
+ p->yystksz = newSize;
}
return pNew==0;
}
#endif
-/* Datatype of the argument to the memory allocated passed as the
-** second argument to sqlite3ParserAlloc() below. This can be changed by
-** putting an appropriate #define in the %include section of the input
-** grammar.
-*/
-#ifndef YYMALLOCARGTYPE
-# define YYMALLOCARGTYPE size_t
-#endif
-
-/* Initialize a new parser that has already been allocated.
-*/
+/* Datatype of the argument to the memory allocated passed as the
+** second argument to sqlite3ParserAlloc() below. This can be changed by
+** putting an appropriate #define in the %include section of the input
+** grammar.
+*/
+#ifndef YYMALLOCARGTYPE
+# define YYMALLOCARGTYPE size_t
+#endif
+
+/* Initialize a new parser that has already been allocated.
+*/
SQLITE_PRIVATE void sqlite3ParserInit(void *yypRawParser sqlite3ParserCTX_PDECL){
yyParser *yypParser = (yyParser*)yypRawParser;
sqlite3ParserCTX_STORE
-#ifdef YYTRACKMAXSTACKDEPTH
+#ifdef YYTRACKMAXSTACKDEPTH
yypParser->yyhwm = 0;
-#endif
-#if YYSTACKDEPTH<=0
+#endif
+#if YYSTACKDEPTH<=0
yypParser->yytos = NULL;
yypParser->yystack = NULL;
yypParser->yystksz = 0;
if( yyGrowStack(yypParser) ){
yypParser->yystack = &yypParser->yystk0;
yypParser->yystksz = 1;
- }
-#endif
-#ifndef YYNOERRORRECOVERY
+ }
+#endif
+#ifndef YYNOERRORRECOVERY
yypParser->yyerrcnt = -1;
-#endif
+#endif
yypParser->yytos = yypParser->yystack;
yypParser->yystack[0].stateno = 0;
yypParser->yystack[0].major = 0;
-#if YYSTACKDEPTH>0
+#if YYSTACKDEPTH>0
yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1];
-#endif
-}
-
-#ifndef sqlite3Parser_ENGINEALWAYSONSTACK
+#endif
+}
+
+#ifndef sqlite3Parser_ENGINEALWAYSONSTACK
/*
** This function allocates a new parser.
** The only argument is a pointer to a function which works like
@@ -161770,15 +161770,15 @@ SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) sql
}
return (void*)yypParser;
}
-#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */
+#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */
-
-/* The following function deletes the "minor type" or semantic value
-** associated with a symbol. The symbol can be either a terminal
-** or nonterminal. "yymajor" is the symbol code, and "yypminor" is
+
+/* The following function deletes the "minor type" or semantic value
+** associated with a symbol. The symbol can be either a terminal
+** or nonterminal. "yymajor" is the symbol code, and "yypminor" is
** a pointer to the value to be deleted. The code used to do the
-** deletions is derived from the %destructor and/or %token_destructor
-** directives of the input grammar.
+** deletions is derived from the %destructor and/or %token_destructor
+** directives of the input grammar.
*/
static void yy_destructor(
yyParser *yypParser, /* The parser */
@@ -161795,10 +161795,10 @@ static void yy_destructor(
** being destroyed before it is finished parsing.
**
** Note: during a reduce, the only symbols destroyed are those
- ** which appear on the RHS of the rule, but which are *not* used
+ ** which appear on the RHS of the rule, but which are *not* used
** inside the C code.
*/
-/********* Begin destructor definitions ***************************************/
+/********* Begin destructor definitions ***************************************/
case 203: /* select */
case 238: /* selectnowith */
case 239: /* oneselect */
@@ -161894,7 +161894,7 @@ sqlite3IdListDelete(pParse->db, (yypminor->yy570).b);
sqlite3ExprDelete(pParse->db, (yypminor->yy81).pExpr);
}
break;
-/********* End destructor definitions *****************************************/
+/********* End destructor definitions *****************************************/
default: break; /* If no destructor action specified: do nothing */
}
}
@@ -161905,52 +161905,52 @@ sqlite3ExprDelete(pParse->db, (yypminor->yy81).pExpr);
** If there is a destructor routine associated with the token which
** is popped from the stack, then call it.
*/
-static void yy_pop_parser_stack(yyParser *pParser){
- yyStackEntry *yytos;
- assert( pParser->yytos!=0 );
- assert( pParser->yytos > pParser->yystack );
- yytos = pParser->yytos--;
+static void yy_pop_parser_stack(yyParser *pParser){
+ yyStackEntry *yytos;
+ assert( pParser->yytos!=0 );
+ assert( pParser->yytos > pParser->yystack );
+ yytos = pParser->yytos--;
#ifndef NDEBUG
- if( yyTraceFILE ){
+ if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sPopping %s\n",
yyTracePrompt,
yyTokenName[yytos->major]);
}
#endif
- yy_destructor(pParser, yytos->major, &yytos->minor);
+ yy_destructor(pParser, yytos->major, &yytos->minor);
+}
+
+/*
+** Clear all secondary memory allocations from the parser
+*/
+SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){
+ yyParser *pParser = (yyParser*)p;
+ while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser);
+#if YYSTACKDEPTH<=0
+ if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack);
+#endif
}
-/*
-** Clear all secondary memory allocations from the parser
-*/
-SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){
- yyParser *pParser = (yyParser*)p;
- while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser);
-#if YYSTACKDEPTH<=0
- if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack);
-#endif
-}
-
-#ifndef sqlite3Parser_ENGINEALWAYSONSTACK
+#ifndef sqlite3Parser_ENGINEALWAYSONSTACK
/*
-** Deallocate and destroy a parser. Destructors are called for
+** Deallocate and destroy a parser. Destructors are called for
** all stack elements before shutting the parser down.
**
-** If the YYPARSEFREENEVERNULL macro exists (for example because it
-** is defined in a %include section of the input grammar) then it is
-** assumed that the input pointer is never NULL.
+** If the YYPARSEFREENEVERNULL macro exists (for example because it
+** is defined in a %include section of the input grammar) then it is
+** assumed that the input pointer is never NULL.
*/
SQLITE_PRIVATE void sqlite3ParserFree(
void *p, /* The parser to be deleted */
void (*freeProc)(void*) /* Function used to reclaim memory */
){
-#ifndef YYPARSEFREENEVERNULL
- if( p==0 ) return;
+#ifndef YYPARSEFREENEVERNULL
+ if( p==0 ) return;
#endif
- sqlite3ParserFinalize(p);
- (*freeProc)(p);
+ sqlite3ParserFinalize(p);
+ (*freeProc)(p);
}
-#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */
+#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */
/*
** Return the peak depth of the stack for a parser.
@@ -161958,48 +161958,48 @@ SQLITE_PRIVATE void sqlite3ParserFree(
#ifdef YYTRACKMAXSTACKDEPTH
SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){
yyParser *pParser = (yyParser*)p;
- return pParser->yyhwm;
-}
-#endif
-
-/* This array of booleans keeps track of the parser statement
-** coverage. The element yycoverage[X][Y] is set when the parser
-** is in state X and has a lookahead token Y. In a well-tested
-** systems, every element of this matrix should end up being set.
-*/
-#if defined(YYCOVERAGE)
-static unsigned char yycoverage[YYNSTATE][YYNTOKEN];
-#endif
-
-/*
-** Write into out a description of every state/lookahead combination that
-**
-** (1) has not been used by the parser, and
-** (2) is not a syntax error.
-**
-** Return the number of missed state/lookahead combinations.
-*/
-#if defined(YYCOVERAGE)
-SQLITE_PRIVATE int sqlite3ParserCoverage(FILE *out){
- int stateno, iLookAhead, i;
- int nMissed = 0;
- for(stateno=0; stateno<YYNSTATE; stateno++){
- i = yy_shift_ofst[stateno];
- for(iLookAhead=0; iLookAhead<YYNTOKEN; iLookAhead++){
- if( yy_lookahead[i+iLookAhead]!=iLookAhead ) continue;
- if( yycoverage[stateno][iLookAhead]==0 ) nMissed++;
- if( out ){
- fprintf(out,"State %d lookahead %s %s\n", stateno,
- yyTokenName[iLookAhead],
- yycoverage[stateno][iLookAhead] ? "ok" : "missed");
- }
- }
- }
- return nMissed;
-}
-#endif
-
-/*
+ return pParser->yyhwm;
+}
+#endif
+
+/* This array of booleans keeps track of the parser statement
+** coverage. The element yycoverage[X][Y] is set when the parser
+** is in state X and has a lookahead token Y. In a well-tested
+** systems, every element of this matrix should end up being set.
+*/
+#if defined(YYCOVERAGE)
+static unsigned char yycoverage[YYNSTATE][YYNTOKEN];
+#endif
+
+/*
+** Write into out a description of every state/lookahead combination that
+**
+** (1) has not been used by the parser, and
+** (2) is not a syntax error.
+**
+** Return the number of missed state/lookahead combinations.
+*/
+#if defined(YYCOVERAGE)
+SQLITE_PRIVATE int sqlite3ParserCoverage(FILE *out){
+ int stateno, iLookAhead, i;
+ int nMissed = 0;
+ for(stateno=0; stateno<YYNSTATE; stateno++){
+ i = yy_shift_ofst[stateno];
+ for(iLookAhead=0; iLookAhead<YYNTOKEN; iLookAhead++){
+ if( yy_lookahead[i+iLookAhead]!=iLookAhead ) continue;
+ if( yycoverage[stateno][iLookAhead]==0 ) nMissed++;
+ if( out ){
+ fprintf(out,"State %d lookahead %s %s\n", stateno,
+ yyTokenName[iLookAhead],
+ yycoverage[stateno][iLookAhead] ? "ok" : "missed");
+ }
+ }
+ }
+ return nMissed;
+}
+#endif
+
+/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
*/
@@ -162009,19 +162009,19 @@ static YYACTIONTYPE yy_find_shift_action(
){
int i;
- if( stateno>YY_MAX_SHIFT ) return stateno;
- assert( stateno <= YY_SHIFT_COUNT );
-#if defined(YYCOVERAGE)
- yycoverage[stateno][iLookAhead] = 1;
-#endif
- do{
- i = yy_shift_ofst[stateno];
+ if( stateno>YY_MAX_SHIFT ) return stateno;
+ assert( stateno <= YY_SHIFT_COUNT );
+#if defined(YYCOVERAGE)
+ yycoverage[stateno][iLookAhead] = 1;
+#endif
+ do{
+ i = yy_shift_ofst[stateno];
assert( i>=0 );
assert( i<=YY_ACTTAB_COUNT );
assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD );
- assert( iLookAhead!=YYNOCODE );
- assert( iLookAhead < YYNTOKEN );
- i += iLookAhead;
+ assert( iLookAhead!=YYNOCODE );
+ assert( iLookAhead < YYNTOKEN );
+ i += iLookAhead;
assert( i<(int)YY_NLOOKAHEAD );
if( yy_lookahead[i]!=iLookAhead ){
#ifdef YYFALLBACK
@@ -162035,9 +162035,9 @@ static YYACTIONTYPE yy_find_shift_action(
yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
}
#endif
- assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
- iLookAhead = iFallback;
- continue;
+ assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
+ iLookAhead = iFallback;
+ continue;
}
#endif
#ifdef YYWILDCARD
@@ -162048,20 +162048,20 @@ static YYACTIONTYPE yy_find_shift_action(
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
- yyTracePrompt, yyTokenName[iLookAhead],
- yyTokenName[YYWILDCARD]);
+ yyTracePrompt, yyTokenName[iLookAhead],
+ yyTokenName[YYWILDCARD]);
}
#endif /* NDEBUG */
return yy_action[j];
}
}
#endif /* YYWILDCARD */
- return yy_default[stateno];
- }else{
+ return yy_default[stateno];
+ }else{
assert( i>=0 && i<(int)(sizeof(yy_action)/sizeof(yy_action[0])) );
- return yy_action[i];
+ return yy_action[i];
}
- }while(1);
+ }while(1);
}
/*
@@ -162097,7 +162097,7 @@ static YYACTIONTYPE yy_find_reduce_action(
/*
** The following routine is called if the stack overflows.
*/
-static void yyStackOverflow(yyParser *yypParser){
+static void yyStackOverflow(yyParser *yypParser){
sqlite3ParserARG_FETCH
sqlite3ParserCTX_FETCH
#ifndef NDEBUG
@@ -162105,78 +162105,78 @@ static void yyStackOverflow(yyParser *yypParser){
fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
}
#endif
- while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
+ while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
/* Here code is inserted which will execute if the parser
** stack every overflows */
-/******** Begin %stack_overflow code ******************************************/
+/******** Begin %stack_overflow code ******************************************/
sqlite3ErrorMsg(pParse, "parser stack overflow");
-/******** End %stack_overflow code ********************************************/
+/******** End %stack_overflow code ********************************************/
sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */
sqlite3ParserCTX_STORE
}
/*
-** Print tracing information for a SHIFT action
-*/
-#ifndef NDEBUG
-static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){
- if( yyTraceFILE ){
- if( yyNewState<YYNSTATE ){
- fprintf(yyTraceFILE,"%s%s '%s', go to state %d\n",
- yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major],
- yyNewState);
- }else{
- fprintf(yyTraceFILE,"%s%s '%s', pending reduce %d\n",
- yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major],
- yyNewState - YY_MIN_REDUCE);
- }
- }
-}
-#else
-# define yyTraceShift(X,Y,Z)
-#endif
-
-/*
+** Print tracing information for a SHIFT action
+*/
+#ifndef NDEBUG
+static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){
+ if( yyTraceFILE ){
+ if( yyNewState<YYNSTATE ){
+ fprintf(yyTraceFILE,"%s%s '%s', go to state %d\n",
+ yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major],
+ yyNewState);
+ }else{
+ fprintf(yyTraceFILE,"%s%s '%s', pending reduce %d\n",
+ yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major],
+ yyNewState - YY_MIN_REDUCE);
+ }
+ }
+}
+#else
+# define yyTraceShift(X,Y,Z)
+#endif
+
+/*
** Perform a shift action.
*/
static void yy_shift(
yyParser *yypParser, /* The parser to be shifted */
YYACTIONTYPE yyNewState, /* The new state to shift in */
YYCODETYPE yyMajor, /* The major token to shift in */
- sqlite3ParserTOKENTYPE yyMinor /* The minor token to shift in */
+ sqlite3ParserTOKENTYPE yyMinor /* The minor token to shift in */
){
yyStackEntry *yytos;
- yypParser->yytos++;
+ yypParser->yytos++;
#ifdef YYTRACKMAXSTACKDEPTH
- if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
- yypParser->yyhwm++;
- assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) );
+ if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
+ yypParser->yyhwm++;
+ assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) );
}
#endif
#if YYSTACKDEPTH>0
- if( yypParser->yytos>yypParser->yystackEnd ){
- yypParser->yytos--;
- yyStackOverflow(yypParser);
+ if( yypParser->yytos>yypParser->yystackEnd ){
+ yypParser->yytos--;
+ yyStackOverflow(yypParser);
return;
}
#else
- if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){
- if( yyGrowStack(yypParser) ){
- yypParser->yytos--;
- yyStackOverflow(yypParser);
+ if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){
+ if( yyGrowStack(yypParser) ){
+ yypParser->yytos--;
+ yyStackOverflow(yypParser);
return;
}
}
#endif
- if( yyNewState > YY_MAX_SHIFT ){
- yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
- }
- yytos = yypParser->yytos;
+ if( yyNewState > YY_MAX_SHIFT ){
+ yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
+ }
+ yytos = yypParser->yytos;
yytos->stateno = yyNewState;
yytos->major = yyMajor;
- yytos->minor.yy0 = yyMinor;
- yyTraceShift(yypParser, yyNewState, "Shift");
+ yytos->minor.yy0 = yyMinor;
+ yyTraceShift(yypParser, yyNewState, "Shift");
}
/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side
@@ -162996,18 +162996,18 @@ static void yy_accept(yyParser*); /* Forward Declaration */
/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
-**
-** The yyLookahead and yyLookaheadToken parameters provide reduce actions
-** access to the lookahead token (if any). The yyLookahead will be YYNOCODE
-** if the lookahead token has already been consumed. As this procedure is
-** only called from one place, optimizing compilers will in-line it, which
-** means that the extra parameters have no performance impact.
+**
+** The yyLookahead and yyLookaheadToken parameters provide reduce actions
+** access to the lookahead token (if any). The yyLookahead will be YYNOCODE
+** if the lookahead token has already been consumed. As this procedure is
+** only called from one place, optimizing compilers will in-line it, which
+** means that the extra parameters have no performance impact.
*/
static YYACTIONTYPE yy_reduce(
yyParser *yypParser, /* The parser */
- unsigned int yyruleno, /* Number of the rule by which to reduce */
- int yyLookahead, /* Lookahead token, or YYNOCODE if none */
- sqlite3ParserTOKENTYPE yyLookaheadToken /* Value of the lookahead token */
+ unsigned int yyruleno, /* Number of the rule by which to reduce */
+ int yyLookahead, /* Lookahead token, or YYNOCODE if none */
+ sqlite3ParserTOKENTYPE yyLookaheadToken /* Value of the lookahead token */
sqlite3ParserCTX_PDECL /* %extra_context */
){
int yygoto; /* The next state */
@@ -163015,9 +163015,9 @@ static YYACTIONTYPE yy_reduce(
yyStackEntry *yymsp; /* The top of the parser's stack */
int yysize; /* Amount to pop the stack */
sqlite3ParserARG_FETCH
- (void)yyLookahead;
- (void)yyLookaheadToken;
- yymsp = yypParser->yytos;
+ (void)yyLookahead;
+ (void)yyLookaheadToken;
+ yymsp = yypParser->yytos;
switch( yyruleno ){
/* Beginning here are the reduction cases. A typical example
@@ -163028,58 +163028,58 @@ static YYACTIONTYPE yy_reduce(
** #line <lineno> <thisfile>
** break;
*/
-/********** Begin reduce actions **********************************************/
- YYMINORTYPE yylhsminor;
- case 0: /* explain ::= EXPLAIN */
-{ pParse->explain = 1; }
+/********** Begin reduce actions **********************************************/
+ YYMINORTYPE yylhsminor;
+ case 0: /* explain ::= EXPLAIN */
+{ pParse->explain = 1; }
break;
- case 1: /* explain ::= EXPLAIN QUERY PLAN */
-{ pParse->explain = 2; }
+ case 1: /* explain ::= EXPLAIN QUERY PLAN */
+{ pParse->explain = 2; }
break;
- case 2: /* cmdx ::= cmd */
+ case 2: /* cmdx ::= cmd */
{ sqlite3FinishCoding(pParse); }
break;
- case 3: /* cmd ::= BEGIN transtype trans_opt */
+ case 3: /* cmd ::= BEGIN transtype trans_opt */
{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy64);}
break;
- case 4: /* transtype ::= */
+ case 4: /* transtype ::= */
{yymsp[1].minor.yy64 = TK_DEFERRED;}
break;
- case 5: /* transtype ::= DEFERRED */
- case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
- case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
+ case 5: /* transtype ::= DEFERRED */
+ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
+ case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
case 320: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==320);
{yymsp[0].minor.yy64 = yymsp[0].major; /*A-overwrites-X*/}
break;
- case 8: /* cmd ::= COMMIT|END trans_opt */
- case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
-{sqlite3EndTransaction(pParse,yymsp[-1].major);}
+ case 8: /* cmd ::= COMMIT|END trans_opt */
+ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
+{sqlite3EndTransaction(pParse,yymsp[-1].major);}
break;
- case 10: /* cmd ::= SAVEPOINT nm */
+ case 10: /* cmd ::= SAVEPOINT nm */
{
sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0);
}
break;
- case 11: /* cmd ::= RELEASE savepoint_opt nm */
+ case 11: /* cmd ::= RELEASE savepoint_opt nm */
{
sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0);
}
break;
- case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+ case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
{
sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
}
break;
- case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy64,0,0,yymsp[-2].minor.yy64);
}
break;
- case 14: /* createkw ::= CREATE */
-{disableLookaside(pParse);}
+ case 14: /* createkw ::= CREATE */
+{disableLookaside(pParse);}
break;
- case 15: /* ifnotexists ::= */
- case 18: /* temp ::= */ yytestcase(yyruleno==18);
+ case 15: /* ifnotexists ::= */
+ case 18: /* temp ::= */ yytestcase(yyruleno==18);
case 47: /* autoinc ::= */ yytestcase(yyruleno==47);
case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62);
case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72);
@@ -163088,18 +163088,18 @@ static YYACTIONTYPE yy_reduce(
case 241: /* collate ::= */ yytestcase(yyruleno==241);
{yymsp[1].minor.yy64 = 0;}
break;
- case 16: /* ifnotexists ::= IF NOT EXISTS */
+ case 16: /* ifnotexists ::= IF NOT EXISTS */
{yymsp[-2].minor.yy64 = 1;}
break;
- case 17: /* temp ::= TEMP */
+ case 17: /* temp ::= TEMP */
{yymsp[0].minor.yy64 = pParse->db->init.busy==0;}
- break;
+ break;
case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */
{
sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy51,0);
}
break;
- case 20: /* create_table_args ::= AS select */
+ case 20: /* create_table_args ::= AS select */
{
sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy303);
sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy303);
@@ -163132,31 +163132,31 @@ static YYACTIONTYPE yy_reduce(
}
}
yymsp[0].minor.yy51 = yylhsminor.yy51;
- break;
+ break;
case 25: /* columnname ::= nm typetoken */
{sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);}
break;
case 26: /* typetoken ::= */
case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65);
case 104: /* as ::= */ yytestcase(yyruleno==104);
-{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
- break;
+{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
+ break;
case 27: /* typetoken ::= typename LP signed RP */
{
- yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
+ yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
}
break;
case 28: /* typetoken ::= typename LP signed COMMA signed RP */
{
- yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
+ yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
}
break;
case 29: /* typename ::= typename ID|STRING */
-{yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
+{yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
case 30: /* scanpt ::= */
{
- assert( yyLookahead!=YYNOCODE );
+ assert( yyLookahead!=YYNOCODE );
yymsp[1].minor.yy600 = yyLookaheadToken.z;
}
break;
@@ -163168,7 +163168,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 32: /* ccons ::= CONSTRAINT nm */
case 67: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==67);
-{pParse->constraintName = yymsp[0].minor.yy0;}
+{pParse->constraintName = yymsp[0].minor.yy0;}
break;
case 33: /* ccons ::= DEFAULT scantok term */
{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy626,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
@@ -163187,7 +163187,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 37: /* ccons ::= DEFAULT scantok ID|INDEXED */
{
- Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
+ Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
if( p ){
sqlite3ExprIdToTrueFalse(p);
testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
@@ -163203,7 +163203,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 40: /* ccons ::= UNIQUE onconf */
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy64,0,0,0,0,
- SQLITE_IDXTYPE_UNIQUE);}
+ SQLITE_IDXTYPE_UNIQUE);}
break;
case 41: /* ccons ::= CHECK LP expr RP */
{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy626,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);}
@@ -163258,10 +163258,10 @@ static YYACTIONTYPE yy_reduce(
break;
case 59: /* refact ::= NO ACTION */
{ yymsp[-1].minor.yy64 = OE_None; /* EV: R-33326-45252 */}
- break;
+ break;
case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
{yymsp[-2].minor.yy64 = 0;}
- break;
+ break;
case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76);
case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171);
@@ -163285,7 +163285,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy562,yymsp[0].minor.yy64,0,0,0,0,
- SQLITE_IDXTYPE_UNIQUE);}
+ SQLITE_IDXTYPE_UNIQUE);}
break;
case 70: /* tcons ::= CHECK LP expr RP onconf */
{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy626,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);}
@@ -163357,7 +163357,7 @@ static YYACTIONTYPE yy_reduce(
x.n = 0;
parserDoubleLinkSelect(pParse, pRhs);
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
- pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
+ pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
}
if( pRhs ){
pRhs->op = (u8)yymsp[-1].minor.yy64;
@@ -163377,7 +163377,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 90: /* multiselect_op ::= UNION ALL */
{yymsp[-1].minor.yy64 = TK_ALL;}
- break;
+ break;
case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
yymsp[-8].minor.yy303 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy562,yymsp[-5].minor.yy607,yymsp[-4].minor.yy626,yymsp[-3].minor.yy562,yymsp[-2].minor.yy626,yymsp[-1].minor.yy562,yymsp[-7].minor.yy64,yymsp[0].minor.yy626);
@@ -163435,15 +163435,15 @@ static YYACTIONTYPE yy_reduce(
break;
case 101: /* selcollist ::= sclp scanpt STAR */
{
- Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
+ Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
yymsp[-2].minor.yy562 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy562, p);
}
break;
case 102: /* selcollist ::= sclp scanpt nm DOT STAR */
{
- Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
- Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
- Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
+ Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
+ Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
+ Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
yymsp[-4].minor.yy562 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy562, pDot);
}
break;
@@ -163451,7 +163451,7 @@ static YYACTIONTYPE yy_reduce(
case 114: /* dbnm ::= DOT nm */ yytestcase(yyruleno==114);
case 253: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==253);
case 254: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==254);
-{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
+{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
break;
case 105: /* from ::= */
case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108);
@@ -163478,10 +163478,10 @@ static YYACTIONTYPE yy_reduce(
{
yymsp[-8].minor.yy607 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy607,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy626,yymsp[0].minor.yy240);
sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy607, yymsp[-4].minor.yy562);
-}
- break;
+}
+ break;
case 111: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
-{
+{
yymsp[-6].minor.yy607 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy607,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy303,yymsp[-1].minor.yy626,yymsp[0].minor.yy240);
}
break;
@@ -163517,7 +163517,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 113: /* dbnm ::= */
case 127: /* indexed_opt ::= */ yytestcase(yyruleno==127);
-{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
+{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
break;
case 115: /* fullname ::= nm */
{
@@ -163582,10 +163582,10 @@ static YYACTIONTYPE yy_reduce(
{yymsp[1].minor.yy626 = 0;}
break;
case 128: /* indexed_opt ::= INDEXED BY nm */
-{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
+{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
break;
case 129: /* indexed_opt ::= NOT INDEXED */
-{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
+{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
break;
case 130: /* using_opt ::= USING LP idlist RP */
{yymsp[-3].minor.yy240 = yymsp[-1].minor.yy240;}
@@ -163597,7 +163597,7 @@ static YYACTIONTYPE yy_reduce(
case 133: /* orderby_opt ::= ORDER BY sortlist */
case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143);
{yymsp[-2].minor.yy562 = yymsp[0].minor.yy562;}
- break;
+ break;
case 134: /* sortlist ::= sortlist COMMA expr sortorder nulls */
{
yymsp[-4].minor.yy562 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy562,yymsp[-2].minor.yy626);
@@ -163693,14 +163693,14 @@ static YYACTIONTYPE yy_reduce(
}
break;
case 162: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
-{
+{
sqlite3Insert(pParse, yymsp[-3].minor.yy607, yymsp[-1].minor.yy303, yymsp[-2].minor.yy240, yymsp[-5].minor.yy64, yymsp[0].minor.yy138);
-}
+}
break;
case 163: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
-{
+{
sqlite3Insert(pParse, yymsp[-4].minor.yy607, 0, yymsp[-3].minor.yy240, yymsp[-6].minor.yy64, 0);
-}
+}
break;
case 164: /* upsert ::= */
{ yymsp[1].minor.yy138 = 0; }
@@ -163740,23 +163740,23 @@ static YYACTIONTYPE yy_reduce(
{yymsp[0].minor.yy626=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
case 180: /* expr ::= nm DOT nm */
-{
- Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
- Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
+{
+ Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
+ Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
}
yylhsminor.yy626 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
-}
+}
yymsp[-2].minor.yy626 = yylhsminor.yy626;
break;
case 181: /* expr ::= nm DOT nm DOT nm */
{
- Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
- Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
- Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
- Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
+ Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
+ Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
+ Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
+ Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
@@ -163768,7 +163768,7 @@ static YYACTIONTYPE yy_reduce(
case 182: /* term ::= NULL|FLOAT|BLOB */
case 183: /* term ::= STRING */ yytestcase(yyruleno==183);
{yymsp[0].minor.yy626=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
- break;
+ break;
case 184: /* term ::= INTEGER */
{
yylhsminor.yy626 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
@@ -163777,18 +163777,18 @@ static YYACTIONTYPE yy_reduce(
break;
case 185: /* expr ::= VARIABLE */
{
- if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
- u32 n = yymsp[0].minor.yy0.n;
+ if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
+ u32 n = yymsp[0].minor.yy0.n;
yymsp[0].minor.yy626 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy626, n);
- }else{
+ }else{
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
** in the virtual machine. #N is the N-th register. */
- Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
- assert( t.n>=2 );
+ Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
+ assert( t.n>=2 );
if( pParse->nested==0 ){
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
yymsp[0].minor.yy626 = 0;
}else{
yymsp[0].minor.yy626 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
@@ -163828,7 +163828,7 @@ static YYACTIONTYPE yy_reduce(
yymsp[-5].minor.yy626 = yylhsminor.yy626;
break;
case 191: /* expr ::= ID|INDEXED LP STAR RP filter_over */
-{
+{
yylhsminor.yy626 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
sqlite3WindowAttach(pParse, yylhsminor.yy626, yymsp[0].minor.yy375);
}
@@ -163849,10 +163849,10 @@ static YYACTIONTYPE yy_reduce(
if( ALWAYS(pList->nExpr) ){
yymsp[-4].minor.yy626->flags |= pList->a[0].pExpr->flags & EP_Propagate;
}
- }else{
- sqlite3ExprListDelete(pParse->db, pList);
- }
-}
+ }else{
+ sqlite3ExprListDelete(pParse->db, pList);
+ }
+}
break;
case 194: /* expr ::= expr AND expr */
{yymsp[-2].minor.yy626=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy626,yymsp[0].minor.yy626);}
@@ -163867,13 +163867,13 @@ static YYACTIONTYPE yy_reduce(
{yymsp[-2].minor.yy626=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy626,yymsp[0].minor.yy626);}
break;
case 202: /* likeop ::= NOT LIKE_KW|MATCH */
-{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
+{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
break;
case 203: /* expr ::= expr likeop expr */
{
ExprList *pList;
- int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
- yymsp[-1].minor.yy0.n &= 0x7fffffff;
+ int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
+ yymsp[-1].minor.yy0.n &= 0x7fffffff;
pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy626);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy626);
yymsp[-2].minor.yy626 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
@@ -163884,8 +163884,8 @@ static YYACTIONTYPE yy_reduce(
case 204: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
- int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
- yymsp[-3].minor.yy0.n &= 0x7fffffff;
+ int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
+ yymsp[-3].minor.yy0.n &= 0x7fffffff;
pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy626);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy626);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy626);
@@ -163995,7 +163995,7 @@ static YYACTIONTYPE yy_reduce(
case 220: /* expr ::= expr in_op nm dbnm paren_exprlist */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
- Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
+ Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
if( yymsp[0].minor.yy562 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy562);
yymsp[-4].minor.yy626 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy626, 0);
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy626, pSelect);
@@ -164004,7 +164004,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 221: /* expr ::= EXISTS LP select RP */
{
- Expr *p;
+ Expr *p;
p = yymsp[-3].minor.yy626 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy303);
}
@@ -164041,11 +164041,11 @@ static YYACTIONTYPE yy_reduce(
break;
case 231: /* nexprlist ::= expr */
{yymsp[0].minor.yy562 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy626); /*A-overwrites-Y*/}
- break;
+ break;
case 233: /* paren_exprlist ::= LP exprlist RP */
case 238: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==238);
{yymsp[-2].minor.yy562 = yymsp[-1].minor.yy562;}
- break;
+ break;
case 234: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
{
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
@@ -164108,7 +164108,7 @@ static YYACTIONTYPE yy_reduce(
case 256: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy64, yymsp[-4].minor.yy570.a, yymsp[-4].minor.yy570.b, yymsp[-2].minor.yy607, yymsp[0].minor.yy626, yymsp[-10].minor.yy64, yymsp[-8].minor.yy64);
- yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
+ yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
}
break;
case 257: /* trigger_time ::= BEFORE|AFTER */
@@ -164150,7 +164150,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 267: /* trnm ::= nm DOT nm */
{
- yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
+ yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
"qualified table names are not allowed on INSERT, UPDATE, and DELETE "
"statements within triggers");
@@ -164244,8 +164244,8 @@ static YYACTIONTYPE yy_reduce(
break;
case 289: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
{
- yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
- sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
+ yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
+ sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
}
break;
case 290: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
@@ -164255,7 +164255,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 291: /* add_column_fullname ::= fullname */
{
- disableLookaside(pParse);
+ disableLookaside(pParse);
sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy607);
}
break;
@@ -164305,7 +164305,7 @@ static YYACTIONTYPE yy_reduce(
{
yymsp[0].minor.yy43 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy255); /*A-overwrites-X*/
}
- break;
+ break;
case 307: /* wqlist ::= wqlist COMMA wqitem */
{
yymsp[-2].minor.yy43 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy43, yymsp[0].minor.yy255);
@@ -164520,25 +164520,25 @@ static YYACTIONTYPE yy_reduce(
/* (399) anylist ::= anylist ANY */ yytestcase(yyruleno==399);
/* (400) with ::= */ yytestcase(yyruleno==400);
break;
-/********** End reduce actions ************************************************/
+/********** End reduce actions ************************************************/
};
assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
yygoto = yyRuleInfoLhs[yyruleno];
yysize = yyRuleInfoNRhs[yyruleno];
- yyact = yy_find_reduce_action(yymsp[yysize].stateno,(YYCODETYPE)yygoto);
-
- /* There are no SHIFTREDUCE actions on nonterminals because the table
- ** generator has simplified them to pure REDUCE actions. */
- assert( !(yyact>YY_MAX_SHIFT && yyact<=YY_MAX_SHIFTREDUCE) );
-
- /* It is not possible for a REDUCE to be followed by an error */
- assert( yyact!=YY_ERROR_ACTION );
-
- yymsp += yysize+1;
- yypParser->yytos = yymsp;
- yymsp->stateno = (YYACTIONTYPE)yyact;
- yymsp->major = (YYCODETYPE)yygoto;
- yyTraceShift(yypParser, yyact, "... then shift");
+ yyact = yy_find_reduce_action(yymsp[yysize].stateno,(YYCODETYPE)yygoto);
+
+ /* There are no SHIFTREDUCE actions on nonterminals because the table
+ ** generator has simplified them to pure REDUCE actions. */
+ assert( !(yyact>YY_MAX_SHIFT && yyact<=YY_MAX_SHIFTREDUCE) );
+
+ /* It is not possible for a REDUCE to be followed by an error */
+ assert( yyact!=YY_ERROR_ACTION );
+
+ yymsp += yysize+1;
+ yypParser->yytos = yymsp;
+ yymsp->stateno = (YYACTIONTYPE)yyact;
+ yymsp->major = (YYCODETYPE)yygoto;
+ yyTraceShift(yypParser, yyact, "... then shift");
return yyact;
}
@@ -164556,11 +164556,11 @@ static void yy_parse_failed(
fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
}
#endif
- while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
+ while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
/* Here code is inserted which will be executed whenever the
** parser fails */
-/************ Begin %parse_failure code ***************************************/
-/************ End %parse_failure code *****************************************/
+/************ Begin %parse_failure code ***************************************/
+/************ End %parse_failure code *****************************************/
sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
sqlite3ParserCTX_STORE
}
@@ -164572,20 +164572,20 @@ static void yy_parse_failed(
static void yy_syntax_error(
yyParser *yypParser, /* The parser */
int yymajor, /* The major type of the error token */
- sqlite3ParserTOKENTYPE yyminor /* The minor type of the error token */
+ sqlite3ParserTOKENTYPE yyminor /* The minor type of the error token */
){
sqlite3ParserARG_FETCH
sqlite3ParserCTX_FETCH
-#define TOKEN yyminor
-/************ Begin %syntax_error code ****************************************/
+#define TOKEN yyminor
+/************ Begin %syntax_error code ****************************************/
UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */
- if( TOKEN.z[0] ){
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
- }else{
- sqlite3ErrorMsg(pParse, "incomplete input");
- }
-/************ End %syntax_error code ******************************************/
+ if( TOKEN.z[0] ){
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
+ }else{
+ sqlite3ErrorMsg(pParse, "incomplete input");
+ }
+/************ End %syntax_error code ******************************************/
sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
sqlite3ParserCTX_STORE
}
@@ -164603,14 +164603,14 @@ static void yy_accept(
fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
}
#endif
-#ifndef YYNOERRORRECOVERY
- yypParser->yyerrcnt = -1;
-#endif
- assert( yypParser->yytos==yypParser->yystack );
+#ifndef YYNOERRORRECOVERY
+ yypParser->yyerrcnt = -1;
+#endif
+ assert( yypParser->yytos==yypParser->yystack );
/* Here code is inserted which will be executed whenever the
** parser accepts */
-/*********** Begin %parse_accept code *****************************************/
-/*********** End %parse_accept code *******************************************/
+/*********** Begin %parse_accept code *****************************************/
+/*********** End %parse_accept code *******************************************/
sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
sqlite3ParserCTX_STORE
}
@@ -164652,7 +164652,7 @@ SQLITE_PRIVATE void sqlite3Parser(
sqlite3ParserCTX_FETCH
sqlite3ParserARG_STORE
- assert( yypParser->yytos!=0 );
+ assert( yypParser->yytos!=0 );
#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
yyendofinput = (yymajor==0);
#endif
@@ -164661,12 +164661,12 @@ SQLITE_PRIVATE void sqlite3Parser(
#ifndef NDEBUG
if( yyTraceFILE ){
if( yyact < YY_MIN_REDUCE ){
- fprintf(yyTraceFILE,"%sInput '%s' in state %d\n",
+ fprintf(yyTraceFILE,"%sInput '%s' in state %d\n",
yyTracePrompt,yyTokenName[yymajor],yyact);
- }else{
- fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
+ }else{
+ fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE);
- }
+ }
}
#endif
@@ -164674,7 +164674,7 @@ SQLITE_PRIVATE void sqlite3Parser(
assert( yypParser->yytos>=yypParser->yystack );
assert( yyact==yypParser->yytos->stateno );
yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
- if( yyact >= YY_MIN_REDUCE ){
+ if( yyact >= YY_MIN_REDUCE ){
unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */
#ifndef NDEBUG
assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
@@ -164720,19 +164720,19 @@ SQLITE_PRIVATE void sqlite3Parser(
#endif
}
yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor sqlite3ParserCTX_PARAM);
- }else if( yyact <= YY_MAX_SHIFTREDUCE ){
+ }else if( yyact <= YY_MAX_SHIFTREDUCE ){
yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor);
-#ifndef YYNOERRORRECOVERY
+#ifndef YYNOERRORRECOVERY
yypParser->yyerrcnt--;
-#endif
+#endif
break;
- }else if( yyact==YY_ACCEPT_ACTION ){
- yypParser->yytos--;
- yy_accept(yypParser);
- return;
+ }else if( yyact==YY_ACCEPT_ACTION ){
+ yypParser->yytos--;
+ yy_accept(yypParser);
+ return;
}else{
assert( yyact == YY_ERROR_ACTION );
- yyminorunion.yy0 = yyminor;
+ yyminorunion.yy0 = yyminor;
#ifdef YYERRORSYMBOL
int yymx;
#endif
@@ -164762,9 +164762,9 @@ SQLITE_PRIVATE void sqlite3Parser(
**
*/
if( yypParser->yyerrcnt<0 ){
- yy_syntax_error(yypParser,yymajor,yyminor);
+ yy_syntax_error(yypParser,yymajor,yyminor);
}
- yymx = yypParser->yytos->major;
+ yymx = yypParser->yytos->major;
if( yymx==YYERRORSYMBOL || yyerrorhit ){
#ifndef NDEBUG
if( yyTraceFILE ){
@@ -164772,7 +164772,7 @@ SQLITE_PRIVATE void sqlite3Parser(
yyTracePrompt,yyTokenName[yymajor]);
}
#endif
- yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
+ yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
yymajor = YYNOCODE;
}else{
while( yypParser->yytos > yypParser->yystack ){
@@ -164784,12 +164784,12 @@ SQLITE_PRIVATE void sqlite3Parser(
if( yypParser->yytos <= yypParser->yystack || yymajor==0 ){
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
yy_parse_failed(yypParser);
-#ifndef YYNOERRORRECOVERY
- yypParser->yyerrcnt = -1;
-#endif
+#ifndef YYNOERRORRECOVERY
+ yypParser->yyerrcnt = -1;
+#endif
yymajor = YYNOCODE;
}else if( yymx!=YYERRORSYMBOL ){
- yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
+ yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
}
}
yypParser->yyerrcnt = 3;
@@ -164804,7 +164804,7 @@ SQLITE_PRIVATE void sqlite3Parser(
** Applications can set this macro (for example inside %include) if
** they intend to abandon the parse upon the first syntax error seen.
*/
- yy_syntax_error(yypParser,yymajor, yyminor);
+ yy_syntax_error(yypParser,yymajor, yyminor);
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
break;
#else /* YYERRORSYMBOL is not defined */
@@ -164818,32 +164818,32 @@ SQLITE_PRIVATE void sqlite3Parser(
** three input tokens have been successfully shifted.
*/
if( yypParser->yyerrcnt<=0 ){
- yy_syntax_error(yypParser,yymajor, yyminor);
+ yy_syntax_error(yypParser,yymajor, yyminor);
}
yypParser->yyerrcnt = 3;
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
if( yyendofinput ){
yy_parse_failed(yypParser);
-#ifndef YYNOERRORRECOVERY
- yypParser->yyerrcnt = -1;
-#endif
+#ifndef YYNOERRORRECOVERY
+ yypParser->yyerrcnt = -1;
+#endif
}
break;
#endif
}
}
-#ifndef NDEBUG
- if( yyTraceFILE ){
- yyStackEntry *i;
- char cDiv = '[';
- fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt);
- for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){
- fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]);
- cDiv = ' ';
- }
- fprintf(yyTraceFILE,"]\n");
- }
-#endif
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ yyStackEntry *i;
+ char cDiv = '[';
+ fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt);
+ for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){
+ fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]);
+ cDiv = ' ';
+ }
+ fprintf(yyTraceFILE,"]\n");
+ }
+#endif
return;
}
@@ -164883,56 +164883,56 @@ SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){
/* #include "sqliteInt.h" */
/* #include <stdlib.h> */
-/* Character classes for tokenizing
-**
-** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented
-** using a lookup table, whereas a switch() directly on c uses a binary search.
-** The lookup table is much faster. To maximize speed, and to ensure that
-** a lookup table is used, all of the classes need to be small integers and
-** all of them need to be used within the switch.
-*/
-#define CC_X 0 /* The letter 'x', or start of BLOB literal */
+/* Character classes for tokenizing
+**
+** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented
+** using a lookup table, whereas a switch() directly on c uses a binary search.
+** The lookup table is much faster. To maximize speed, and to ensure that
+** a lookup table is used, all of the classes need to be small integers and
+** all of them need to be used within the switch.
+*/
+#define CC_X 0 /* The letter 'x', or start of BLOB literal */
#define CC_KYWD0 1 /* First letter of a keyword */
#define CC_KYWD 2 /* Alphabetics or '_'. Usable in a keyword */
-#define CC_DIGIT 3 /* Digits */
-#define CC_DOLLAR 4 /* '$' */
-#define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */
-#define CC_VARNUM 6 /* '?'. Numeric SQL variables */
-#define CC_SPACE 7 /* Space characters */
-#define CC_QUOTE 8 /* '"', '\'', or '`'. String literals, quoted ids */
-#define CC_QUOTE2 9 /* '['. [...] style quoted ids */
-#define CC_PIPE 10 /* '|'. Bitwise OR or concatenate */
-#define CC_MINUS 11 /* '-'. Minus or SQL-style comment */
-#define CC_LT 12 /* '<'. Part of < or <= or <> */
-#define CC_GT 13 /* '>'. Part of > or >= */
-#define CC_EQ 14 /* '='. Part of = or == */
-#define CC_BANG 15 /* '!'. Part of != */
-#define CC_SLASH 16 /* '/'. / or c-style comment */
-#define CC_LP 17 /* '(' */
-#define CC_RP 18 /* ')' */
-#define CC_SEMI 19 /* ';' */
-#define CC_PLUS 20 /* '+' */
-#define CC_STAR 21 /* '*' */
-#define CC_PERCENT 22 /* '%' */
-#define CC_COMMA 23 /* ',' */
-#define CC_AND 24 /* '&' */
-#define CC_TILDA 25 /* '~' */
-#define CC_DOT 26 /* '.' */
+#define CC_DIGIT 3 /* Digits */
+#define CC_DOLLAR 4 /* '$' */
+#define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */
+#define CC_VARNUM 6 /* '?'. Numeric SQL variables */
+#define CC_SPACE 7 /* Space characters */
+#define CC_QUOTE 8 /* '"', '\'', or '`'. String literals, quoted ids */
+#define CC_QUOTE2 9 /* '['. [...] style quoted ids */
+#define CC_PIPE 10 /* '|'. Bitwise OR or concatenate */
+#define CC_MINUS 11 /* '-'. Minus or SQL-style comment */
+#define CC_LT 12 /* '<'. Part of < or <= or <> */
+#define CC_GT 13 /* '>'. Part of > or >= */
+#define CC_EQ 14 /* '='. Part of = or == */
+#define CC_BANG 15 /* '!'. Part of != */
+#define CC_SLASH 16 /* '/'. / or c-style comment */
+#define CC_LP 17 /* '(' */
+#define CC_RP 18 /* ')' */
+#define CC_SEMI 19 /* ';' */
+#define CC_PLUS 20 /* '+' */
+#define CC_STAR 21 /* '*' */
+#define CC_PERCENT 22 /* '%' */
+#define CC_COMMA 23 /* ',' */
+#define CC_AND 24 /* '&' */
+#define CC_TILDA 25 /* '~' */
+#define CC_DOT 26 /* '.' */
#define CC_ID 27 /* unicode characters usable in IDs */
#define CC_ILLEGAL 28 /* Illegal character */
#define CC_NUL 29 /* 0x00 */
#define CC_BOM 30 /* First byte of UTF8 BOM: 0xEF 0xBB 0xBF */
-
-static const unsigned char aiClass[] = {
-#ifdef SQLITE_ASCII
-/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */
+
+static const unsigned char aiClass[] = {
+#ifdef SQLITE_ASCII
+/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */
/* 0x */ 29, 28, 28, 28, 28, 28, 28, 28, 28, 7, 7, 28, 7, 7, 28, 28,
/* 1x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-/* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16,
-/* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6,
-/* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+/* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16,
+/* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6,
+/* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 9, 28, 28, 28, 2,
-/* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+/* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28,
/* 8x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 9x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
@@ -164942,9 +164942,9 @@ static const unsigned char aiClass[] = {
/* Dx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* Ex */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 30,
/* Fx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27
-#endif
-#ifdef SQLITE_EBCDIC
-/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */
+#endif
+#ifdef SQLITE_EBCDIC
+/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */
/* 0x */ 29, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 7, 7, 28, 28,
/* 1x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
/* 2x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
@@ -164961,17 +164961,17 @@ static const unsigned char aiClass[] = {
/* Dx */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28,
/* Ex */ 28, 28, 1, 1, 1, 1, 1, 0, 2, 2, 28, 28, 28, 28, 28, 28,
/* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 28, 28, 28, 28, 28, 28,
-#endif
-};
-
+#endif
+};
+
/*
-** The charMap() macro maps alphabetic characters (only) into their
+** The charMap() macro maps alphabetic characters (only) into their
** lower-case ASCII equivalent. On ASCII machines, this is just
** an upper-to-lower case map. On EBCDIC machines we also need
-** to adjust the encoding. The mapping is only valid for alphabetics
+** to adjust the encoding. The mapping is only valid for alphabetics
** which are the only characters for which this feature is used.
-**
-** Used by keywordhash.h
+**
+** Used by keywordhash.h
*/
#ifdef SQLITE_ASCII
# define charMap(X) sqlite3UpperToLower[(unsigned char)X]
@@ -165005,7 +165005,7 @@ const unsigned char ebcdicToAscii[] = {
** returned. If the input is not a keyword, TK_ID is returned.
**
** The implementation of this routine was generated by a program,
-** mkkeywordhash.c, located in the tool subdirectory of the distribution.
+** mkkeywordhash.c, located in the tool subdirectory of the distribution.
** The output of the mkkeywordhash.c program is written into a file
** named keywordhash.h and then included into this source file by
** the #include below.
@@ -165027,7 +165027,7 @@ const unsigned char ebcdicToAscii[] = {
*/
/* Hash score: 231 */
/* zKWText[] encodes 1007 bytes of keyword text in 667 bytes */
-/* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */
+/* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */
/* ABLEFTHENDEFERRABLELSEXCLUDELETEMPORARYISNULLSAVEPOINTERSECT */
/* IESNOTNULLIKEXCEPTRANSACTIONATURALTERAISEXCLUSIVEXISTS */
/* CONSTRAINTOFFSETRIGGERANGENERATEDETACHAVINGLOBEGINNEREFERENCES */
@@ -165040,10 +165040,10 @@ const unsigned char ebcdicToAscii[] = {
/* ETURNINGRIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEWINDOWBY */
/* INITIALLYPRIMARY */
static const char zKWText[666] = {
- 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
- 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
- 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
- 'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F',
+ 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
+ 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
+ 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
+ 'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F',
'E','R','R','A','B','L','E','L','S','E','X','C','L','U','D','E','L','E',
'T','E','M','P','O','R','A','R','Y','I','S','N','U','L','L','S','A','V',
'E','P','O','I','N','T','E','R','S','E','C','T','I','E','S','N','O','T',
@@ -165077,9 +165077,9 @@ static const char zKWText[666] = {
'W','S','U','N','B','O','U','N','D','E','D','U','N','I','O','N','U','S',
'I','N','G','V','A','C','U','U','M','V','I','E','W','I','N','D','O','W',
'B','Y','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R','Y',
-};
-/* aKWHash[i] is the hash value for the i-th keyword */
-static const unsigned char aKWHash[127] = {
+};
+/* aKWHash[i] is the hash value for the i-th keyword */
+static const unsigned char aKWHash[127] = {
84, 92, 134, 82, 105, 29, 0, 0, 94, 0, 85, 72, 0,
53, 35, 86, 15, 0, 42, 97, 54, 89, 135, 19, 0, 0,
140, 0, 40, 129, 0, 22, 107, 0, 9, 0, 0, 123, 80,
@@ -165090,10 +165090,10 @@ static const unsigned char aKWHash[127] = {
50, 124, 0, 100, 0, 18, 121, 144, 56, 130, 139, 88, 83,
37, 30, 126, 0, 0, 108, 51, 131, 128, 0, 34, 0, 0,
132, 0, 98, 38, 39, 0, 20, 45, 117, 93,
-};
-/* aKWNext[] forms the hash collision chain. If aKWHash[i]==0
-** then the i-th keyword has no more hash collisions. Otherwise,
-** the next keyword with the same hash is aKWHash[i]-1. */
+};
+/* aKWNext[] forms the hash collision chain. If aKWHash[i]==0
+** then the i-th keyword has no more hash collisions. Otherwise,
+** the next keyword with the same hash is aKWHash[i]-1. */
static const unsigned char aKWNext[147] = {
0, 0, 0, 0, 4, 0, 43, 0, 0, 106, 114, 0, 0,
0, 2, 0, 0, 143, 0, 0, 0, 13, 0, 0, 0, 0,
@@ -165107,10 +165107,10 @@ static const unsigned char aKWNext[147] = {
112, 21, 7, 67, 0, 79, 96, 118, 0, 0, 68, 0, 0,
99, 44, 0, 55, 0, 76, 0, 95, 32, 33, 57, 25, 0,
102, 0, 0, 87,
-};
-/* aKWLen[i] is the length (in bytes) of the i-th keyword */
+};
+/* aKWLen[i] is the length (in bytes) of the i-th keyword */
static const unsigned char aKWLen[147] = {
- 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6,
+ 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6,
7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 7,
6, 9, 4, 2, 6, 5, 9, 9, 4, 7, 3, 2, 4,
4, 6, 11, 6, 2, 7, 5, 5, 9, 6, 10, 4, 6,
@@ -165122,12 +165122,12 @@ static const unsigned char aKWLen[147] = {
4, 4, 6, 7, 5, 9, 4, 4, 5, 2, 5, 8, 6,
4, 9, 5, 8, 4, 3, 9, 5, 5, 6, 4, 6, 2,
2, 9, 3, 7,
-};
-/* aKWOffset[i] is the index into zKWText[] of the start of
-** the text for the i-th keyword. */
+};
+/* aKWOffset[i] is the index into zKWText[] of the start of
+** the text for the i-th keyword. */
static const unsigned short int aKWOffset[147] = {
- 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33,
- 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81,
+ 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33,
+ 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81,
86, 90, 90, 94, 99, 101, 105, 111, 119, 123, 123, 123, 126,
129, 132, 137, 142, 146, 147, 152, 156, 160, 168, 174, 181, 184,
184, 187, 189, 195, 198, 206, 211, 216, 219, 222, 226, 236, 239,
@@ -165138,8 +165138,8 @@ static const unsigned short int aKWOffset[147] = {
520, 523, 527, 532, 539, 544, 553, 557, 560, 565, 567, 571, 579,
585, 588, 597, 602, 610, 610, 614, 623, 628, 633, 639, 642, 645,
648, 650, 655, 659,
-};
-/* aKWCode[i] is the parser symbol code for the i-th keyword */
+};
+/* aKWCode[i] is the parser symbol code for the i-th keyword */
static const unsigned char aKWCode[147] = {
TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE,
TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN,
@@ -165171,7 +165171,7 @@ static const unsigned char aKWCode[147] = {
TK_ROW, TK_UNBOUNDED, TK_UNION, TK_USING, TK_VACUUM,
TK_VIEW, TK_WINDOW, TK_DO, TK_BY, TK_INITIALLY,
TK_ALL, TK_PRIMARY,
-};
+};
/* Hash table decoded:
** 0: INSERT
** 1: IS
@@ -165301,30 +165301,30 @@ static const unsigned char aKWCode[147] = {
** 125: PRECEDING
** 126: UPDATE UNIQUE
*/
-/* Check to see if z[0..n-1] is a keyword. If it is, write the
-** parser symbol code for that keyword into *pType. Always
-** return the integer n (the length of the token). */
-static int keywordCode(const char *z, int n, int *pType){
- int i, j;
- const char *zKW;
- if( n>=2 ){
+/* Check to see if z[0..n-1] is a keyword. If it is, write the
+** parser symbol code for that keyword into *pType. Always
+** return the integer n (the length of the token). */
+static int keywordCode(const char *z, int n, int *pType){
+ int i, j;
+ const char *zKW;
+ if( n>=2 ){
i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127;
- for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){
- if( aKWLen[i]!=n ) continue;
- zKW = &zKWText[aKWOffset[i]];
-#ifdef SQLITE_ASCII
+ for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){
+ if( aKWLen[i]!=n ) continue;
+ zKW = &zKWText[aKWOffset[i]];
+#ifdef SQLITE_ASCII
if( (z[0]&~0x20)!=zKW[0] ) continue;
if( (z[1]&~0x20)!=zKW[1] ) continue;
j = 2;
- while( j<n && (z[j]&~0x20)==zKW[j] ){ j++; }
-#endif
-#ifdef SQLITE_EBCDIC
+ while( j<n && (z[j]&~0x20)==zKW[j] ){ j++; }
+#endif
+#ifdef SQLITE_EBCDIC
if( toupper(z[0])!=zKW[0] ) continue;
if( toupper(z[1])!=zKW[1] ) continue;
j = 2;
- while( j<n && toupper(z[j])==zKW[j] ){ j++; }
-#endif
- if( j<n ) continue;
+ while( j<n && toupper(z[j])==zKW[j] ){ j++; }
+#endif
+ if( j<n ) continue;
testcase( i==0 ); /* REINDEX */
testcase( i==1 ); /* INDEXED */
testcase( i==2 ); /* INDEX */
@@ -165472,16 +165472,16 @@ static int keywordCode(const char *z, int n, int *pType){
testcase( i==144 ); /* INITIALLY */
testcase( i==145 ); /* ALL */
testcase( i==146 ); /* PRIMARY */
- *pType = aKWCode[i];
- break;
+ *pType = aKWCode[i];
+ break;
}
}
- return n;
+ return n;
}
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
- int id = TK_ID;
- keywordCode((char*)z, n, &id);
- return id;
+ int id = TK_ID;
+ keywordCode((char*)z, n, &id);
+ return id;
}
#define SQLITE_N_KEYWORD 147
SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){
@@ -165623,10 +165623,10 @@ static int analyzeFilterKeyword(const unsigned char *z, int lastToken){
*/
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
int i, c;
- switch( aiClass[*z] ){ /* Switch on the character-class of the first byte
- ** of the token. See the comment on the CC_ defines
- ** above. */
- case CC_SPACE: {
+ switch( aiClass[*z] ){ /* Switch on the character-class of the first byte
+ ** of the token. See the comment on the CC_ defines
+ ** above. */
+ case CC_SPACE: {
testcase( z[0]==' ' );
testcase( z[0]=='\t' );
testcase( z[0]=='\n' );
@@ -165636,7 +165636,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
*tokenType = TK_SPACE;
return i;
}
- case CC_MINUS: {
+ case CC_MINUS: {
if( z[1]=='-' ){
for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
@@ -165645,27 +165645,27 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
*tokenType = TK_MINUS;
return 1;
}
- case CC_LP: {
+ case CC_LP: {
*tokenType = TK_LP;
return 1;
}
- case CC_RP: {
+ case CC_RP: {
*tokenType = TK_RP;
return 1;
}
- case CC_SEMI: {
+ case CC_SEMI: {
*tokenType = TK_SEMI;
return 1;
}
- case CC_PLUS: {
+ case CC_PLUS: {
*tokenType = TK_PLUS;
return 1;
}
- case CC_STAR: {
+ case CC_STAR: {
*tokenType = TK_STAR;
return 1;
}
- case CC_SLASH: {
+ case CC_SLASH: {
if( z[1]!='*' || z[2]==0 ){
*tokenType = TK_SLASH;
return 1;
@@ -165675,15 +165675,15 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
return i;
}
- case CC_PERCENT: {
+ case CC_PERCENT: {
*tokenType = TK_REM;
return 1;
}
- case CC_EQ: {
+ case CC_EQ: {
*tokenType = TK_EQ;
return 1 + (z[1]=='=');
}
- case CC_LT: {
+ case CC_LT: {
if( (c=z[1])=='=' ){
*tokenType = TK_LE;
return 2;
@@ -165698,7 +165698,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
return 1;
}
}
- case CC_GT: {
+ case CC_GT: {
if( (c=z[1])=='=' ){
*tokenType = TK_GE;
return 2;
@@ -165710,16 +165710,16 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
return 1;
}
}
- case CC_BANG: {
+ case CC_BANG: {
if( z[1]!='=' ){
*tokenType = TK_ILLEGAL;
- return 1;
+ return 1;
}else{
*tokenType = TK_NE;
return 2;
}
}
- case CC_PIPE: {
+ case CC_PIPE: {
if( z[1]!='|' ){
*tokenType = TK_BITOR;
return 1;
@@ -165728,19 +165728,19 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
return 2;
}
}
- case CC_COMMA: {
+ case CC_COMMA: {
*tokenType = TK_COMMA;
return 1;
}
- case CC_AND: {
+ case CC_AND: {
*tokenType = TK_BITAND;
return 1;
}
- case CC_TILDA: {
+ case CC_TILDA: {
*tokenType = TK_BITNOT;
return 1;
}
- case CC_QUOTE: {
+ case CC_QUOTE: {
int delim = z[0];
testcase( delim=='`' );
testcase( delim=='\'' );
@@ -165765,7 +165765,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
return i;
}
}
- case CC_DOT: {
+ case CC_DOT: {
#ifndef SQLITE_OMIT_FLOATING_POINT
if( !sqlite3Isdigit(z[1]) )
#endif
@@ -165777,7 +165777,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
** number that begins with ".". Fall thru into the next case */
/* no break */ deliberate_fall_through
}
- case CC_DIGIT: {
+ case CC_DIGIT: {
testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' );
testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' );
testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' );
@@ -165812,18 +165812,18 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
}
return i;
}
- case CC_QUOTE2: {
+ case CC_QUOTE2: {
for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){}
*tokenType = c==']' ? TK_ID : TK_ILLEGAL;
return i;
}
- case CC_VARNUM: {
+ case CC_VARNUM: {
*tokenType = TK_VARIABLE;
for(i=1; sqlite3Isdigit(z[i]); i++){}
return i;
}
- case CC_DOLLAR:
- case CC_VARALPHA: {
+ case CC_DOLLAR:
+ case CC_VARALPHA: {
int n = 0;
testcase( z[0]=='$' ); testcase( z[0]=='@' );
testcase( z[0]==':' ); testcase( z[0]=='#' );
@@ -165853,18 +165853,18 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
return i;
}
case CC_KYWD0: {
- for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
- if( IdChar(z[i]) ){
- /* This token started out using characters that can appear in keywords,
- ** but z[i] is a character not allowed within keywords, so this must
- ** be an identifier instead */
- i++;
- break;
- }
- *tokenType = TK_ID;
- return keywordCode((char*)z, i, tokenType);
- }
- case CC_X: {
+ for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
+ if( IdChar(z[i]) ){
+ /* This token started out using characters that can appear in keywords,
+ ** but z[i] is a character not allowed within keywords, so this must
+ ** be an identifier instead */
+ i++;
+ break;
+ }
+ *tokenType = TK_ID;
+ return keywordCode((char*)z, i, tokenType);
+ }
+ case CC_X: {
#ifndef SQLITE_OMIT_BLOB_LITERAL
testcase( z[0]=='x' ); testcase( z[0]=='X' );
if( z[1]=='\'' ){
@@ -165877,16 +165877,16 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
if( z[i] ) i++;
return i;
}
-#endif
- /* If it is not a BLOB literal, then it must be an ID, since no
- ** SQL keywords start with the letter 'x'. Fall through */
+#endif
+ /* If it is not a BLOB literal, then it must be an ID, since no
+ ** SQL keywords start with the letter 'x'. Fall through */
/* no break */ deliberate_fall_through
}
case CC_KYWD:
- case CC_ID: {
- i = 1;
- break;
- }
+ case CC_ID: {
+ i = 1;
+ break;
+ }
case CC_BOM: {
if( z[1]==0xbb && z[2]==0xbf ){
*tokenType = TK_SPACE;
@@ -165900,13 +165900,13 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
return 0;
}
default: {
- *tokenType = TK_ILLEGAL;
- return 1;
+ *tokenType = TK_ILLEGAL;
+ return 1;
}
}
- while( IdChar(z[i]) ){ i++; }
- *tokenType = TK_ID;
- return i;
+ while( IdChar(z[i]) ){ i++; }
+ *tokenType = TK_ID;
+ return i;
}
/*
@@ -165919,15 +165919,15 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
int nErr = 0; /* Number of errors encountered */
void *pEngine; /* The LEMON-generated LALR(1) parser */
- int n = 0; /* Length of the next token token */
+ int n = 0; /* Length of the next token token */
int tokenType; /* type of the next token */
int lastTokenParsed = -1; /* type of the previous token */
sqlite3 *db = pParse->db; /* The database connection */
int mxSqlLen; /* Max length of an SQL string */
Parse *pParentParse = 0; /* Outer parse context, if any */
-#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
- yyParser sEngine; /* Space to hold the Lemon-generated Parser object */
-#endif
+#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
+ yyParser sEngine; /* Space to hold the Lemon-generated Parser object */
+#endif
VVA_ONLY( u8 startedWithOom = db->mallocFailed );
assert( zSql!=0 );
@@ -165946,41 +165946,41 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
sqlite3ParserTrace(0, 0);
}
#endif
-#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
- pEngine = &sEngine;
+#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
+ pEngine = &sEngine;
sqlite3ParserInit(pEngine, pParse);
-#else
+#else
pEngine = sqlite3ParserAlloc(sqlite3Malloc, pParse);
if( pEngine==0 ){
- sqlite3OomFault(db);
- return SQLITE_NOMEM_BKPT;
+ sqlite3OomFault(db);
+ return SQLITE_NOMEM_BKPT;
}
-#endif
+#endif
assert( pParse->pNewTable==0 );
assert( pParse->pNewTrigger==0 );
assert( pParse->nVar==0 );
- assert( pParse->pVList==0 );
+ assert( pParse->pVList==0 );
pParentParse = db->pParse;
db->pParse = pParse;
- while( 1 ){
+ while( 1 ){
n = sqlite3GetToken((u8*)zSql, &tokenType);
mxSqlLen -= n;
if( mxSqlLen<0 ){
pParse->rc = SQLITE_TOOBIG;
break;
- }
+ }
#ifndef SQLITE_OMIT_WINDOWFUNC
if( tokenType>=TK_WINDOW ){
assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER
|| tokenType==TK_ILLEGAL || tokenType==TK_WINDOW
);
#else
- if( tokenType>=TK_SPACE ){
- assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
+ if( tokenType>=TK_SPACE ){
+ assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
#endif /* SQLITE_OMIT_WINDOWFUNC */
if( AtomicLoad(&db->u1.isInterrupted) ){
- pParse->rc = SQLITE_INTERRUPT;
- break;
+ pParse->rc = SQLITE_INTERRUPT;
+ break;
}
if( tokenType==TK_SPACE ){
zSql += n;
@@ -166009,7 +166009,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
#endif /* SQLITE_OMIT_WINDOWFUNC */
}else{
- sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
+ sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
break;
}
}
@@ -166024,18 +166024,18 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
assert( nErr==0 );
#ifdef YYTRACKMAXSTACKDEPTH
sqlite3_mutex_enter(sqlite3MallocMutex());
- sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
+ sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
sqlite3ParserStackPeak(pEngine)
);
sqlite3_mutex_leave(sqlite3MallocMutex());
#endif /* YYDEBUG */
-#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
- sqlite3ParserFinalize(pEngine);
-#else
+#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
+ sqlite3ParserFinalize(pEngine);
+#else
sqlite3ParserFree(pEngine, sqlite3_free);
-#endif
+#endif
if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM_BKPT;
+ pParse->rc = SQLITE_NOMEM_BKPT;
}
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
@@ -166074,7 +166074,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
if( !IN_RENAME_OBJECT ){
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
}
- sqlite3DbFree(db, pParse->pVList);
+ sqlite3DbFree(db, pParse->pVList);
db->pParse = pParentParse;
assert( nErr==0 || pParse->rc!=SQLITE_OK );
return nErr;
@@ -166320,7 +166320,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[];
** to recognize the end of a trigger can be omitted. All we have to do
** is look for a semicolon that is not part of an string or comment.
*/
-SQLITE_API int sqlite3_complete(const char *zSql){
+SQLITE_API int sqlite3_complete(const char *zSql){
u8 state = 0; /* Current state, using numbers defined in header comment */
u8 token; /* Value of the next token */
@@ -166485,7 +166485,7 @@ SQLITE_API int sqlite3_complete(const char *zSql){
** above, except that the parameter is required to be UTF-16 encoded, not
** UTF-8.
*/
-SQLITE_API int sqlite3_complete16(const void *zSql){
+SQLITE_API int sqlite3_complete16(const void *zSql){
sqlite3_value *pVal;
char const *zSql8;
int rc;
@@ -166500,7 +166500,7 @@ SQLITE_API int sqlite3_complete16(const void *zSql){
if( zSql8 ){
rc = sqlite3_complete(zSql8);
}else{
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
sqlite3ValueFree(pVal);
return rc & 0xff;
@@ -166581,10 +166581,10 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db);
*/
/* #include "sqlite3.h" */
-#ifdef SQLITE_OMIT_VIRTUALTABLE
-# undef SQLITE_ENABLE_RTREE
-#endif
-
+#ifdef SQLITE_OMIT_VIRTUALTABLE
+# undef SQLITE_ENABLE_RTREE
+#endif
+
#if 0
extern "C" {
#endif /* __cplusplus */
@@ -166598,7 +166598,7 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db);
/************** End of rtree.h ***********************************************/
/************** Continuing where we left off in main.c ***********************/
#endif
-#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
+#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
/************** Include sqliteicu.h in the middle of main.c ******************/
/************** Begin file sqliteicu.h ***************************************/
/*
@@ -166656,12 +166656,12 @@ SQLITE_PRIVATE int sqlite3Fts2Init(sqlite3*);
#ifdef SQLITE_ENABLE_FTS5
SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*);
#endif
-#ifdef SQLITE_ENABLE_JSON1
-SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*);
-#endif
-#ifdef SQLITE_ENABLE_STMTVTAB
-SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*);
-#endif
+#ifdef SQLITE_ENABLE_JSON1
+SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*);
+#endif
+#ifdef SQLITE_ENABLE_STMTVTAB
+SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*);
+#endif
/*
** An array of pointers to extension initializer functions for
@@ -166677,9 +166677,9 @@ static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
#ifdef SQLITE_ENABLE_FTS3
sqlite3Fts3Init,
#endif
-#ifdef SQLITE_ENABLE_FTS5
+#ifdef SQLITE_ENABLE_FTS5
sqlite3Fts5Init,
-#endif
+#endif
#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
sqlite3IcuInit,
#endif
@@ -166714,26 +166714,26 @@ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns
** a pointer to the to the sqlite3_version[] string constant.
*/
-SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
+SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
-/* IMPLEMENTATION-OF: R-25063-23286 The sqlite3_sourceid() function returns a
+/* IMPLEMENTATION-OF: R-25063-23286 The sqlite3_sourceid() function returns a
** pointer to a string constant whose value is the same as the
-** SQLITE_SOURCE_ID C preprocessor macro. Except if SQLite is built using
-** an edited copy of the amalgamation, then the last four characters of
-** the hash might be different from SQLITE_SOURCE_ID.
+** SQLITE_SOURCE_ID C preprocessor macro. Except if SQLite is built using
+** an edited copy of the amalgamation, then the last four characters of
+** the hash might be different from SQLITE_SOURCE_ID.
*/
-/* SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } */
+/* SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } */
/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function
** returns an integer equal to SQLITE_VERSION_NUMBER.
*/
-SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
+SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns
** zero if and only if SQLite was compiled with mutexing code omitted due to
** the SQLITE_THREADSAFE compile-time option being set to 0.
*/
-SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
+SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
/*
** When compiling the test fixture or with debugging enabled (on Win32),
@@ -166806,7 +166806,7 @@ SQLITE_API char *sqlite3_data_directory = 0;
** * Recursive calls to this routine from thread X return immediately
** without blocking.
*/
-SQLITE_API int sqlite3_initialize(void){
+SQLITE_API int sqlite3_initialize(void){
MUTEX_LOGIC( sqlite3_mutex *pMainMtx; ) /* The main static mutex */
int rc; /* Result code */
#ifdef SQLITE_EXTRA_INIT
@@ -166864,7 +166864,7 @@ SQLITE_API int sqlite3_initialize(void){
sqlite3GlobalConfig.pInitMutex =
sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
}
}
@@ -166896,14 +166896,14 @@ SQLITE_API int sqlite3_initialize(void){
sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
sqlite3GlobalConfig.inProgress = 1;
-#ifdef SQLITE_ENABLE_SQLLOG
- {
- extern void sqlite3_init_sqllog(void);
- sqlite3_init_sqllog();
- }
-#endif
- memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions));
- sqlite3RegisterBuiltinFunctions();
+#ifdef SQLITE_ENABLE_SQLLOG
+ {
+ extern void sqlite3_init_sqllog(void);
+ sqlite3_init_sqllog();
+ }
+#endif
+ memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions));
+ sqlite3RegisterBuiltinFunctions();
if( sqlite3GlobalConfig.isPCacheInit==0 ){
rc = sqlite3PcacheInitialize();
}
@@ -166981,7 +166981,7 @@ SQLITE_API int sqlite3_initialize(void){
** on when SQLite is already shut down. If SQLite is already shut down
** when this routine is invoked, then this routine is a harmless no-op.
*/
-SQLITE_API int sqlite3_shutdown(void){
+SQLITE_API int sqlite3_shutdown(void){
#ifdef SQLITE_OMIT_WSD
int rc = sqlite3_wsd_init(4096, 24);
if( rc!=SQLITE_OK ){
@@ -167035,7 +167035,7 @@ SQLITE_API int sqlite3_shutdown(void){
** threadsafe. Failure to heed these warnings can lead to unpredictable
** behavior.
*/
-SQLITE_API int sqlite3_config(int op, ...){
+SQLITE_API int sqlite3_config(int op, ...){
va_list ap;
int rc = SQLITE_OK;
@@ -167116,15 +167116,15 @@ SQLITE_API int sqlite3_config(int op, ...){
sqlite3GlobalConfig.bMemstat = va_arg(ap, int);
break;
}
- case SQLITE_CONFIG_SMALL_MALLOC: {
- sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int);
+ case SQLITE_CONFIG_SMALL_MALLOC: {
+ sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int);
break;
}
case SQLITE_CONFIG_PAGECACHE: {
- /* EVIDENCE-OF: R-18761-36601 There are three arguments to
- ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem),
- ** the size of each page cache line (sz), and the number of cache lines
- ** (N). */
+ /* EVIDENCE-OF: R-18761-36601 There are three arguments to
+ ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem),
+ ** the size of each page cache line (sz), and the number of cache lines
+ ** (N). */
sqlite3GlobalConfig.pPage = va_arg(ap, void*);
sqlite3GlobalConfig.szPage = va_arg(ap, int);
sqlite3GlobalConfig.nPage = va_arg(ap, int);
@@ -167310,11 +167310,11 @@ SQLITE_API int sqlite3_config(int op, ...){
break;
}
- case SQLITE_CONFIG_STMTJRNL_SPILL: {
- sqlite3GlobalConfig.nStmtSpill = va_arg(ap, int);
- break;
- }
-
+ case SQLITE_CONFIG_STMTJRNL_SPILL: {
+ sqlite3GlobalConfig.nStmtSpill = va_arg(ap, int);
+ break;
+ }
+
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
case SQLITE_CONFIG_SORTERREF_SIZE: {
int iVal = va_arg(ap, int);
@@ -167360,7 +167360,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
int nBig; /* Number of full-size slots */
int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */
- if( sqlite3LookasideUsed(db,0)>0 ){
+ if( sqlite3LookasideUsed(db,0)>0 ){
return SQLITE_BUSY;
}
/* Free any existing lookaside buffer for this handle before
@@ -167403,7 +167403,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
nBig = nSm = 0;
}
db->lookaside.pStart = pStart;
- db->lookaside.pInit = 0;
+ db->lookaside.pInit = 0;
db->lookaside.pFree = 0;
db->lookaside.sz = (u16)sz;
db->lookaside.szTrue = (u16)sz;
@@ -167413,8 +167413,8 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
assert( sz > (int)sizeof(LookasideSlot*) );
p = (LookasideSlot*)pStart;
for(i=0; i<nBig; i++){
- p->pNext = db->lookaside.pInit;
- db->lookaside.pInit = p;
+ p->pNext = db->lookaside.pInit;
+ db->lookaside.pInit = p;
p = (LookasideSlot*)&((u8*)p)[sz];
}
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
@@ -167429,7 +167429,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
assert( ((uptr)p)<=szAlloc + (uptr)pStart );
db->lookaside.pEnd = p;
- db->lookaside.bDisable = 0;
+ db->lookaside.bDisable = 0;
db->lookaside.bMalloced = pBuf==0 ?1:0;
db->lookaside.nSlot = nBig+nSm;
}else{
@@ -167440,10 +167440,10 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
db->lookaside.pMiddle = db;
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
db->lookaside.pEnd = db;
- db->lookaside.bDisable = 1;
+ db->lookaside.bDisable = 1;
db->lookaside.sz = 0;
db->lookaside.bMalloced = 0;
- db->lookaside.nSlot = 0;
+ db->lookaside.nSlot = 0;
}
assert( sqlite3LookasideUsed(db,0)==0 );
#endif /* SQLITE_OMIT_LOOKASIDE */
@@ -167453,7 +167453,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
/*
** Return the mutex associated with a database connection.
*/
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
+SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -167467,7 +167467,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
** Free up as much memory as we can from the given database
** connection.
*/
-SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
+SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
int i;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -167488,50 +167488,50 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
}
/*
-** Flush any dirty pages in the pager-cache for any attached database
-** to disk.
-*/
-SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){
- int i;
- int rc = SQLITE_OK;
- int bSeenBusy = 0;
-
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
-#endif
- sqlite3_mutex_enter(db->mutex);
- sqlite3BtreeEnterAll(db);
- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
+** Flush any dirty pages in the pager-cache for any attached database
+** to disk.
+*/
+SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){
+ int i;
+ int rc = SQLITE_OK;
+ int bSeenBusy = 0;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
+ sqlite3_mutex_enter(db->mutex);
+ sqlite3BtreeEnterAll(db);
+ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
if( pBt && sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){
- Pager *pPager = sqlite3BtreePager(pBt);
- rc = sqlite3PagerFlush(pPager);
- if( rc==SQLITE_BUSY ){
- bSeenBusy = 1;
- rc = SQLITE_OK;
- }
- }
- }
- sqlite3BtreeLeaveAll(db);
- sqlite3_mutex_leave(db->mutex);
- return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc);
-}
-
-/*
+ Pager *pPager = sqlite3BtreePager(pBt);
+ rc = sqlite3PagerFlush(pPager);
+ if( rc==SQLITE_BUSY ){
+ bSeenBusy = 1;
+ rc = SQLITE_OK;
+ }
+ }
+ }
+ sqlite3BtreeLeaveAll(db);
+ sqlite3_mutex_leave(db->mutex);
+ return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc);
+}
+
+/*
** Configuration settings for an individual database connection
*/
-SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
+SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
va_list ap;
int rc;
va_start(ap, op);
switch( op ){
- case SQLITE_DBCONFIG_MAINDBNAME: {
- /* IMP: R-06824-28531 */
- /* IMP: R-36257-52125 */
- db->aDb[0].zDbSName = va_arg(ap,char*);
- rc = SQLITE_OK;
- break;
- }
+ case SQLITE_DBCONFIG_MAINDBNAME: {
+ /* IMP: R-06824-28531 */
+ /* IMP: R-36257-52125 */
+ db->aDb[0].zDbSName = va_arg(ap,char*);
+ rc = SQLITE_OK;
+ break;
+ }
case SQLITE_DBCONFIG_LOOKASIDE: {
void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
int sz = va_arg(ap, int); /* IMP: R-47871-25994 */
@@ -167544,14 +167544,14 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
int op; /* The opcode */
u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */
} aFlagOp[] = {
- { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
- { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
+ { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
+ { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
{ SQLITE_DBCONFIG_ENABLE_VIEW, SQLITE_EnableView },
- { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
- { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
- { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
- { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
- { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
+ { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
+ { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
+ { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
+ { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
+ { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
{ SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase },
{ SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive },
{ SQLITE_DBCONFIG_WRITABLE_SCHEMA, SQLITE_WriteSchema|
@@ -167606,7 +167606,7 @@ static int binCollFunc(
/* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
** strings byte by byte using the memcmp() function from the standard C
** library. */
- assert( pKey1 && pKey2 );
+ assert( pKey1 && pKey2 );
rc = memcmp(pKey1, pKey2, n);
if( rc==0 ){
rc = nKey1 - nKey2;
@@ -167664,7 +167664,7 @@ static int nocaseCollatingFunc(
/*
** Return the ROWID of the most recent insert
*/
-SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
+SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -167675,21 +167675,21 @@ SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
}
/*
-** Set the value returned by the sqlite3_last_insert_rowid() API function.
-*/
-SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !sqlite3SafetyCheckOk(db) ){
- (void)SQLITE_MISUSE_BKPT;
- return;
- }
-#endif
- sqlite3_mutex_enter(db->mutex);
- db->lastRowid = iRowid;
- sqlite3_mutex_leave(db->mutex);
-}
-
-/*
+** Set the value returned by the sqlite3_last_insert_rowid() API function.
+*/
+SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return;
+ }
+#endif
+ sqlite3_mutex_enter(db->mutex);
+ db->lastRowid = iRowid;
+ sqlite3_mutex_leave(db->mutex);
+}
+
+/*
** Return the number of changes in the most recent call to sqlite3_exec().
*/
SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3 *db){
@@ -167763,7 +167763,7 @@ static void functionDestroy(sqlite3 *db, FuncDef *p){
static void disconnectAllVtab(sqlite3 *db){
#ifndef SQLITE_OMIT_VIRTUALTABLE
int i;
- HashElem *p;
+ HashElem *p;
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
Schema *pSchema = db->aDb[i].pSchema;
@@ -167774,12 +167774,12 @@ static void disconnectAllVtab(sqlite3 *db){
}
}
}
- for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){
- Module *pMod = (Module *)sqliteHashData(p);
- if( pMod->pEpoTab ){
- sqlite3VtabDisconnect(db, pMod->pEpoTab);
- }
- }
+ for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){
+ Module *pMod = (Module *)sqliteHashData(p);
+ if( pMod->pEpoTab ){
+ sqlite3VtabDisconnect(db, pMod->pEpoTab);
+ }
+ }
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
#else
@@ -167815,9 +167815,9 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
- if( db->mTrace & SQLITE_TRACE_CLOSE ){
+ if( db->mTrace & SQLITE_TRACE_CLOSE ){
db->trace.xV2(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0);
- }
+ }
/* Force xDisconnect calls on all virtual tables */
disconnectAllVtab(db);
@@ -167894,8 +167894,8 @@ SQLITE_API int sqlite3_txn_state(sqlite3 *db, const char *zSchema){
** unclosed resources, and arranges for deallocation when the last
** prepare statement or sqlite3_backup closes.
*/
-SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
-SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
+SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
+SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
/*
@@ -167961,17 +167961,17 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
*/
sqlite3ConnectionClosed(db);
- for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
- FuncDef *pNext, *p;
- p = sqliteHashData(i);
- do{
- functionDestroy(db, p);
- pNext = p->pNext;
- sqlite3DbFree(db, p);
- p = pNext;
- }while( p );
- }
- sqlite3HashClear(&db->aFunc);
+ for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
+ FuncDef *pNext, *p;
+ p = sqliteHashData(i);
+ do{
+ functionDestroy(db, p);
+ pNext = p->pNext;
+ sqlite3DbFree(db, p);
+ p = pNext;
+ }while( p );
+ }
+ sqlite3HashClear(&db->aFunc);
for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
CollSeq *pColl = (CollSeq *)sqliteHashData(i);
/* Invoke any destructors registered for collation sequence user data. */
@@ -167986,7 +167986,7 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
#ifndef SQLITE_OMIT_VIRTUALTABLE
for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){
Module *pMod = (Module *)sqliteHashData(i);
- sqlite3VtabEponymousTableClear(db, pMod);
+ sqlite3VtabEponymousTableClear(db, pMod);
sqlite3VtabModuleUnref(db, pMod);
}
sqlite3HashClear(&db->aModule);
@@ -168015,7 +168015,7 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
sqlite3_mutex_leave(db->mutex);
db->eOpenState = SQLITE_STATE_CLOSED;
sqlite3_mutex_free(db->mutex);
- assert( sqlite3LookasideUsed(db,0)==0 );
+ assert( sqlite3LookasideUsed(db,0)==0 );
if( db->lookaside.bMalloced ){
sqlite3_free(db->lookaside.pStart);
}
@@ -168043,7 +168043,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
** the database rollback and schema reset, which can cause false
** corruption reports in some cases. */
sqlite3BtreeEnterAll(db);
- schemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0 && db->init.busy==0;
+ schemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0 && db->init.busy==0;
for(i=0; i<db->nDb; i++){
Btree *p = db->aDb[i].pBt;
@@ -168099,10 +168099,10 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break;
- case SQLITE_READONLY_CANTINIT: zName = "SQLITE_READONLY_CANTINIT"; break;
+ case SQLITE_READONLY_CANTINIT: zName = "SQLITE_READONLY_CANTINIT"; break;
case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break;
case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break;
- case SQLITE_READONLY_DIRECTORY: zName = "SQLITE_READONLY_DIRECTORY";break;
+ case SQLITE_READONLY_DIRECTORY: zName = "SQLITE_READONLY_DIRECTORY";break;
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break;
@@ -168193,10 +168193,10 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){
static const char* const aMsg[] = {
/* SQLITE_OK */ "not an error",
- /* SQLITE_ERROR */ "SQL logic error",
+ /* SQLITE_ERROR */ "SQL logic error",
/* SQLITE_INTERNAL */ 0,
/* SQLITE_PERM */ "access permission denied",
- /* SQLITE_ABORT */ "query aborted",
+ /* SQLITE_ABORT */ "query aborted",
/* SQLITE_BUSY */ "database is locked",
/* SQLITE_LOCKED */ "database table is locked",
/* SQLITE_NOMEM */ "out of memory",
@@ -168208,21 +168208,21 @@ SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){
/* SQLITE_FULL */ "database or disk is full",
/* SQLITE_CANTOPEN */ "unable to open database file",
/* SQLITE_PROTOCOL */ "locking protocol",
- /* SQLITE_EMPTY */ 0,
+ /* SQLITE_EMPTY */ 0,
/* SQLITE_SCHEMA */ "database schema has changed",
/* SQLITE_TOOBIG */ "string or blob too big",
/* SQLITE_CONSTRAINT */ "constraint failed",
/* SQLITE_MISMATCH */ "datatype mismatch",
- /* SQLITE_MISUSE */ "bad parameter or other API misuse",
-#ifdef SQLITE_DISABLE_LFS
+ /* SQLITE_MISUSE */ "bad parameter or other API misuse",
+#ifdef SQLITE_DISABLE_LFS
/* SQLITE_NOLFS */ "large file support is disabled",
-#else
- /* SQLITE_NOLFS */ 0,
-#endif
+#else
+ /* SQLITE_NOLFS */ 0,
+#endif
/* SQLITE_AUTH */ "authorization denied",
- /* SQLITE_FORMAT */ 0,
- /* SQLITE_RANGE */ "column index out of range",
- /* SQLITE_NOTADB */ "file is not a database",
+ /* SQLITE_FORMAT */ 0,
+ /* SQLITE_RANGE */ "column index out of range",
+ /* SQLITE_NOTADB */ "file is not a database",
/* SQLITE_NOTICE */ "notification message",
/* SQLITE_WARNING */ "warning message",
};
@@ -168328,7 +168328,7 @@ SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
** This routine sets the busy callback for an Sqlite database to the
** given callback function with the given argument.
*/
-SQLITE_API int sqlite3_busy_handler(
+SQLITE_API int sqlite3_busy_handler(
sqlite3 *db,
int (*xBusy)(void*,int),
void *pArg
@@ -168351,7 +168351,7 @@ SQLITE_API int sqlite3_busy_handler(
** given callback function with the given argument. The progress callback will
** be invoked every nOps opcodes.
*/
-SQLITE_API void sqlite3_progress_handler(
+SQLITE_API void sqlite3_progress_handler(
sqlite3 *db,
int nOps,
int (*xProgress)(void*),
@@ -168382,7 +168382,7 @@ SQLITE_API void sqlite3_progress_handler(
** This routine installs a default busy handler that waits for the
** specified number of milliseconds before returning 0.
*/
-SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
+SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
@@ -168399,7 +168399,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
/*
** Cause any pending operation to stop at its earliest opportunity.
*/
-SQLITE_API void sqlite3_interrupt(sqlite3 *db){
+SQLITE_API void sqlite3_interrupt(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) ){
(void)SQLITE_MISUSE_BKPT;
@@ -168422,7 +168422,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
int nArg,
int enc,
void *pUserData,
- void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+ void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
void (*xStep)(sqlite3_context*,int,sqlite3_value **),
void (*xFinal)(sqlite3_context*),
void (*xValue)(sqlite3_context*),
@@ -168501,7 +168501,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
** is being overridden/deleted but there are no active VMs, allow the
** operation to continue but invalidate all precompiled statements.
*/
- p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0);
+ p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0);
if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){
if( db->nVdbeActive ){
sqlite3ErrorWithMsg(db, SQLITE_BUSY,
@@ -168517,10 +168517,10 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
return SQLITE_OK;
}
- p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1);
+ p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1);
assert(p || db->mallocFailed);
if( !p ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
/* If an older version of the function with a configured destructor is
@@ -168530,11 +168530,11 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
if( pDestructor ){
pDestructor->nRef++;
}
- p->u.pDestructor = pDestructor;
+ p->u.pDestructor = pDestructor;
p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
testcase( p->funcFlags & SQLITE_DETERMINISTIC );
testcase( p->funcFlags & SQLITE_DIRECTONLY );
- p->xSFunc = xSFunc ? xSFunc : xStep;
+ p->xSFunc = xSFunc ? xSFunc : xStep;
p->xFinalize = xFinal;
p->xValue = xValue;
p->xInverse = xInverse;
@@ -168645,13 +168645,13 @@ SQLITE_API int sqlite3_create_window_function(
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int sqlite3_create_function16(
+SQLITE_API int sqlite3_create_function16(
sqlite3 *db,
const void *zFunctionName,
int nArg,
int eTextRep,
void *p,
- void (*xSFunc)(sqlite3_context*,int,sqlite3_value**),
+ void (*xSFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
){
@@ -168707,7 +168707,7 @@ static void sqlite3InvalidFunction(
** A global function must exist in order for name resolution to work
** properly.
*/
-SQLITE_API int sqlite3_overload_function(
+SQLITE_API int sqlite3_overload_function(
sqlite3 *db,
const char *zName,
int nArg
@@ -168739,8 +168739,8 @@ SQLITE_API int sqlite3_overload_function(
** trace is a pointer to a function that is invoked at the start of each
** SQL statement.
*/
-#ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){
+#ifndef SQLITE_OMIT_DEPRECATED
+SQLITE_API void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){
void *pOld;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -168751,38 +168751,38 @@ SQLITE_API void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), vo
#endif
sqlite3_mutex_enter(db->mutex);
pOld = db->pTraceArg;
- db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0;
+ db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0;
db->trace.xLegacy = xTrace;
db->pTraceArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pOld;
}
-#endif /* SQLITE_OMIT_DEPRECATED */
-
-/* Register a trace callback using the version-2 interface.
-*/
-SQLITE_API int sqlite3_trace_v2(
- sqlite3 *db, /* Trace this connection */
- unsigned mTrace, /* Mask of events to be traced */
- int(*xTrace)(unsigned,void*,void*,void*), /* Callback to invoke */
- void *pArg /* Context */
-){
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !sqlite3SafetyCheckOk(db) ){
- return SQLITE_MISUSE_BKPT;
- }
-#endif
- sqlite3_mutex_enter(db->mutex);
- if( mTrace==0 ) xTrace = 0;
- if( xTrace==0 ) mTrace = 0;
- db->mTrace = mTrace;
+#endif /* SQLITE_OMIT_DEPRECATED */
+
+/* Register a trace callback using the version-2 interface.
+*/
+SQLITE_API int sqlite3_trace_v2(
+ sqlite3 *db, /* Trace this connection */
+ unsigned mTrace, /* Mask of events to be traced */
+ int(*xTrace)(unsigned,void*,void*,void*), /* Callback to invoke */
+ void *pArg /* Context */
+){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
+ sqlite3_mutex_enter(db->mutex);
+ if( mTrace==0 ) xTrace = 0;
+ if( xTrace==0 ) mTrace = 0;
+ db->mTrace = mTrace;
db->trace.xV2 = xTrace;
- db->pTraceArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_DEPRECATED
+ db->pTraceArg = pArg;
+ sqlite3_mutex_leave(db->mutex);
+ return SQLITE_OK;
+}
+
+#ifndef SQLITE_OMIT_DEPRECATED
/*
** Register a profile function. The pArg from the previously registered
** profile function is returned.
@@ -168791,7 +168791,7 @@ SQLITE_API int sqlite3_trace_v2(
** profile is a pointer to a function that is invoked at the conclusion of
** each SQL statement that is run.
*/
-SQLITE_API void *sqlite3_profile(
+SQLITE_API void *sqlite3_profile(
sqlite3 *db,
void (*xProfile)(void*,const char*,sqlite_uint64),
void *pArg
@@ -168813,7 +168813,7 @@ SQLITE_API void *sqlite3_profile(
sqlite3_mutex_leave(db->mutex);
return pOld;
}
-#endif /* SQLITE_OMIT_DEPRECATED */
+#endif /* SQLITE_OMIT_DEPRECATED */
#endif /* SQLITE_OMIT_TRACE */
/*
@@ -168821,7 +168821,7 @@ SQLITE_API void *sqlite3_profile(
** If the invoked function returns non-zero, then the commit becomes a
** rollback.
*/
-SQLITE_API void *sqlite3_commit_hook(
+SQLITE_API void *sqlite3_commit_hook(
sqlite3 *db, /* Attach the hook to this database */
int (*xCallback)(void*), /* Function to invoke on each commit */
void *pArg /* Argument to the function */
@@ -168846,7 +168846,7 @@ SQLITE_API void *sqlite3_commit_hook(
** Register a callback to be invoked each time a row is updated,
** inserted or deleted using this database connection.
*/
-SQLITE_API void *sqlite3_update_hook(
+SQLITE_API void *sqlite3_update_hook(
sqlite3 *db, /* Attach the hook to this database */
void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
void *pArg /* Argument to the function */
@@ -168871,7 +168871,7 @@ SQLITE_API void *sqlite3_update_hook(
** Register a callback to be invoked each time a transaction is rolled
** back by this database connection.
*/
-SQLITE_API void *sqlite3_rollback_hook(
+SQLITE_API void *sqlite3_rollback_hook(
sqlite3 *db, /* Attach the hook to this database */
void (*xCallback)(void*), /* Callback function */
void *pArg /* Argument to the function */
@@ -168892,27 +168892,27 @@ SQLITE_API void *sqlite3_rollback_hook(
return pRet;
}
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
-/*
-** Register a callback to be invoked each time a row is updated,
-** inserted or deleted using this database connection.
-*/
-SQLITE_API void *sqlite3_preupdate_hook(
- sqlite3 *db, /* Attach the hook to this database */
- void(*xCallback)( /* Callback function */
- void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64),
- void *pArg /* First callback argument */
-){
- void *pRet;
- sqlite3_mutex_enter(db->mutex);
- pRet = db->pPreUpdateArg;
- db->xPreUpdateCallback = xCallback;
- db->pPreUpdateArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pRet;
-}
-#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
-
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** Register a callback to be invoked each time a row is updated,
+** inserted or deleted using this database connection.
+*/
+SQLITE_API void *sqlite3_preupdate_hook(
+ sqlite3 *db, /* Attach the hook to this database */
+ void(*xCallback)( /* Callback function */
+ void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64),
+ void *pArg /* First callback argument */
+){
+ void *pRet;
+ sqlite3_mutex_enter(db->mutex);
+ pRet = db->pPreUpdateArg;
+ db->xPreUpdateCallback = xCallback;
+ db->pPreUpdateArg = pArg;
+ sqlite3_mutex_leave(db->mutex);
+ return pRet;
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
/*
** Register a function to be invoked prior to each autovacuum that
** determines the number of pages to vacuum.
@@ -168974,7 +168974,7 @@ SQLITE_PRIVATE int sqlite3WalDefaultHook(
** using sqlite3_wal_hook() disables the automatic checkpoint mechanism
** configured by this function.
*/
-SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
+SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
#ifdef SQLITE_OMIT_WAL
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(nFrame);
@@ -168995,7 +168995,7 @@ SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
** Register a callback to be invoked each time a transaction is written
** into the write-ahead-log by this database connection.
*/
-SQLITE_API void *sqlite3_wal_hook(
+SQLITE_API void *sqlite3_wal_hook(
sqlite3 *db, /* Attach the hook to this db handle */
int(*xCallback)(void *, sqlite3*, const char*, int),
void *pArg /* First argument passed to xCallback() */
@@ -169022,7 +169022,7 @@ SQLITE_API void *sqlite3_wal_hook(
/*
** Checkpoint database zDb.
*/
-SQLITE_API int sqlite3_wal_checkpoint_v2(
+SQLITE_API int sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -169068,13 +169068,13 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
sqlite3Error(db, rc);
}
rc = sqlite3ApiExit(db, rc);
-
- /* If there are no active statements, clear the interrupt flag at this
- ** point. */
- if( db->nVdbeActive==0 ){
+
+ /* If there are no active statements, clear the interrupt flag at this
+ ** point. */
+ if( db->nVdbeActive==0 ){
AtomicStore(&db->u1.isInterrupted, 0);
- }
-
+ }
+
sqlite3_mutex_leave(db->mutex);
return rc;
#endif
@@ -169086,7 +169086,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
** to contains a zero-length string, all attached databases are
** checkpointed.
*/
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
+SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
/* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to
** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */
return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0);
@@ -169110,8 +169110,8 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
** checkpointed. If an error is encountered it is returned immediately -
** no attempt is made to checkpoint any remaining databases.
**
-** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART
-** or TRUNCATE.
+** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART
+** or TRUNCATE.
*/
SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){
int rc = SQLITE_OK; /* Return code */
@@ -169180,17 +169180,17 @@ SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
-SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
+SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
const char *z;
if( !db ){
- return sqlite3ErrStr(SQLITE_NOMEM_BKPT);
+ return sqlite3ErrStr(SQLITE_NOMEM_BKPT);
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
return sqlite3ErrStr(SQLITE_MISUSE_BKPT);
}
sqlite3_mutex_enter(db->mutex);
if( db->mallocFailed ){
- z = sqlite3ErrStr(SQLITE_NOMEM_BKPT);
+ z = sqlite3ErrStr(SQLITE_NOMEM_BKPT);
}else{
testcase( db->pErr==0 );
z = db->errCode ? (char*)sqlite3_value_text(db->pErr) : 0;
@@ -169208,14 +169208,14 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
** Return UTF-16 encoded English language explanation of the most recent
** error.
*/
-SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
+SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
static const u16 outOfMem[] = {
'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
};
static const u16 misuse[] = {
- 'b', 'a', 'd', ' ', 'p', 'a', 'r', 'a', 'm', 'e', 't', 'e', 'r', ' ',
- 'o', 'r', ' ', 'o', 't', 'h', 'e', 'r', ' ', 'A', 'P', 'I', ' ',
- 'm', 'i', 's', 'u', 's', 'e', 0
+ 'b', 'a', 'd', ' ', 'p', 'a', 'r', 'a', 'm', 'e', 't', 'e', 'r', ' ',
+ 'o', 'r', ' ', 'o', 't', 'h', 'e', 'r', ' ', 'A', 'P', 'I', ' ',
+ 'm', 'i', 's', 'u', 's', 'e', 0
};
const void *z;
@@ -169239,7 +169239,7 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
** be cleared before returning. Do this directly, instead of via
** sqlite3ApiExit(), to avoid setting the database handle error message.
*/
- sqlite3OomClear(db);
+ sqlite3OomClear(db);
}
sqlite3_mutex_leave(db->mutex);
return z;
@@ -169250,26 +169250,26 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
** Return the most recent error code generated by an SQLite routine. If NULL is
** passed to this function, we assume a malloc() failed during sqlite3_open().
*/
-SQLITE_API int sqlite3_errcode(sqlite3 *db){
+SQLITE_API int sqlite3_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
if( !db || db->mallocFailed ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
return db->errCode & db->errMask;
}
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
+SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
if( !db || db->mallocFailed ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}
return db->errCode;
}
-SQLITE_API int sqlite3_system_errno(sqlite3 *db){
- return db ? db->iSysErrno : 0;
+SQLITE_API int sqlite3_system_errno(sqlite3 *db){
+ return db ? db->iSysErrno : 0;
}
/*
@@ -169277,7 +169277,7 @@ SQLITE_API int sqlite3_system_errno(sqlite3 *db){
** argument. For now, this simply calls the internal sqlite3ErrStr()
** function.
*/
-SQLITE_API const char *sqlite3_errstr(int rc){
+SQLITE_API const char *sqlite3_errstr(int rc){
return sqlite3ErrStr(rc);
}
@@ -169347,7 +169347,7 @@ static int createCollation(
}
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
- if( pColl==0 ) return SQLITE_NOMEM_BKPT;
+ if( pColl==0 ) return SQLITE_NOMEM_BKPT;
pColl->xCmp = xCompare;
pColl->pUser = pCtx;
pColl->xDel = xDel;
@@ -169395,8 +169395,8 @@ static const int aHardLimit[] = {
#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>127
-# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127
+#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127
+# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127
#endif
#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
# error SQLITE_MAX_ATTACHED must be between 0 and 125
@@ -169425,7 +169425,7 @@ static const int aHardLimit[] = {
** It merely prevents new constructs that exceed the limit
** from forming.
*/
-SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
+SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
int oldLimit;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -169530,7 +169530,7 @@ SQLITE_PRIVATE int sqlite3ParseUri(
for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
zFile = sqlite3_malloc64(nByte);
- if( !zFile ) return SQLITE_NOMEM_BKPT;
+ if( !zFile ) return SQLITE_NOMEM_BKPT;
memset(zFile, 0, 4); /* 4-byte of 0x00 is the start of DB name marker */
zFile += 4;
@@ -169584,7 +169584,7 @@ SQLITE_PRIVATE int sqlite3ParseUri(
assert( octet>=0 && octet<256 );
if( octet==0 ){
-#ifndef SQLITE_ENABLE_URI_00_ERROR
+#ifndef SQLITE_ENABLE_URI_00_ERROR
/* This branch is taken when "%00" appears within the URI. In this
** case we ignore all text in the remainder of the path, name or
** value currently being parsed. So ignore the current character
@@ -169597,12 +169597,12 @@ SQLITE_PRIVATE int sqlite3ParseUri(
iIn++;
}
continue;
-#else
- /* If ENABLE_URI_00_ERROR is defined, "%00" in a URI is an error. */
- *pzErrMsg = sqlite3_mprintf("unexpected %%00 in uri");
- rc = SQLITE_ERROR;
- goto parse_uri_out;
-#endif
+#else
+ /* If ENABLE_URI_00_ERROR is defined, "%00" in a URI is an error. */
+ *pzErrMsg = sqlite3_mprintf("unexpected %%00 in uri");
+ rc = SQLITE_ERROR;
+ goto parse_uri_out;
+#endif
}
c = octet;
}else if( eState==1 && (c=='&' || c=='=') ){
@@ -169705,12 +169705,12 @@ SQLITE_PRIVATE int sqlite3ParseUri(
}else{
zFile = sqlite3_malloc64(nUri+8);
- if( !zFile ) return SQLITE_NOMEM_BKPT;
+ if( !zFile ) return SQLITE_NOMEM_BKPT;
memset(zFile, 0, 4);
zFile += 4;
- if( nUri ){
- memcpy(zFile, zUri, nUri);
- }
+ if( nUri ){
+ memcpy(zFile, zUri, nUri);
+ }
memset(zFile+nUri, 0, 4);
flags &= ~SQLITE_OPEN_URI;
}
@@ -169783,7 +169783,7 @@ static int openDatabase(
}else{
isThreadsafe = sqlite3GlobalConfig.bFullMutex;
}
-
+
if( flags & SQLITE_OPEN_PRIVATECACHE ){
flags &= ~SQLITE_OPEN_SHAREDCACHE;
}else if( sqlite3GlobalConfig.sharedCacheEnabled ){
@@ -169817,19 +169817,19 @@ static int openDatabase(
db = sqlite3MallocZero( sizeof(sqlite3) );
if( db==0 ) goto opendb_out;
if( isThreadsafe
-#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
- || sqlite3GlobalConfig.bCoreMutex
-#endif
- ){
+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
+ || sqlite3GlobalConfig.bCoreMutex
+#endif
+ ){
db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
if( db->mutex==0 ){
sqlite3_free(db);
db = 0;
goto opendb_out;
}
- if( isThreadsafe==0 ){
- sqlite3MutexWarnOnContention(db->mutex);
- }
+ if( isThreadsafe==0 ){
+ sqlite3MutexWarnOnContention(db->mutex);
+ }
}
sqlite3_mutex_enter(db->mutex);
db->errMask = (flags & SQLITE_OPEN_EXRESCODE)!=0 ? 0xffffffff : 0xff;
@@ -169911,12 +169911,12 @@ static int openDatabase(
#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
| SQLITE_CellSizeCk
#endif
-#if defined(SQLITE_ENABLE_FTS3_TOKENIZER)
- | SQLITE_Fts3Tokenizer
-#endif
-#if defined(SQLITE_ENABLE_QPSG)
- | SQLITE_EnableQPSG
-#endif
+#if defined(SQLITE_ENABLE_FTS3_TOKENIZER)
+ | SQLITE_Fts3Tokenizer
+#endif
+#if defined(SQLITE_ENABLE_QPSG)
+ | SQLITE_EnableQPSG
+#endif
#if defined(SQLITE_DEFAULT_DEFENSIVE)
| SQLITE_Defensive
#endif
@@ -169936,41 +169936,41 @@ static int openDatabase(
** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
** functions:
*/
- createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0);
- createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
- createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
+ createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0);
+ createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
+ createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0);
if( db->mallocFailed ){
goto opendb_out;
}
- /* Parse the filename/URI argument
- **
+ /* Parse the filename/URI argument
+ **
** Only allow sensible combinations of bits in the flags argument.
- ** Throw an error if any non-sense combination is used. If we
- ** do not block illegal combinations here, it could trigger
- ** assert() statements in deeper layers. Sensible combinations
- ** are:
- **
- ** 1: SQLITE_OPEN_READONLY
- ** 2: SQLITE_OPEN_READWRITE
- ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
- */
+ ** Throw an error if any non-sense combination is used. If we
+ ** do not block illegal combinations here, it could trigger
+ ** assert() statements in deeper layers. Sensible combinations
+ ** are:
+ **
+ ** 1: SQLITE_OPEN_READONLY
+ ** 2: SQLITE_OPEN_READWRITE
+ ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
+ */
db->openFlags = flags;
- assert( SQLITE_OPEN_READONLY == 0x01 );
- assert( SQLITE_OPEN_READWRITE == 0x02 );
- assert( SQLITE_OPEN_CREATE == 0x04 );
- testcase( (1<<(flags&7))==0x02 ); /* READONLY */
- testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
- testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
- if( ((1<<(flags&7)) & 0x46)==0 ){
+ assert( SQLITE_OPEN_READONLY == 0x01 );
+ assert( SQLITE_OPEN_READWRITE == 0x02 );
+ assert( SQLITE_OPEN_CREATE == 0x04 );
+ testcase( (1<<(flags&7))==0x02 ); /* READONLY */
+ testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
+ testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
+ if( ((1<<(flags&7)) & 0x46)==0 ){
rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */
- }else{
- rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
- }
+ }else{
+ rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
+ }
if( rc!=SQLITE_OK ){
- if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
+ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
sqlite3_free(zErrMsg);
goto opendb_out;
@@ -169981,7 +169981,7 @@ static int openDatabase(
flags | SQLITE_OPEN_MAIN_DB);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_IOERR_NOMEM ){
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
sqlite3Error(db, rc);
goto opendb_out;
@@ -169994,13 +169994,13 @@ static int openDatabase(
sqlite3BtreeLeave(db->aDb[0].pBt);
db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
- /* The default safety_level for the main database is FULL; for the temp
+ /* The default safety_level for the main database is FULL; for the temp
** database it is OFF. This matches the pager layer defaults.
*/
- db->aDb[0].zDbSName = "main";
- db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
- db->aDb[1].zDbSName = "temp";
- db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF;
+ db->aDb[0].zDbSName = "main";
+ db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
+ db->aDb[1].zDbSName = "temp";
+ db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF;
db->eOpenState = SQLITE_STATE_OPEN;
if( db->mallocFailed ){
@@ -170012,15 +170012,15 @@ static int openDatabase(
** is accessed.
*/
sqlite3Error(db, SQLITE_OK);
- sqlite3RegisterPerConnectionBuiltinFunctions(db);
- rc = sqlite3_errcode(db);
+ sqlite3RegisterPerConnectionBuiltinFunctions(db);
+ rc = sqlite3_errcode(db);
/* Load compiled-in extensions */
for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
rc = sqlite3BuiltinExtensions[i](db);
- }
-
+ }
+
/* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API.
*/
@@ -170087,14 +170087,14 @@ opendb_out:
/*
** Open a new database handle.
*/
-SQLITE_API int sqlite3_open(
+SQLITE_API int sqlite3_open(
const char *zFilename,
sqlite3 **ppDb
){
return openDatabase(zFilename, ppDb,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
}
-SQLITE_API int sqlite3_open_v2(
+SQLITE_API int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
@@ -170107,7 +170107,7 @@ SQLITE_API int sqlite3_open_v2(
/*
** Open a new database handle.
*/
-SQLITE_API int sqlite3_open16(
+SQLITE_API int sqlite3_open16(
const void *zFilename,
sqlite3 **ppDb
){
@@ -170135,7 +170135,7 @@ SQLITE_API int sqlite3_open16(
SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE;
}
}else{
- rc = SQLITE_NOMEM_BKPT;
+ rc = SQLITE_NOMEM_BKPT;
}
sqlite3ValueFree(pVal);
@@ -170146,7 +170146,7 @@ SQLITE_API int sqlite3_open16(
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int sqlite3_create_collation(
+SQLITE_API int sqlite3_create_collation(
sqlite3* db,
const char *zName,
int enc,
@@ -170159,7 +170159,7 @@ SQLITE_API int sqlite3_create_collation(
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int sqlite3_create_collation_v2(
+SQLITE_API int sqlite3_create_collation_v2(
sqlite3* db,
const char *zName,
int enc,
@@ -170184,7 +170184,7 @@ SQLITE_API int sqlite3_create_collation_v2(
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int sqlite3_create_collation16(
+SQLITE_API int sqlite3_create_collation16(
sqlite3* db,
const void *zName,
int enc,
@@ -170214,7 +170214,7 @@ SQLITE_API int sqlite3_create_collation16(
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
-SQLITE_API int sqlite3_collation_needed(
+SQLITE_API int sqlite3_collation_needed(
sqlite3 *db,
void *pCollNeededArg,
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
@@ -170235,7 +170235,7 @@ SQLITE_API int sqlite3_collation_needed(
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
-SQLITE_API int sqlite3_collation_needed16(
+SQLITE_API int sqlite3_collation_needed16(
sqlite3 *db,
void *pCollNeededArg,
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
@@ -170257,7 +170257,7 @@ SQLITE_API int sqlite3_collation_needed16(
** This function is now an anachronism. It used to be used to recover from a
** malloc() failure, but SQLite now does this automatically.
*/
-SQLITE_API int sqlite3_global_recover(void){
+SQLITE_API int sqlite3_global_recover(void){
return SQLITE_OK;
}
#endif
@@ -170268,7 +170268,7 @@ SQLITE_API int sqlite3_global_recover(void){
** by default. Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
*/
-SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
+SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -170280,7 +170280,7 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
/*
** The following routines are substitutes for constants SQLITE_CORRUPT,
-** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_NOMEM and possibly other error
+** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_NOMEM and possibly other error
** constants. They serve two purposes:
**
** 1. Serve as a convenient place to set a breakpoint in a debugger
@@ -170289,41 +170289,41 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
** 2. Invoke sqlite3_log() to provide the source code location where
** a low-level error is first detected.
*/
-SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType){
- sqlite3_log(iErr, "%s at line %d of [%.10s]",
- zType, lineno, 20+sqlite3_sourceid());
- return iErr;
-}
+SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType){
+ sqlite3_log(iErr, "%s at line %d of [%.10s]",
+ zType, lineno, 20+sqlite3_sourceid());
+ return iErr;
+}
SQLITE_PRIVATE int sqlite3CorruptError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return sqlite3ReportError(SQLITE_CORRUPT, lineno, "database corruption");
+ return sqlite3ReportError(SQLITE_CORRUPT, lineno, "database corruption");
}
SQLITE_PRIVATE int sqlite3MisuseError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return sqlite3ReportError(SQLITE_MISUSE, lineno, "misuse");
+ return sqlite3ReportError(SQLITE_MISUSE, lineno, "misuse");
}
SQLITE_PRIVATE int sqlite3CantopenError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file");
+ return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file");
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_CORRUPT_PGNO)
-SQLITE_PRIVATE int sqlite3CorruptPgnoError(int lineno, Pgno pgno){
- char zMsg[100];
- sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno);
- testcase( sqlite3GlobalConfig.xLog!=0 );
- return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
-}
+SQLITE_PRIVATE int sqlite3CorruptPgnoError(int lineno, Pgno pgno){
+ char zMsg[100];
+ sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno);
+ testcase( sqlite3GlobalConfig.xLog!=0 );
+ return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
+}
#endif
#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3NomemError(int lineno){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM");
-}
-SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- return sqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
-}
-#endif
+SQLITE_PRIVATE int sqlite3NomemError(int lineno){
+ testcase( sqlite3GlobalConfig.xLog!=0 );
+ return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM");
+}
+SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){
+ testcase( sqlite3GlobalConfig.xLog!=0 );
+ return sqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
+}
+#endif
#ifndef SQLITE_OMIT_DEPRECATED
/*
@@ -170333,7 +170333,7 @@ SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){
** SQLite no longer uses thread-specific data so this routine is now a
** no-op. It is retained for historical compatibility.
*/
-SQLITE_API void sqlite3_thread_cleanup(void){
+SQLITE_API void sqlite3_thread_cleanup(void){
}
#endif
@@ -170341,7 +170341,7 @@ SQLITE_API void sqlite3_thread_cleanup(void){
** Return meta information about a specific column of a database table.
** See comment in sqlite3.h (sqlite.h.in) for details.
*/
-SQLITE_API int sqlite3_table_column_metadata(
+SQLITE_API int sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
@@ -170417,7 +170417,7 @@ SQLITE_API int sqlite3_table_column_metadata(
** explicitly declared column. Copy meta information from *pCol.
*/
if( pCol ){
- zDataType = sqlite3ColumnType(pCol,0);
+ zDataType = sqlite3ColumnType(pCol,0);
zCollSeq = sqlite3ColumnColl(pCol);
notnull = pCol->notNull!=0;
primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
@@ -170427,7 +170427,7 @@ SQLITE_API int sqlite3_table_column_metadata(
primarykey = 1;
}
if( !zCollSeq ){
- zCollSeq = sqlite3StrBINARY;
+ zCollSeq = sqlite3StrBINARY;
}
error_out:
@@ -170459,7 +170459,7 @@ error_out:
/*
** Sleep for a little while. Return the amount of time slept.
*/
-SQLITE_API int sqlite3_sleep(int ms){
+SQLITE_API int sqlite3_sleep(int ms){
sqlite3_vfs *pVfs;
int rc;
pVfs = sqlite3_vfs_find(0);
@@ -170475,7 +170475,7 @@ SQLITE_API int sqlite3_sleep(int ms){
/*
** Enable or disable the extended result codes.
*/
-SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
+SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
@@ -170488,7 +170488,7 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
/*
** Invoke the xFileControl method on a particular database.
*/
-SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
+SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
int rc = SQLITE_ERROR;
Btree *pBtree;
@@ -170508,12 +170508,12 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo
if( op==SQLITE_FCNTL_FILE_POINTER ){
*(sqlite3_file**)pArg = fd;
rc = SQLITE_OK;
- }else if( op==SQLITE_FCNTL_VFS_POINTER ){
- *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager);
- rc = SQLITE_OK;
- }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){
- *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager);
- rc = SQLITE_OK;
+ }else if( op==SQLITE_FCNTL_VFS_POINTER ){
+ *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager);
+ rc = SQLITE_OK;
+ }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){
+ *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager);
+ rc = SQLITE_OK;
}else if( op==SQLITE_FCNTL_DATA_VERSION ){
*(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
rc = SQLITE_OK;
@@ -170538,9 +170538,9 @@ 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, ...){
+SQLITE_API int sqlite3_test_control(int op, ...){
int rc = 0;
-#ifdef SQLITE_UNTESTABLE
+#ifdef SQLITE_UNTESTABLE
UNUSED_PARAMETER(op);
#else
va_list ap;
@@ -170687,7 +170687,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){
*/
case SQLITE_TESTCTRL_ASSERT: {
volatile int x = 0;
- assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 );
+ assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 );
rc = x;
break;
}
@@ -170699,7 +170699,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){
** This action provides a run-time test to see how the ALWAYS and
** NEVER macros were defined at compile-time.
**
- ** The return value is ALWAYS(X) if X is true, or 0 if X is false.
+ ** The return value is ALWAYS(X) if X is true, or 0 if X is false.
**
** The recommended test is X==2. If the return value is 2, that means
** ALWAYS() and NEVER() are both no-op pass-through macros, which is the
@@ -170722,7 +170722,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){
*/
case SQLITE_TESTCTRL_ALWAYS: {
int x = va_arg(ap,int);
- rc = x ? ALWAYS(x) : 0;
+ rc = x ? ALWAYS(x) : 0;
break;
}
@@ -170808,15 +170808,15 @@ SQLITE_API int sqlite3_test_control(int op, ...){
break;
}
- /* Set the threshold at which OP_Once counters reset back to zero.
- ** By default this is 0x7ffffffe (over 2 billion), but that value is
- ** too big to test in a reasonable amount of time, so this control is
- ** provided to set a small and easily reachable reset value.
- */
- case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: {
- sqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int);
- break;
- }
+ /* Set the threshold at which OP_Once counters reset back to zero.
+ ** By default this is 0x7ffffffe (over 2 billion), but that value is
+ ** too big to test in a reasonable amount of time, so this control is
+ ** provided to set a small and easily reachable reset value.
+ */
+ case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: {
+ sqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int);
+ break;
+ }
/* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr);
**
@@ -170882,22 +170882,22 @@ SQLITE_API int sqlite3_test_control(int op, ...){
sqlite3_mutex_leave(db->mutex);
break;
}
-
-#if defined(YYCOVERAGE)
- /* sqlite3_test_control(SQLITE_TESTCTRL_PARSER_COVERAGE, FILE *out)
- **
- ** This test control (only available when SQLite is compiled with
- ** -DYYCOVERAGE) writes a report onto "out" that shows all
- ** state/lookahead combinations in the parser state machine
- ** which are never exercised. If any state is missed, make the
- ** return code SQLITE_ERROR.
- */
- case SQLITE_TESTCTRL_PARSER_COVERAGE: {
- FILE *out = va_arg(ap, FILE*);
- if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR;
- break;
- }
-#endif /* defined(YYCOVERAGE) */
+
+#if defined(YYCOVERAGE)
+ /* sqlite3_test_control(SQLITE_TESTCTRL_PARSER_COVERAGE, FILE *out)
+ **
+ ** This test control (only available when SQLite is compiled with
+ ** -DYYCOVERAGE) writes a report onto "out" that shows all
+ ** state/lookahead combinations in the parser state machine
+ ** which are never exercised. If any state is missed, make the
+ ** return code SQLITE_ERROR.
+ */
+ case SQLITE_TESTCTRL_PARSER_COVERAGE: {
+ FILE *out = va_arg(ap, FILE*);
+ if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR;
+ break;
+ }
+#endif /* defined(YYCOVERAGE) */
/* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*);
**
@@ -170984,7 +170984,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){
#endif
}
va_end(ap);
-#endif /* SQLITE_UNTESTABLE */
+#endif /* SQLITE_UNTESTABLE */
return rc;
}
@@ -171076,7 +171076,7 @@ SQLITE_API void sqlite3_free_filename(char *p){
** parameter if it exists. If the parameter does not exist, this routine
** returns a NULL pointer.
*/
-SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
+SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
if( zFilename==0 || zParam==0 ) return 0;
zFilename = databaseName(zFilename);
return uriParameter(zFilename, zParam);
@@ -171099,7 +171099,7 @@ SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N){
/*
** Return a boolean value for a query parameter.
*/
-SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
+SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
const char *z = sqlite3_uri_parameter(zFilename, zParam);
bDflt = bDflt!=0;
return z ? sqlite3GetBoolean(z, bDflt) : bDflt;
@@ -171108,14 +171108,14 @@ SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, in
/*
** Return a 64-bit integer value for a query parameter.
*/
-SQLITE_API sqlite3_int64 sqlite3_uri_int64(
+SQLITE_API sqlite3_int64 sqlite3_uri_int64(
const char *zFilename, /* Filename as passed to xOpen */
const char *zParam, /* URI parameter sought */
sqlite3_int64 bDflt /* return if parameter is missing */
){
const char *z = sqlite3_uri_parameter(zFilename, zParam);
sqlite3_int64 v;
- if( z && sqlite3DecOrHexToI64(z, &v)==0 ){
+ if( z && sqlite3DecOrHexToI64(z, &v)==0 ){
bDflt = v;
}
return bDflt;
@@ -171159,15 +171159,15 @@ SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){
** Return the Btree pointer identified by zDbName. Return NULL if not found.
*/
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
- int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0;
- return iDb<0 ? 0 : db->aDb[iDb].pBt;
+ int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0;
+ return iDb<0 ? 0 : db->aDb[iDb].pBt;
}
/*
** Return the filename of the database associated with a database
** connection.
*/
-SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
+SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
Btree *pBt;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
@@ -171183,7 +171183,7 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
** Return 1 if database is read-only or 0 if read/write. Return -1 if
** no such database exists.
*/
-SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
+SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
Btree *pBt;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
@@ -171195,66 +171195,66 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
}
-#ifdef SQLITE_ENABLE_SNAPSHOT
-/*
+#ifdef SQLITE_ENABLE_SNAPSHOT
+/*
** Obtain a snapshot handle for the snapshot of database zDb currently
-** being read by handle db.
-*/
-SQLITE_API int sqlite3_snapshot_get(
+** being read by handle db.
+*/
+SQLITE_API int sqlite3_snapshot_get(
sqlite3 *db,
- const char *zDb,
- sqlite3_snapshot **ppSnapshot
-){
- int rc = SQLITE_ERROR;
-#ifndef SQLITE_OMIT_WAL
-
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !sqlite3SafetyCheckOk(db) ){
- return SQLITE_MISUSE_BKPT;
- }
-#endif
- sqlite3_mutex_enter(db->mutex);
-
- if( db->autoCommit==0 ){
- int iDb = sqlite3FindDbName(db, zDb);
- if( iDb==0 || iDb>1 ){
- Btree *pBt = db->aDb[iDb].pBt;
+ const char *zDb,
+ sqlite3_snapshot **ppSnapshot
+){
+ int rc = SQLITE_ERROR;
+#ifndef SQLITE_OMIT_WAL
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
+ sqlite3_mutex_enter(db->mutex);
+
+ if( db->autoCommit==0 ){
+ int iDb = sqlite3FindDbName(db, zDb);
+ if( iDb==0 || iDb>1 ){
+ Btree *pBt = db->aDb[iDb].pBt;
if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){
rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
- }
- }
- }
- }
-
- sqlite3_mutex_leave(db->mutex);
-#endif /* SQLITE_OMIT_WAL */
- return rc;
-}
-
-/*
-** Open a read-transaction on the snapshot idendified by pSnapshot.
-*/
-SQLITE_API int sqlite3_snapshot_open(
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
+ }
+ }
+ }
+ }
+
+ sqlite3_mutex_leave(db->mutex);
+#endif /* SQLITE_OMIT_WAL */
+ return rc;
+}
+
+/*
+** Open a read-transaction on the snapshot idendified by pSnapshot.
+*/
+SQLITE_API int sqlite3_snapshot_open(
sqlite3 *db,
const char *zDb,
- sqlite3_snapshot *pSnapshot
-){
- int rc = SQLITE_ERROR;
-#ifndef SQLITE_OMIT_WAL
-
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !sqlite3SafetyCheckOk(db) ){
- return SQLITE_MISUSE_BKPT;
- }
-#endif
- sqlite3_mutex_enter(db->mutex);
- if( db->autoCommit==0 ){
- int iDb;
- iDb = sqlite3FindDbName(db, zDb);
- if( iDb==0 || iDb>1 ){
- Btree *pBt = db->aDb[iDb].pBt;
+ sqlite3_snapshot *pSnapshot
+){
+ int rc = SQLITE_ERROR;
+#ifndef SQLITE_OMIT_WAL
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
+ sqlite3_mutex_enter(db->mutex);
+ if( db->autoCommit==0 ){
+ int iDb;
+ iDb = sqlite3FindDbName(db, zDb);
+ if( iDb==0 || iDb>1 ){
+ Btree *pBt = db->aDb[iDb].pBt;
if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ){
Pager *pPager = sqlite3BtreePager(pBt);
int bUnlock = 0;
@@ -171269,9 +171269,9 @@ SQLITE_API int sqlite3_snapshot_open(
}else{
rc = SQLITE_OK;
}
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
rc = sqlite3PagerSnapshotOpen(pPager, pSnapshot);
- }
+ }
if( rc==SQLITE_OK ){
rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
sqlite3PagerSnapshotOpen(pPager, 0);
@@ -171279,107 +171279,107 @@ SQLITE_API int sqlite3_snapshot_open(
if( bUnlock ){
sqlite3PagerSnapshotUnlock(pPager);
}
- }
- }
- }
-
- sqlite3_mutex_leave(db->mutex);
-#endif /* SQLITE_OMIT_WAL */
- return rc;
-}
-
-/*
-** Recover as many snapshots as possible from the wal file associated with
-** schema zDb of database db.
-*/
-SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){
- int rc = SQLITE_ERROR;
- int iDb;
-#ifndef SQLITE_OMIT_WAL
-
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !sqlite3SafetyCheckOk(db) ){
- return SQLITE_MISUSE_BKPT;
- }
-#endif
-
- sqlite3_mutex_enter(db->mutex);
- iDb = sqlite3FindDbName(db, zDb);
- if( iDb==0 || iDb>1 ){
- Btree *pBt = db->aDb[iDb].pBt;
+ }
+ }
+ }
+
+ sqlite3_mutex_leave(db->mutex);
+#endif /* SQLITE_OMIT_WAL */
+ return rc;
+}
+
+/*
+** Recover as many snapshots as possible from the wal file associated with
+** schema zDb of database db.
+*/
+SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){
+ int rc = SQLITE_ERROR;
+ int iDb;
+#ifndef SQLITE_OMIT_WAL
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
+
+ sqlite3_mutex_enter(db->mutex);
+ iDb = sqlite3FindDbName(db, zDb);
+ if( iDb==0 || iDb>1 ){
+ Btree *pBt = db->aDb[iDb].pBt;
if( SQLITE_TXN_NONE==sqlite3BtreeTxnState(pBt) ){
rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt));
- sqlite3BtreeCommit(pBt);
- }
- }
- }
- sqlite3_mutex_leave(db->mutex);
-#endif /* SQLITE_OMIT_WAL */
- return rc;
-}
-
-/*
-** Free a snapshot handle obtained from sqlite3_snapshot_get().
-*/
-SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){
- sqlite3_free(pSnapshot);
-}
-#endif /* SQLITE_ENABLE_SNAPSHOT */
-
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-/*
-** Given the name of a compile-time option, return true if that option
-** was used and false if not.
-**
-** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
-** is not required for a match.
-*/
-SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
- int i, n;
- int nOpt;
- const char **azCompileOpt;
-
-#if SQLITE_ENABLE_API_ARMOR
- if( zOptName==0 ){
- (void)SQLITE_MISUSE_BKPT;
- return 0;
- }
-#endif
-
- azCompileOpt = sqlite3CompileOptions(&nOpt);
-
- if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
- n = sqlite3Strlen30(zOptName);
-
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt));
+ sqlite3BtreeCommit(pBt);
+ }
+ }
+ }
+ sqlite3_mutex_leave(db->mutex);
+#endif /* SQLITE_OMIT_WAL */
+ return rc;
+}
+
+/*
+** Free a snapshot handle obtained from sqlite3_snapshot_get().
+*/
+SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){
+ sqlite3_free(pSnapshot);
+}
+#endif /* SQLITE_ENABLE_SNAPSHOT */
+
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+/*
+** Given the name of a compile-time option, return true if that option
+** was used and false if not.
+**
+** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
+** is not required for a match.
+*/
+SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
+ int i, n;
+ int nOpt;
+ const char **azCompileOpt;
+
+#if SQLITE_ENABLE_API_ARMOR
+ if( zOptName==0 ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+
+ azCompileOpt = sqlite3CompileOptions(&nOpt);
+
+ if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
+ n = sqlite3Strlen30(zOptName);
+
/* Since nOpt is normally in single digits, a linear search is
- ** adequate. No need for a binary search. */
- for(i=0; i<nOpt; i++){
- if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
- && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
- ){
- return 1;
- }
- }
- return 0;
-}
-
-/*
-** Return the N-th compile-time option string. If N is out of range,
-** return a NULL pointer.
-*/
-SQLITE_API const char *sqlite3_compileoption_get(int N){
- int nOpt;
- const char **azCompileOpt;
- azCompileOpt = sqlite3CompileOptions(&nOpt);
- if( N>=0 && N<nOpt ){
- return azCompileOpt[N];
- }
- return 0;
-}
-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
-
+ ** adequate. No need for a binary search. */
+ for(i=0; i<nOpt; i++){
+ if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
+ && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
+ ){
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+** Return the N-th compile-time option string. If N is out of range,
+** return a NULL pointer.
+*/
+SQLITE_API const char *sqlite3_compileoption_get(int N){
+ int nOpt;
+ const char **azCompileOpt;
+ azCompileOpt = sqlite3CompileOptions(&nOpt);
+ if( N>=0 && N<nOpt ){
+ return azCompileOpt[N];
+ }
+ return 0;
+}
+#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
+
/************** End of main.c ************************************************/
/************** Begin file notify.c ******************************************/
/*
@@ -171529,7 +171529,7 @@ static void leaveMutex(void){
** on the same "db". If xNotify==0 then any prior callbacks are immediately
** cancelled.
*/
-SQLITE_API int sqlite3_unlock_notify(
+SQLITE_API int sqlite3_unlock_notify(
sqlite3 *db,
void (*xNotify)(void **, int),
void *pArg
@@ -172029,12 +172029,12 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){
# define NDEBUG 1
#endif
-/* FTS3/FTS4 require virtual tables */
-#ifdef SQLITE_OMIT_VIRTUALTABLE
-# undef SQLITE_ENABLE_FTS3
-# undef SQLITE_ENABLE_FTS4
-#endif
-
+/* FTS3/FTS4 require virtual tables */
+#ifdef SQLITE_OMIT_VIRTUALTABLE
+# undef SQLITE_ENABLE_FTS3
+# undef SQLITE_ENABLE_FTS4
+#endif
+
/*
** FTS4 is really an extension for FTS3. It is enabled using the
** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all
@@ -172543,7 +172543,7 @@ struct Fts3Table {
** statements is run and reset within a single virtual table API call.
*/
sqlite3_stmt *aStmt[40];
- sqlite3_stmt *pSeekStmt; /* Cache for fts3CursorSeekStmt() */
+ sqlite3_stmt *pSeekStmt; /* Cache for fts3CursorSeekStmt() */
char *zReadExprlist;
char *zWriteExprlist;
@@ -172584,7 +172584,7 @@ struct Fts3Table {
int nPendingData; /* Current bytes of pending data */
sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */
int iPrevLangid; /* Langid of recently inserted document */
- int bPrevDelete; /* True if last operation was a delete */
+ int bPrevDelete; /* True if last operation was a delete */
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
/* State variables used for validating that the transaction control
@@ -172623,7 +172623,7 @@ struct Fts3Cursor {
i16 eSearch; /* Search strategy (see below) */
u8 isEof; /* True if at End Of Results */
u8 isRequireSeek; /* True if must seek pStmt to %_content row */
- u8 bSeekStmt; /* True if pStmt is a seek */
+ u8 bSeekStmt; /* True if pStmt is a seek */
sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */
Fts3Expr *pExpr; /* Parsed MATCH query string */
int iLangid; /* Language being queried for */
@@ -173006,8 +173006,8 @@ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
if( (v & mask2)==0 ){ var = v; return ret; }
SQLITE_PRIVATE int sqlite3Fts3GetVarintU(const char *pBuf, sqlite_uint64 *v){
- const unsigned char *p = (const unsigned char*)pBuf;
- const unsigned char *pStart = p;
+ const unsigned char *p = (const unsigned char*)pBuf;
+ const unsigned char *pStart = p;
u32 a;
u64 b;
int shift;
@@ -173064,7 +173064,7 @@ SQLITE_PRIVATE int sqlite3Fts3GetVarintBounded(
/*
** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to
-** a non-negative 32-bit integer before it is returned.
+** a non-negative 32-bit integer before it is returned.
*/
SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){
const unsigned char *ptr = (const unsigned char*)p;
@@ -173082,8 +173082,8 @@ SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){
GETVARINT_STEP(a, ptr, 21, 0x1FFFFF, 0x10000000, *pi, 4);
a = (a & 0x0FFFFFFF );
*pi = (int)(a | ((u32)(*ptr & 0x07) << 28));
- assert( 0==(a & 0x80000000) );
- assert( *pi>=0 );
+ assert( 0==(a & 0x80000000) );
+ assert( *pi>=0 );
return 5;
}
@@ -173187,7 +173187,7 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
assert( p->pSegments==0 );
/* Free any prepared statements held */
- sqlite3_finalize(p->pSeekStmt);
+ sqlite3_finalize(p->pSeekStmt);
for(i=0; i<SizeofArray(p->aStmt); i++){
sqlite3_finalize(p->aStmt[i]);
}
@@ -173932,66 +173932,66 @@ static int fts3InitVtab(
break;
}
}
- switch( iOpt ){
- case 0: /* MATCHINFO */
- if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
- sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
- rc = SQLITE_ERROR;
- }
- bNoDocsize = 1;
- break;
-
- case 1: /* PREFIX */
- sqlite3_free(zPrefix);
- zPrefix = zVal;
- zVal = 0;
- break;
-
- case 2: /* COMPRESS */
- sqlite3_free(zCompress);
- zCompress = zVal;
- zVal = 0;
- break;
-
- case 3: /* UNCOMPRESS */
- sqlite3_free(zUncompress);
- zUncompress = zVal;
- zVal = 0;
- break;
-
- case 4: /* ORDER */
+ switch( iOpt ){
+ case 0: /* MATCHINFO */
+ if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
+ rc = SQLITE_ERROR;
+ }
+ bNoDocsize = 1;
+ break;
+
+ case 1: /* PREFIX */
+ sqlite3_free(zPrefix);
+ zPrefix = zVal;
+ zVal = 0;
+ break;
+
+ case 2: /* COMPRESS */
+ sqlite3_free(zCompress);
+ zCompress = zVal;
+ zVal = 0;
+ break;
+
+ case 3: /* UNCOMPRESS */
+ sqlite3_free(zUncompress);
+ zUncompress = zVal;
+ zVal = 0;
+ break;
+
+ case 4: /* ORDER */
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
- ){
- sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
- rc = SQLITE_ERROR;
- }
- bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
- break;
-
- case 5: /* CONTENT */
- sqlite3_free(zContent);
- zContent = zVal;
- zVal = 0;
- break;
-
- case 6: /* LANGUAGEID */
- assert( iOpt==6 );
- sqlite3_free(zLanguageid);
- zLanguageid = zVal;
- zVal = 0;
- break;
-
- case 7: /* NOTINDEXED */
- azNotindexed[nNotindexed++] = zVal;
- zVal = 0;
- break;
-
- default:
- assert( iOpt==SizeofArray(aFts4Opt) );
- sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
- rc = SQLITE_ERROR;
- break;
+ ){
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
+ rc = SQLITE_ERROR;
+ }
+ bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
+ break;
+
+ case 5: /* CONTENT */
+ sqlite3_free(zContent);
+ zContent = zVal;
+ zVal = 0;
+ break;
+
+ case 6: /* LANGUAGEID */
+ assert( iOpt==6 );
+ sqlite3_free(zLanguageid);
+ zLanguageid = zVal;
+ zVal = 0;
+ break;
+
+ case 7: /* NOTINDEXED */
+ azNotindexed[nNotindexed++] = zVal;
+ zVal = 0;
+ break;
+
+ default:
+ assert( iOpt==SizeofArray(aFts4Opt) );
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
+ rc = SQLITE_ERROR;
+ break;
}
sqlite3_free(zVal);
}
@@ -174079,9 +174079,9 @@ static int fts3InitVtab(
p->pTokenizer = pTokenizer;
p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
p->bHasDocsize = (isFts4 && bNoDocsize==0);
- p->bHasStat = (u8)isFts4;
- p->bFts4 = (u8)isFts4;
- p->bDescIdx = (u8)bDescIdx;
+ p->bHasStat = (u8)isFts4;
+ p->bFts4 = (u8)isFts4;
+ p->bDescIdx = (u8)bDescIdx;
p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */
p->zContentTbl = zContent;
p->zLanguageid = zLanguageid;
@@ -174112,9 +174112,9 @@ static int fts3InitVtab(
char *z;
int n = 0;
z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n);
- if( n>0 ){
- memcpy(zCsr, z, n);
- }
+ if( n>0 ){
+ memcpy(zCsr, z, n);
+ }
zCsr[n] = '\0';
sqlite3Fts3Dequote(zCsr);
p->azColumn[iCol] = zCsr;
@@ -174239,19 +174239,19 @@ static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
#endif
}
-/*
-** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
-** extension is currently being used by a version of SQLite too old to
-** support index-info flags. In that case this function is a no-op.
-*/
-static void fts3SetUniqueFlag(sqlite3_index_info *pIdxInfo){
-#if SQLITE_VERSION_NUMBER>=3008012
- if( sqlite3_libversion_number()>=3008012 ){
- pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
- }
-#endif
-}
-
+/*
+** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
+** extension is currently being used by a version of SQLite too old to
+** support index-info flags. In that case this function is a no-op.
+*/
+static void fts3SetUniqueFlag(sqlite3_index_info *pIdxInfo){
+#if SQLITE_VERSION_NUMBER>=3008012
+ if( sqlite3_libversion_number()>=3008012 ){
+ pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
+ }
+#endif
+}
+
/*
** Implementation of the xBestIndex method for FTS3 tables. There
** are three possible strategies, in order of preference:
@@ -174346,9 +174346,9 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
}
}
- /* If using a docid=? or rowid=? strategy, set the UNIQUE flag. */
- if( pInfo->idxNum==FTS3_DOCID_SEARCH ) fts3SetUniqueFlag(pInfo);
-
+ /* If using a docid=? or rowid=? strategy, set the UNIQUE flag. */
+ if( pInfo->idxNum==FTS3_DOCID_SEARCH ) fts3SetUniqueFlag(pInfo);
+
iIdx = 1;
if( iCons>=0 ){
pInfo->aConstraintUsage[iCons].argvIndex = iIdx++;
@@ -174407,46 +174407,46 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
}
/*
-** Finalize the statement handle at pCsr->pStmt.
-**
-** Or, if that statement handle is one created by fts3CursorSeekStmt(),
-** and the Fts3Table.pSeekStmt slot is currently NULL, save the statement
-** pointer there instead of finalizing it.
-*/
-static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){
- if( pCsr->bSeekStmt ){
- Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
- if( p->pSeekStmt==0 ){
- p->pSeekStmt = pCsr->pStmt;
- sqlite3_reset(pCsr->pStmt);
- pCsr->pStmt = 0;
- }
- pCsr->bSeekStmt = 0;
- }
- sqlite3_finalize(pCsr->pStmt);
-}
-
-/*
-** Free all resources currently held by the cursor passed as the only
-** argument.
-*/
-static void fts3ClearCursor(Fts3Cursor *pCsr){
- fts3CursorFinalizeStmt(pCsr);
- sqlite3Fts3FreeDeferredTokens(pCsr);
- sqlite3_free(pCsr->aDoclist);
- sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
- sqlite3Fts3ExprFree(pCsr->pExpr);
- memset(&(&pCsr->base)[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
-}
-
-/*
+** Finalize the statement handle at pCsr->pStmt.
+**
+** Or, if that statement handle is one created by fts3CursorSeekStmt(),
+** and the Fts3Table.pSeekStmt slot is currently NULL, save the statement
+** pointer there instead of finalizing it.
+*/
+static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){
+ if( pCsr->bSeekStmt ){
+ Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
+ if( p->pSeekStmt==0 ){
+ p->pSeekStmt = pCsr->pStmt;
+ sqlite3_reset(pCsr->pStmt);
+ pCsr->pStmt = 0;
+ }
+ pCsr->bSeekStmt = 0;
+ }
+ sqlite3_finalize(pCsr->pStmt);
+}
+
+/*
+** Free all resources currently held by the cursor passed as the only
+** argument.
+*/
+static void fts3ClearCursor(Fts3Cursor *pCsr){
+ fts3CursorFinalizeStmt(pCsr);
+ sqlite3Fts3FreeDeferredTokens(pCsr);
+ sqlite3_free(pCsr->aDoclist);
+ sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
+ sqlite3Fts3ExprFree(pCsr->pExpr);
+ memset(&(&pCsr->base)[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
+}
+
+/*
** Close the cursor. For additional information see the documentation
** on the xClose method of the virtual table interface.
*/
static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
- fts3ClearCursor(pCsr);
+ fts3ClearCursor(pCsr);
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
sqlite3_free(pCsr);
return SQLITE_OK;
@@ -174461,25 +174461,25 @@ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
** it. If an error occurs, return an SQLite error code.
*/
-static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
+static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
int rc = SQLITE_OK;
if( pCsr->pStmt==0 ){
Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
char *zSql;
- if( p->pSeekStmt ){
- pCsr->pStmt = p->pSeekStmt;
- p->pSeekStmt = 0;
- }else{
- zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
- if( !zSql ) return SQLITE_NOMEM;
+ if( p->pSeekStmt ){
+ pCsr->pStmt = p->pSeekStmt;
+ p->pSeekStmt = 0;
+ }else{
+ zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
+ if( !zSql ) return SQLITE_NOMEM;
p->bLock++;
rc = sqlite3_prepare_v3(
p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0
);
p->bLock--;
- sqlite3_free(zSql);
- }
- if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1;
+ sqlite3_free(zSql);
+ }
+ if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1;
}
return rc;
}
@@ -174492,7 +174492,7 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
int rc = SQLITE_OK;
if( pCsr->isRequireSeek ){
- rc = fts3CursorSeekStmt(pCsr);
+ rc = fts3CursorSeekStmt(pCsr);
if( rc==SQLITE_OK ){
Fts3Table *pTab = (Fts3Table*)pCsr->base.pVtab;
pTab->bLock++;
@@ -174589,7 +174589,7 @@ static int fts3ScanInteriorNode(
isFirstTerm = 0;
zCsr += fts3GetVarint32(zCsr, &nSuffix);
- assert( nPrefix>=0 && nSuffix>=0 );
+ assert( nPrefix>=0 && nSuffix>=0 );
if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr || nSuffix==0 ){
rc = FTS_CORRUPT_VTAB;
goto finish_scan;
@@ -175431,7 +175431,7 @@ SQLITE_PRIVATE int sqlite3Fts3FirstFilter(
fts3ColumnlistCopy(0, &p);
}
- while( p<pEnd ){
+ while( p<pEnd ){
sqlite3_int64 iCol;
p++;
p += sqlite3Fts3GetVarint(p, &iCol);
@@ -175986,7 +175986,7 @@ static int fts3FilterMethod(
assert( iIdx==nVal );
/* In case the cursor has been used before, clear it now. */
- fts3ClearCursor(pCsr);
+ fts3ClearCursor(pCsr);
/* Set the lower and upper bounds on docids to return */
pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
@@ -176054,7 +176054,7 @@ static int fts3FilterMethod(
rc = SQLITE_NOMEM;
}
}else if( eSearch==FTS3_DOCID_SEARCH ){
- rc = fts3CursorSeekStmt(pCsr);
+ rc = fts3CursorSeekStmt(pCsr);
if( rc==SQLITE_OK ){
rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons);
}
@@ -176069,12 +176069,12 @@ static int fts3FilterMethod(
** routine to find out if it has reached the end of a result set.
*/
static int fts3EofMethod(sqlite3_vtab_cursor *pCursor){
- Fts3Cursor *pCsr = (Fts3Cursor*)pCursor;
- if( pCsr->isEof ){
- fts3ClearCursor(pCsr);
- pCsr->isEof = 1;
- }
- return pCsr->isEof;
+ Fts3Cursor *pCsr = (Fts3Cursor*)pCursor;
+ if( pCsr->isEof ){
+ fts3ClearCursor(pCsr);
+ pCsr->isEof = 1;
+ }
+ return pCsr->isEof;
}
/*
@@ -176112,37 +176112,37 @@ static int fts3ColumnMethod(
/* The column value supplied by SQLite must be in range. */
assert( iCol>=0 && iCol<=p->nColumn+2 );
- switch( iCol-p->nColumn ){
- case 0:
- /* The special 'table-name' column */
- sqlite3_result_pointer(pCtx, pCsr, "fts3cursor", 0);
- break;
-
- case 1:
- /* The docid column */
- sqlite3_result_int64(pCtx, pCsr->iPrevId);
- break;
-
- case 2:
- if( pCsr->pExpr ){
- sqlite3_result_int64(pCtx, pCsr->iLangid);
- break;
- }else if( p->zLanguageid==0 ){
- sqlite3_result_int(pCtx, 0);
- break;
- }else{
- iCol = p->nColumn;
+ switch( iCol-p->nColumn ){
+ case 0:
+ /* The special 'table-name' column */
+ sqlite3_result_pointer(pCtx, pCsr, "fts3cursor", 0);
+ break;
+
+ case 1:
+ /* The docid column */
+ sqlite3_result_int64(pCtx, pCsr->iPrevId);
+ break;
+
+ case 2:
+ if( pCsr->pExpr ){
+ sqlite3_result_int64(pCtx, pCsr->iLangid);
+ break;
+ }else if( p->zLanguageid==0 ){
+ sqlite3_result_int(pCtx, 0);
+ break;
+ }else{
+ iCol = p->nColumn;
/* no break */ deliberate_fall_through
- }
-
- default:
- /* A user column. Or, if this is a full-table scan, possibly the
- ** language-id column. Seek the cursor. */
- rc = fts3CursorSeek(0, pCsr);
- if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){
+ }
+
+ default:
+ /* A user column. Or, if this is a full-table scan, possibly the
+ ** language-id column. Seek the cursor. */
+ rc = fts3CursorSeek(0, pCsr);
+ if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){
sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
}
- break;
+ break;
}
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
@@ -176191,10 +176191,10 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */
Fts3Table *p = (Fts3Table*)pVtab;
- int rc;
- i64 iLastRowid = sqlite3_last_insert_rowid(p->db);
+ int rc;
+ i64 iLastRowid = sqlite3_last_insert_rowid(p->db);
- rc = sqlite3Fts3PendingTermsFlush(p);
+ rc = sqlite3Fts3PendingTermsFlush(p);
if( rc==SQLITE_OK
&& p->nLeafAdd>(nMinMerge/16)
&& p->nAutoincrmerge && p->nAutoincrmerge!=0xff
@@ -176209,7 +176209,7 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge);
}
sqlite3Fts3SegmentsClose(p);
- sqlite3_set_last_insert_rowid(p->db, iLastRowid);
+ sqlite3_set_last_insert_rowid(p->db, iLastRowid);
return rc;
}
@@ -176222,11 +176222,11 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
static int fts3SetHasStat(Fts3Table *p){
int rc = SQLITE_OK;
if( p->bHasStat==2 ){
- char *zTbl = sqlite3_mprintf("%s_stat", p->zName);
- if( zTbl ){
- int res = sqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0);
- sqlite3_free(zTbl);
- p->bHasStat = (res==SQLITE_OK);
+ char *zTbl = sqlite3_mprintf("%s_stat", p->zName);
+ if( zTbl ){
+ int res = sqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0);
+ sqlite3_free(zTbl);
+ p->bHasStat = (res==SQLITE_OK);
}else{
rc = SQLITE_NOMEM;
}
@@ -176339,17 +176339,17 @@ static int fts3FunctionArg(
sqlite3_value *pVal, /* argv[0] passed to function */
Fts3Cursor **ppCsr /* OUT: Store cursor handle here */
){
- int rc;
- *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal, "fts3cursor");
- if( (*ppCsr)!=0 ){
- rc = SQLITE_OK;
- }else{
+ int rc;
+ *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal, "fts3cursor");
+ if( (*ppCsr)!=0 ){
+ rc = SQLITE_OK;
+ }else{
char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
sqlite3_result_error(pContext, zErr, -1);
sqlite3_free(zErr);
- rc = SQLITE_ERROR;
+ rc = SQLITE_ERROR;
}
- return rc;
+ return rc;
}
/*
@@ -176755,7 +176755,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
#endif
/* Create the virtual table wrapper around the hash-table and overload
- ** the four scalar functions. If this is successful, register the
+ ** the four scalar functions. If this is successful, register the
** module with sqlite.
*/
if( SQLITE_OK==rc
@@ -177341,7 +177341,7 @@ static int fts3EvalIncrPhraseNext(
** one incremental token. In which case the bIncr flag is set. */
assert( p->bIncr==1 );
- if( p->nToken==1 ){
+ if( p->nToken==1 ){
rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr,
&pDL->iDocid, &pDL->pList, &pDL->nList
);
@@ -177575,7 +177575,7 @@ static void fts3EvalTokenCosts(
** the number of overflow pages consumed by a record B bytes in size.
*/
static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
- int rc = SQLITE_OK;
+ int rc = SQLITE_OK;
if( pCsr->nRowAvg==0 ){
/* The average document size, which is required to calculate the cost
** of each doclist, has not yet been determined. Read the required
@@ -177618,7 +177618,7 @@ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
}
*pnPage = pCsr->nRowAvg;
- return rc;
+ return rc;
}
/*
@@ -177969,8 +177969,8 @@ static void fts3EvalNextRow(
pExpr->iDocid = pLeft->iDocid;
pExpr->bEof = (pLeft->bEof || pRight->bEof);
if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){
- assert( pRight->eType==FTSQUERY_PHRASE );
- if( pRight->pPhrase->doclist.aAll ){
+ assert( pRight->eType==FTSQUERY_PHRASE );
+ if( pRight->pPhrase->doclist.aAll ){
Fts3Doclist *pDl = &pRight->pPhrase->doclist;
while( *pRc==SQLITE_OK && pRight->bEof==0 ){
memset(pDl->pList, 0, pDl->nList);
@@ -178000,7 +178000,7 @@ static void fts3EvalNextRow(
if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
fts3EvalNextRow(pCsr, pLeft, pRc);
- }else if( pLeft->bEof || iCmp>0 ){
+ }else if( pLeft->bEof || iCmp>0 ){
fts3EvalNextRow(pCsr, pRight, pRc);
}else{
fts3EvalNextRow(pCsr, pLeft, pRc);
@@ -178100,39 +178100,39 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
/* Allocate temporary working space. */
for(p=pExpr; p->pLeft; p=p->pLeft){
- assert( p->pRight->pPhrase->doclist.nList>0 );
+ assert( p->pRight->pPhrase->doclist.nList>0 );
nTmp += p->pRight->pPhrase->doclist.nList;
}
nTmp += p->pPhrase->doclist.nList;
aTmp = sqlite3_malloc64(nTmp*2);
- if( !aTmp ){
- *pRc = SQLITE_NOMEM;
+ if( !aTmp ){
+ *pRc = SQLITE_NOMEM;
res = 0;
}else{
- char *aPoslist = p->pPhrase->doclist.pList;
- int nToken = p->pPhrase->nToken;
-
- for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
- Fts3Phrase *pPhrase = p->pRight->pPhrase;
- int nNear = p->nNear;
- res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
- }
-
- aPoslist = pExpr->pRight->pPhrase->doclist.pList;
- nToken = pExpr->pRight->pPhrase->nToken;
- for(p=pExpr->pLeft; p && res; p=p->pLeft){
- int nNear;
- Fts3Phrase *pPhrase;
- assert( p->pParent && p->pParent->pLeft==p );
- nNear = p->pParent->nNear;
- pPhrase = (
- p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
- );
- res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
+ char *aPoslist = p->pPhrase->doclist.pList;
+ int nToken = p->pPhrase->nToken;
+
+ for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
+ Fts3Phrase *pPhrase = p->pRight->pPhrase;
+ int nNear = p->nNear;
+ res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
+ }
+
+ aPoslist = pExpr->pRight->pPhrase->doclist.pList;
+ nToken = pExpr->pRight->pPhrase->nToken;
+ for(p=pExpr->pLeft; p && res; p=p->pLeft){
+ int nNear;
+ Fts3Phrase *pPhrase;
+ assert( p->pParent && p->pParent->pLeft==p );
+ nNear = p->pParent->nNear;
+ pPhrase = (
+ p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
+ );
+ res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
}
- }
+ }
- sqlite3_free(aTmp);
+ sqlite3_free(aTmp);
}
return res;
@@ -178746,7 +178746,7 @@ SQLITE_PRIVATE int sqlite3Fts3Corrupt(){
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int sqlite3_fts3_init(
+SQLITE_API int sqlite3_fts3_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -180115,48 +180115,48 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){
rc = SQLITE_ERROR;
}
- if( rc==SQLITE_OK ){
- if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
- Fts3Expr **apLeaf;
+ if( rc==SQLITE_OK ){
+ if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
+ Fts3Expr **apLeaf;
apLeaf = (Fts3Expr **)sqlite3_malloc64(sizeof(Fts3Expr *) * nMaxDepth);
- if( 0==apLeaf ){
- rc = SQLITE_NOMEM;
- }else{
- memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth);
- }
-
- if( rc==SQLITE_OK ){
- int i;
- Fts3Expr *p;
-
- /* Set $p to point to the left-most leaf in the tree of eType nodes. */
- for(p=pRoot; p->eType==eType; p=p->pLeft){
- assert( p->pParent==0 || p->pParent->pLeft==p );
- assert( p->pLeft && p->pRight );
- }
-
- /* This loop runs once for each leaf in the tree of eType nodes. */
- while( 1 ){
- int iLvl;
- Fts3Expr *pParent = p->pParent; /* Current parent of p */
-
- assert( pParent==0 || pParent->pLeft==p );
- p->pParent = 0;
- if( pParent ){
- pParent->pLeft = 0;
+ if( 0==apLeaf ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth);
+ }
+
+ if( rc==SQLITE_OK ){
+ int i;
+ Fts3Expr *p;
+
+ /* Set $p to point to the left-most leaf in the tree of eType nodes. */
+ for(p=pRoot; p->eType==eType; p=p->pLeft){
+ assert( p->pParent==0 || p->pParent->pLeft==p );
+ assert( p->pLeft && p->pRight );
+ }
+
+ /* This loop runs once for each leaf in the tree of eType nodes. */
+ while( 1 ){
+ int iLvl;
+ Fts3Expr *pParent = p->pParent; /* Current parent of p */
+
+ assert( pParent==0 || pParent->pLeft==p );
+ p->pParent = 0;
+ if( pParent ){
+ pParent->pLeft = 0;
}else{
- pRoot = 0;
+ pRoot = 0;
}
- rc = fts3ExprBalance(&p, nMaxDepth-1);
- if( rc!=SQLITE_OK ) break;
+ rc = fts3ExprBalance(&p, nMaxDepth-1);
+ if( rc!=SQLITE_OK ) break;
- for(iLvl=0; p && iLvl<nMaxDepth; iLvl++){
- if( apLeaf[iLvl]==0 ){
- apLeaf[iLvl] = p;
- p = 0;
+ for(iLvl=0; p && iLvl<nMaxDepth; iLvl++){
+ if( apLeaf[iLvl]==0 ){
+ apLeaf[iLvl] = p;
+ p = 0;
}else{
- assert( pFree );
- pFree->pLeft = apLeaf[iLvl];
+ assert( pFree );
+ pFree->pLeft = apLeaf[iLvl];
pFree->pRight = p;
pFree->pLeft->pParent = pFree;
pFree->pRight->pParent = pFree;
@@ -180164,99 +180164,99 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){
p = pFree;
pFree = pFree->pParent;
p->pParent = 0;
- apLeaf[iLvl] = 0;
+ apLeaf[iLvl] = 0;
}
}
- if( p ){
- sqlite3Fts3ExprFree(p);
- rc = SQLITE_TOOBIG;
- break;
- }
-
- /* If that was the last leaf node, break out of the loop */
- if( pParent==0 ) break;
-
- /* Set $p to point to the next leaf in the tree of eType nodes */
- for(p=pParent->pRight; p->eType==eType; p=p->pLeft);
-
- /* Remove pParent from the original tree. */
- assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent );
- pParent->pRight->pParent = pParent->pParent;
- if( pParent->pParent ){
- pParent->pParent->pLeft = pParent->pRight;
- }else{
- assert( pParent==pRoot );
- pRoot = pParent->pRight;
- }
-
- /* Link pParent into the free node list. It will be used as an
- ** internal node of the new tree. */
- pParent->pParent = pFree;
- pFree = pParent;
- }
-
- if( rc==SQLITE_OK ){
- p = 0;
- for(i=0; i<nMaxDepth; i++){
- if( apLeaf[i] ){
- if( p==0 ){
- p = apLeaf[i];
- p->pParent = 0;
- }else{
- assert( pFree!=0 );
- pFree->pRight = p;
- pFree->pLeft = apLeaf[i];
- pFree->pLeft->pParent = pFree;
- pFree->pRight->pParent = pFree;
-
- p = pFree;
- pFree = pFree->pParent;
- p->pParent = 0;
- }
- }
- }
- pRoot = p;
- }else{
+ if( p ){
+ sqlite3Fts3ExprFree(p);
+ rc = SQLITE_TOOBIG;
+ break;
+ }
+
+ /* If that was the last leaf node, break out of the loop */
+ if( pParent==0 ) break;
+
+ /* Set $p to point to the next leaf in the tree of eType nodes */
+ for(p=pParent->pRight; p->eType==eType; p=p->pLeft);
+
+ /* Remove pParent from the original tree. */
+ assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent );
+ pParent->pRight->pParent = pParent->pParent;
+ if( pParent->pParent ){
+ pParent->pParent->pLeft = pParent->pRight;
+ }else{
+ assert( pParent==pRoot );
+ pRoot = pParent->pRight;
+ }
+
+ /* Link pParent into the free node list. It will be used as an
+ ** internal node of the new tree. */
+ pParent->pParent = pFree;
+ pFree = pParent;
+ }
+
+ if( rc==SQLITE_OK ){
+ p = 0;
+ for(i=0; i<nMaxDepth; i++){
+ if( apLeaf[i] ){
+ if( p==0 ){
+ p = apLeaf[i];
+ p->pParent = 0;
+ }else{
+ assert( pFree!=0 );
+ pFree->pRight = p;
+ pFree->pLeft = apLeaf[i];
+ pFree->pLeft->pParent = pFree;
+ pFree->pRight->pParent = pFree;
+
+ p = pFree;
+ pFree = pFree->pParent;
+ p->pParent = 0;
+ }
+ }
+ }
+ pRoot = p;
+ }else{
/* An error occurred. Delete the contents of the apLeaf[] array
- ** and pFree list. Everything else is cleaned up by the call to
- ** sqlite3Fts3ExprFree(pRoot) below. */
- Fts3Expr *pDel;
- for(i=0; i<nMaxDepth; i++){
- sqlite3Fts3ExprFree(apLeaf[i]);
- }
- while( (pDel=pFree)!=0 ){
- pFree = pDel->pParent;
- sqlite3_free(pDel);
- }
- }
-
- assert( pFree==0 );
- sqlite3_free( apLeaf );
- }
- }else if( eType==FTSQUERY_NOT ){
- Fts3Expr *pLeft = pRoot->pLeft;
- Fts3Expr *pRight = pRoot->pRight;
-
- pRoot->pLeft = 0;
- pRoot->pRight = 0;
- pLeft->pParent = 0;
- pRight->pParent = 0;
-
- rc = fts3ExprBalance(&pLeft, nMaxDepth-1);
- if( rc==SQLITE_OK ){
- rc = fts3ExprBalance(&pRight, nMaxDepth-1);
- }
-
- if( rc!=SQLITE_OK ){
- sqlite3Fts3ExprFree(pRight);
- sqlite3Fts3ExprFree(pLeft);
- }else{
- assert( pLeft && pRight );
- pRoot->pLeft = pLeft;
- pLeft->pParent = pRoot;
- pRoot->pRight = pRight;
- pRight->pParent = pRoot;
- }
+ ** and pFree list. Everything else is cleaned up by the call to
+ ** sqlite3Fts3ExprFree(pRoot) below. */
+ Fts3Expr *pDel;
+ for(i=0; i<nMaxDepth; i++){
+ sqlite3Fts3ExprFree(apLeaf[i]);
+ }
+ while( (pDel=pFree)!=0 ){
+ pFree = pDel->pParent;
+ sqlite3_free(pDel);
+ }
+ }
+
+ assert( pFree==0 );
+ sqlite3_free( apLeaf );
+ }
+ }else if( eType==FTSQUERY_NOT ){
+ Fts3Expr *pLeft = pRoot->pLeft;
+ Fts3Expr *pRight = pRoot->pRight;
+
+ pRoot->pLeft = 0;
+ pRoot->pRight = 0;
+ pLeft->pParent = 0;
+ pRight->pParent = 0;
+
+ rc = fts3ExprBalance(&pLeft, nMaxDepth-1);
+ if( rc==SQLITE_OK ){
+ rc = fts3ExprBalance(&pRight, nMaxDepth-1);
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3Fts3ExprFree(pRight);
+ sqlite3Fts3ExprFree(pLeft);
+ }else{
+ assert( pLeft && pRight );
+ pRoot->pLeft = pLeft;
+ pLeft->pParent = pRoot;
+ pRoot->pRight = pRight;
+ pRight->pParent = pRoot;
+ }
}
}
@@ -181698,18 +181698,18 @@ SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(
/* #include <string.h> */
/*
-** Return true if the two-argument version of fts3_tokenizer()
-** has been activated via a prior call to sqlite3_db_config(db,
-** SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0);
-*/
-static int fts3TokenizerEnabled(sqlite3_context *context){
- sqlite3 *db = sqlite3_context_db_handle(context);
- int isEnabled = 0;
- sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,-1,&isEnabled);
- return isEnabled;
-}
-
-/*
+** Return true if the two-argument version of fts3_tokenizer()
+** has been activated via a prior call to sqlite3_db_config(db,
+** SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0);
+*/
+static int fts3TokenizerEnabled(sqlite3_context *context){
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ int isEnabled = 0;
+ sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,-1,&isEnabled);
+ return isEnabled;
+}
+
+/*
** Implementation of the SQL scalar function for accessing the underlying
** hash table. This function may be called as follows:
**
@@ -181729,7 +181729,7 @@ static int fts3TokenizerEnabled(sqlite3_context *context){
** is a blob containing the pointer stored as the hash data corresponding
** to string <key-name> (after the hash-table is updated, if applicable).
*/
-static void fts3TokenizerFunc(
+static void fts3TokenizerFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
@@ -181748,19 +181748,19 @@ static void fts3TokenizerFunc(
if( argc==2 ){
if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[1]) ){
- void *pOld;
- int n = sqlite3_value_bytes(argv[1]);
- if( zName==0 || n!=sizeof(pPtr) ){
- sqlite3_result_error(context, "argument type mismatch", -1);
- return;
- }
- pPtr = *(void **)sqlite3_value_blob(argv[1]);
- pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
- if( pOld==pPtr ){
- sqlite3_result_error(context, "out of memory", -1);
- }
- }else{
- sqlite3_result_error(context, "fts3tokenize disabled", -1);
+ void *pOld;
+ int n = sqlite3_value_bytes(argv[1]);
+ if( zName==0 || n!=sizeof(pPtr) ){
+ sqlite3_result_error(context, "argument type mismatch", -1);
+ return;
+ }
+ pPtr = *(void **)sqlite3_value_blob(argv[1]);
+ pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
+ if( pOld==pPtr ){
+ sqlite3_result_error(context, "out of memory", -1);
+ }
+ }else{
+ sqlite3_result_error(context, "fts3tokenize disabled", -1);
return;
}
}else{
@@ -181894,11 +181894,11 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
#ifdef SQLITE_TEST
-#if defined(INCLUDE_SQLITE_TCL_H)
+#if defined(INCLUDE_SQLITE_TCL_H)
# error #include "sqlite_tcl.h"
-#else
-# include "tcl.h"
-#endif
+#else
+# include "tcl.h"
+#endif
/* #include <string.h> */
/*
@@ -182039,7 +182039,7 @@ int registerTokenizer(
return sqlite3_finalize(pStmt);
}
-
+
static
int queryTokenizer(
sqlite3 *db,
@@ -182112,13 +182112,13 @@ static void intTestFunc(
assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") );
/* Test the storage function */
- if( fts3TokenizerEnabled(context) ){
- rc = registerTokenizer(db, "nosuchtokenizer", p1);
- assert( rc==SQLITE_OK );
- rc = queryTokenizer(db, "nosuchtokenizer", &p2);
- assert( rc==SQLITE_OK );
- assert( p2==p1 );
- }
+ if( fts3TokenizerEnabled(context) ){
+ rc = registerTokenizer(db, "nosuchtokenizer", p1);
+ assert( rc==SQLITE_OK );
+ rc = queryTokenizer(db, "nosuchtokenizer", &p2);
+ assert( rc==SQLITE_OK );
+ assert( p2==p1 );
+ }
sqlite3_result_text(context, "ok", -1, SQLITE_STATIC);
}
@@ -182134,7 +182134,7 @@ static void intTestFunc(
** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
**
** This function adds a scalar function (see header comment above
-** fts3TokenizerFunc() in this file for details) and, if ENABLE_TABLE is
+** fts3TokenizerFunc() in this file for details) and, if ENABLE_TABLE is
** defined at compilation time, a temporary virtual table (see header
** comment above struct HashTableVtab) to the database schema. Both
** provide read/write access to the contents of *pHash.
@@ -182163,10 +182163,10 @@ SQLITE_PRIVATE int sqlite3Fts3InitHashTable(
#endif
if( SQLITE_OK==rc ){
- rc = sqlite3_create_function(db, zName, 1, any, p, fts3TokenizerFunc, 0, 0);
+ rc = sqlite3_create_function(db, zName, 1, any, p, fts3TokenizerFunc, 0, 0);
}
if( SQLITE_OK==rc ){
- rc = sqlite3_create_function(db, zName, 2, any, p, fts3TokenizerFunc, 0, 0);
+ rc = sqlite3_create_function(db, zName, 2, any, p, fts3TokenizerFunc, 0, 0);
}
#ifdef SQLITE_TEST
if( SQLITE_OK==rc ){
@@ -183220,8 +183220,8 @@ static int fts3SqlStmt(
** of the oldest level in the db that contains at least ? segments. Or,
** if no level in the FTS index contains more than ? segments, the statement
** returns zero rows. */
-/* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' "
- " GROUP BY level HAVING cnt>=?"
+/* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' "
+ " GROUP BY level HAVING cnt>=?"
" ORDER BY (level %% 1024) ASC, 2 DESC LIMIT 1",
/* Estimate the upper limit on the number of leaf nodes in a new segment
@@ -183752,12 +183752,12 @@ static int fts3PendingTermsAdd(
*/
static int fts3PendingTermsDocid(
Fts3Table *p, /* Full-text table handle */
- int bDelete, /* True if this op is a delete */
+ int bDelete, /* True if this op is a delete */
int iLangid, /* Language id of row being written */
sqlite_int64 iDocid /* Docid of row being written */
){
assert( iLangid>=0 );
- assert( bDelete==1 || bDelete==0 );
+ assert( bDelete==1 || bDelete==0 );
/* TODO(shess) Explore whether partially flushing the buffer on
** forced-flush would provide better performance. I suspect that if
@@ -183766,7 +183766,7 @@ static int fts3PendingTermsDocid(
** generate longer doclists.
*/
if( iDocid<p->iPrevDocid
- || (iDocid==p->iPrevDocid && p->bPrevDelete==0)
+ || (iDocid==p->iPrevDocid && p->bPrevDelete==0)
|| p->iPrevLangid!=iLangid
|| p->nPendingData>p->nMaxPendingData
){
@@ -183775,7 +183775,7 @@ static int fts3PendingTermsDocid(
}
p->iPrevDocid = iDocid;
p->iPrevLangid = iLangid;
- p->bPrevDelete = bDelete;
+ p->bPrevDelete = bDelete;
return SQLITE_OK;
}
@@ -183965,8 +183965,8 @@ static void fts3DeleteTerms(
if( SQLITE_ROW==sqlite3_step(pSelect) ){
int i;
int iLangid = langidFromSelect(p, pSelect);
- i64 iDocid = sqlite3_column_int64(pSelect, 0);
- rc = fts3PendingTermsDocid(p, 1, iLangid, iDocid);
+ i64 iDocid = sqlite3_column_int64(pSelect, 0);
+ rc = fts3PendingTermsDocid(p, 1, iLangid, iDocid);
for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){
int iCol = i-1;
if( p->abNotindexed[iCol]==0 ){
@@ -184216,12 +184216,12 @@ static int fts3SegReaderNext(
if( fts3SegReaderIsPending(pReader) ){
Fts3HashElem *pElem = *(pReader->ppNextElem);
- sqlite3_free(pReader->aNode);
- pReader->aNode = 0;
- if( pElem ){
- char *aCopy;
+ sqlite3_free(pReader->aNode);
+ pReader->aNode = 0;
+ if( pElem ){
+ char *aCopy;
PendingList *pList = (PendingList *)fts3HashData(pElem);
- int nCopy = pList->nData+1;
+ int nCopy = pList->nData+1;
int nTerm = fts3HashKeysize(pElem);
if( (nTerm+1)>pReader->nTermAlloc ){
@@ -184234,11 +184234,11 @@ static int fts3SegReaderNext(
pReader->zTerm[nTerm] = '\0';
pReader->nTerm = nTerm;
- aCopy = (char*)sqlite3_malloc(nCopy);
- if( !aCopy ) return SQLITE_NOMEM;
- memcpy(aCopy, pList->aData, nCopy);
- pReader->nNode = pReader->nDoclist = nCopy;
- pReader->aNode = pReader->aDoclist = aCopy;
+ aCopy = (char*)sqlite3_malloc(nCopy);
+ if( !aCopy ) return SQLITE_NOMEM;
+ memcpy(aCopy, pList->aData, nCopy);
+ pReader->nNode = pReader->nDoclist = nCopy;
+ pReader->aNode = pReader->aDoclist = aCopy;
pReader->ppNextElem++;
assert( pReader->aNode );
}
@@ -184485,12 +184485,12 @@ SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(
** second argument.
*/
SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
- if( pReader ){
+ if( pReader ){
sqlite3_free(pReader->zTerm);
if( !fts3SegReaderIsRootOnly(pReader) ){
sqlite3_free(pReader->aNode);
}
- sqlite3_blob_close(pReader->pBlob);
+ sqlite3_blob_close(pReader->pBlob);
}
sqlite3_free(pReader);
}
@@ -186136,7 +186136,7 @@ static int fts3SegmentMerge(
** segment. The level of the new segment is equal to the numerically
** greatest segment level currently present in the database for this
** index. The idx of the new segment is always 0. */
- if( csr.nSegment==1 && 0==fts3SegReaderIsPending(csr.apSegment[0]) ){
+ if( csr.nSegment==1 && 0==fts3SegReaderIsPending(csr.apSegment[0]) ){
rc = SQLITE_DONE;
goto finished;
}
@@ -186473,7 +186473,7 @@ static int fts3DoRebuild(Fts3Table *p){
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
int iCol;
int iLangid = langidFromSelect(p, pStmt);
- rc = fts3PendingTermsDocid(p, 0, iLangid, sqlite3_column_int64(pStmt, 0));
+ rc = fts3PendingTermsDocid(p, 0, iLangid, sqlite3_column_int64(pStmt, 0));
memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
if( p->abNotindexed[iCol]==0 ){
@@ -187824,11 +187824,11 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
** set nSeg to -1.
*/
rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0);
- sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin));
+ sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin));
if( sqlite3_step(pFindLevel)==SQLITE_ROW ){
iAbsLevel = sqlite3_column_int64(pFindLevel, 0);
- nSeg = sqlite3_column_int(pFindLevel, 1);
- assert( nSeg>=2 );
+ nSeg = sqlite3_column_int(pFindLevel, 1);
+ assert( nSeg>=2 );
}else{
nSeg = -1;
}
@@ -187964,14 +187964,14 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
** Convert the text beginning at *pz into an integer and return
** its value. Advance *pz to point to the first character past
** the integer.
-**
-** This function used for parameters to merge= and incrmerge=
+**
+** This function used for parameters to merge= and incrmerge=
** commands.
*/
static int fts3Getint(const char **pz){
const char *z = *pz;
int i = 0;
- while( (*z)>='0' && (*z)<='9' && i<214748363 ) i = 10*i + *(z++) - '0';
+ while( (*z)>='0' && (*z)<='9' && i<214748363 ) i = 10*i + *(z++) - '0';
*pz = z;
return i;
}
@@ -188649,7 +188649,7 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
}
}
if( rc==SQLITE_OK ){
- rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
+ rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
}
if( rc==SQLITE_OK ){
assert( p->iPrevDocid==*pRowid );
@@ -190589,14 +190589,14 @@ static int unicodeAddExceptions(
){
const unsigned char *z = (const unsigned char *)zIn;
const unsigned char *zTerm = &z[nIn];
- unsigned int iCode;
+ unsigned int iCode;
int nEntry = 0;
assert( bAlnum==0 || bAlnum==1 );
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
- assert( (sqlite3FtsUnicodeIsalnum((int)iCode) & 0xFFFFFFFE)==0 );
+ assert( (sqlite3FtsUnicodeIsalnum((int)iCode) & 0xFFFFFFFE)==0 );
if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum
&& sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
){
@@ -190616,12 +190616,12 @@ static int unicodeAddExceptions(
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum
- && sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
+ && sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
){
int i, j;
- for(i=0; i<nNew && aNew[i]<(int)iCode; i++);
+ for(i=0; i<nNew && aNew[i]<(int)iCode; i++);
for(j=nNew; j>i; j--) aNew[j] = aNew[j-1];
- aNew[i] = (int)iCode;
+ aNew[i] = (int)iCode;
nNew++;
}
}
@@ -190775,7 +190775,7 @@ static int unicodeNext(
){
unicode_cursor *pCsr = (unicode_cursor *)pC;
unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer);
- unsigned int iCode = 0;
+ unsigned int iCode = 0;
char *zOut;
const unsigned char *z = &pCsr->aInput[pCsr->iOff];
const unsigned char *zStart = z;
@@ -190787,7 +190787,7 @@ static int unicodeNext(
** the input. */
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
- if( unicodeIsAlnum(p, (int)iCode) ) break;
+ if( unicodeIsAlnum(p, (int)iCode) ) break;
zStart = z;
}
if( zStart>=zTerm ) return SQLITE_DONE;
@@ -190816,7 +190816,7 @@ static int unicodeNext(
if( z>=zTerm ) break;
READ_UTF8(z, zTerm, iCode);
}while( unicodeIsAlnum(p, (int)iCode)
- || sqlite3FtsUnicodeIsdiacritic((int)iCode)
+ || sqlite3FtsUnicodeIsdiacritic((int)iCode)
);
/* Set the output variables and return. */
@@ -190980,9 +190980,9 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
};
- if( (unsigned int)c<128 ){
- return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
- }else if( (unsigned int)c<(1<<22) ){
+ if( (unsigned int)c<128 ){
+ return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
+ }else if( (unsigned int)c<(1<<22) ){
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
int iRes = 0;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
@@ -191197,12 +191197,12 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){
if( c<128 ){
if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
}else if( c<65536 ){
- const struct TableEntry *p;
+ const struct TableEntry *p;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
int iRes = -1;
- assert( c>aEntry[0].iCode );
+ assert( c>aEntry[0].iCode );
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
int cmp = (c - aEntry[iTest].iCode);
@@ -191214,11 +191214,11 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){
}
}
- assert( iRes>=0 && c>=aEntry[iRes].iCode );
- p = &aEntry[iRes];
- if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
- ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
- assert( ret>0 );
+ assert( iRes>=0 && c>=aEntry[iRes].iCode );
+ p = &aEntry[iRes];
+ if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
+ ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
+ assert( ret>0 );
}
if( eRemoveDiacritic ){
@@ -194016,8 +194016,8 @@ SQLITE_API int sqlite3_json_init(
** child page.
*/
-#if !defined(SQLITE_CORE) \
- || (defined(SQLITE_ENABLE_RTREE) && !defined(SQLITE_OMIT_VIRTUALTABLE))
+#if !defined(SQLITE_CORE) \
+ || (defined(SQLITE_ENABLE_RTREE) && !defined(SQLITE_OMIT_VIRTUALTABLE))
#ifndef SQLITE_CORE
/* #include "sqlite3ext.h" */
@@ -194034,7 +194034,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite
#if !defined(SQLITE_AMALGAMATION)
#error #include "sqlite3rtree.h"
typedef sqlite3_int64 i64;
-typedef sqlite3_uint64 u64;
+typedef sqlite3_uint64 u64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
@@ -194110,10 +194110,10 @@ struct Rtree {
sqlite3 *db; /* Host database connection */
int iNodeSize; /* Size in bytes of each node in the node table */
u8 nDim; /* Number of dimensions */
- u8 nDim2; /* Twice the number of dimensions */
+ u8 nDim2; /* Twice the number of dimensions */
u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
u8 nBytesPerCell; /* Bytes consumed per cell */
- u8 inWrTrans; /* True if inside write transaction */
+ u8 inWrTrans; /* True if inside write transaction */
u8 nAux; /* # of auxiliary columns in %_rowid */
#ifdef SQLITE_ENABLE_GEOPOLY
u8 nAuxNotNull; /* Number of initial not-null aux columns */
@@ -194124,9 +194124,9 @@ struct Rtree {
int iDepth; /* Current depth of the r-tree structure */
char *zDb; /* Name of database containing r-tree table */
char *zName; /* Name of r-tree table */
- u32 nBusy; /* Current number of users of this structure */
+ u32 nBusy; /* Current number of users of this structure */
i64 nRowEst; /* Estimated number of rows in this table */
- u32 nCursor; /* Number of open cursors */
+ u32 nCursor; /* Number of open cursors */
u32 nNodeRef; /* Number RtreeNodes with positive nRef */
char *zReadAuxSql; /* SQL for statement to read aux data */
@@ -194138,9 +194138,9 @@ struct Rtree {
RtreeNode *pDeleted;
int iReinsertHeight; /* Height of sub-trees Reinsert() has run on */
- /* Blob I/O on xxx_node */
- sqlite3_blob *pNodeBlob;
-
+ /* Blob I/O on xxx_node */
+ sqlite3_blob *pNodeBlob;
+
/* Statements to read/write/delete a record from xxx_node */
sqlite3_stmt *pWriteNode;
sqlite3_stmt *pDeleteNode;
@@ -194223,7 +194223,7 @@ struct RtreeSearchPoint {
** The smallest possible node-size is (512-64)==448 bytes. And the largest
** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates).
** Therefore all non-root nodes must contain at least 3 entries. Since
-** 3^40 is greater than 2^64, an r-tree structure always has a depth of
+** 3^40 is greater than 2^64, an r-tree structure always has a depth of
** 40 or less.
*/
#define RTREE_MAX_DEPTH 40
@@ -194368,7 +194368,7 @@ struct RtreeGeomCallback {
** operand to the MATCH operator of an R-Tree.
*/
struct RtreeMatchArg {
- u32 iSize; /* Size of this object */
+ u32 iSize; /* Size of this object */
RtreeGeomCallback cb; /* Info about the callback functions */
int nParam; /* Number of parameters to the SQL function */
sqlite3_value **apSqlParam; /* Original SQL parameter values */
@@ -194382,31 +194382,31 @@ struct RtreeMatchArg {
# define MIN(x,y) ((x) > (y) ? (y) : (x))
#endif
-/* What version of GCC is being used. 0 means GCC is not being used .
-** Note that the GCC_VERSION macro will also be set correctly when using
-** clang, since clang works hard to be gcc compatible. So the gcc
-** optimizations will also work when compiling with clang.
-*/
-#ifndef GCC_VERSION
-#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
-# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
-#else
-# define GCC_VERSION 0
-#endif
-#endif
-
-/* The testcase() macro should already be defined in the amalgamation. If
-** it is not, make it a no-op.
-*/
-#ifndef SQLITE_AMALGAMATION
+/* What version of GCC is being used. 0 means GCC is not being used .
+** Note that the GCC_VERSION macro will also be set correctly when using
+** clang, since clang works hard to be gcc compatible. So the gcc
+** optimizations will also work when compiling with clang.
+*/
+#ifndef GCC_VERSION
+#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
+# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
+#else
+# define GCC_VERSION 0
+#endif
+#endif
+
+/* The testcase() macro should already be defined in the amalgamation. If
+** it is not, make it a no-op.
+*/
+#ifndef SQLITE_AMALGAMATION
# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
unsigned int sqlite3RtreeTestcase = 0;
# define testcase(X) if( X ){ sqlite3RtreeTestcase += __LINE__; }
# else
# define testcase(X)
# endif
-#endif
-
+#endif
+
/*
** Make sure that the compiler intrinsics we desire are enabled when
** compiling with an appropriate version of MSVC unless prevented by
@@ -194425,38 +194425,38 @@ struct RtreeMatchArg {
#endif
/*
-** Macros to determine whether the machine is big or little endian,
-** and whether or not that determination is run-time or compile-time.
-**
-** For best performance, an attempt is made to guess at the byte-order
-** using C-preprocessor macros. If that is unsuccessful, or if
-** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
-** at run-time.
-*/
-#ifndef SQLITE_BYTEORDER
-#if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
- defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
- defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
- defined(__arm__)
-# define SQLITE_BYTEORDER 1234
-#elif defined(sparc) || defined(__ppc__)
-# define SQLITE_BYTEORDER 4321
-#else
-# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
-#endif
-#endif
-
-
-/* What version of MSVC is being used. 0 means MSVC is not being used */
-#ifndef MSVC_VERSION
-#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
-# define MSVC_VERSION _MSC_VER
-#else
-# define MSVC_VERSION 0
-#endif
-#endif
-
-/*
+** Macros to determine whether the machine is big or little endian,
+** and whether or not that determination is run-time or compile-time.
+**
+** For best performance, an attempt is made to guess at the byte-order
+** using C-preprocessor macros. If that is unsuccessful, or if
+** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
+** at run-time.
+*/
+#ifndef SQLITE_BYTEORDER
+#if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
+ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
+ defined(__arm__)
+# define SQLITE_BYTEORDER 1234
+#elif defined(sparc) || defined(__ppc__)
+# define SQLITE_BYTEORDER 4321
+#else
+# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
+#endif
+#endif
+
+
+/* What version of MSVC is being used. 0 means MSVC is not being used */
+#ifndef MSVC_VERSION
+#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
+# define MSVC_VERSION _MSC_VER
+#else
+# define MSVC_VERSION 0
+#endif
+#endif
+
+/*
** Functions to deserialize a 16 bit integer, 32 bit real number and
** 64 bit integer. The deserialized value is returned.
*/
@@ -194464,37 +194464,37 @@ static int readInt16(u8 *p){
return (p[0]<<8) + p[1];
}
static void readCoord(u8 *p, RtreeCoord *pCoord){
- assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */
-#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
- pCoord->u = _byteswap_ulong(*(u32*)p);
-#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
- pCoord->u = __builtin_bswap32(*(u32*)p);
-#elif SQLITE_BYTEORDER==4321
- pCoord->u = *(u32*)p;
-#else
+ assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */
+#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+ pCoord->u = _byteswap_ulong(*(u32*)p);
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+ pCoord->u = __builtin_bswap32(*(u32*)p);
+#elif SQLITE_BYTEORDER==4321
+ pCoord->u = *(u32*)p;
+#else
pCoord->u = (
(((u32)p[0]) << 24) +
(((u32)p[1]) << 16) +
(((u32)p[2]) << 8) +
(((u32)p[3]) << 0)
);
-#endif
+#endif
}
static i64 readInt64(u8 *p){
-#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
- u64 x;
- memcpy(&x, p, 8);
- return (i64)_byteswap_uint64(x);
-#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
- u64 x;
- memcpy(&x, p, 8);
- return (i64)__builtin_bswap64(x);
-#elif SQLITE_BYTEORDER==4321
- i64 x;
- memcpy(&x, p, 8);
- return x;
-#else
- return (i64)(
+#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+ u64 x;
+ memcpy(&x, p, 8);
+ return (i64)_byteswap_uint64(x);
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+ u64 x;
+ memcpy(&x, p, 8);
+ return (i64)__builtin_bswap64(x);
+#elif SQLITE_BYTEORDER==4321
+ i64 x;
+ memcpy(&x, p, 8);
+ return x;
+#else
+ return (i64)(
(((u64)p[0]) << 56) +
(((u64)p[1]) << 48) +
(((u64)p[2]) << 40) +
@@ -194502,9 +194502,9 @@ static i64 readInt64(u8 *p){
(((u64)p[4]) << 24) +
(((u64)p[5]) << 16) +
(((u64)p[6]) << 8) +
- (((u64)p[7]) << 0)
+ (((u64)p[7]) << 0)
);
-#endif
+#endif
}
/*
@@ -194512,43 +194512,43 @@ static i64 readInt64(u8 *p){
** 64 bit integer. The value returned is the number of bytes written
** to the argument buffer (always 2, 4 and 8 respectively).
*/
-static void writeInt16(u8 *p, int i){
+static void writeInt16(u8 *p, int i){
p[0] = (i>> 8)&0xFF;
p[1] = (i>> 0)&0xFF;
}
static int writeCoord(u8 *p, RtreeCoord *pCoord){
u32 i;
- assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */
+ assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */
assert( sizeof(RtreeCoord)==4 );
assert( sizeof(u32)==4 );
-#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
- i = __builtin_bswap32(pCoord->u);
- memcpy(p, &i, 4);
-#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
- i = _byteswap_ulong(pCoord->u);
- memcpy(p, &i, 4);
-#elif SQLITE_BYTEORDER==4321
+#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+ i = __builtin_bswap32(pCoord->u);
+ memcpy(p, &i, 4);
+#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+ i = _byteswap_ulong(pCoord->u);
+ memcpy(p, &i, 4);
+#elif SQLITE_BYTEORDER==4321
+ i = pCoord->u;
+ memcpy(p, &i, 4);
+#else
i = pCoord->u;
- memcpy(p, &i, 4);
-#else
- i = pCoord->u;
p[0] = (i>>24)&0xFF;
p[1] = (i>>16)&0xFF;
p[2] = (i>> 8)&0xFF;
p[3] = (i>> 0)&0xFF;
-#endif
+#endif
return 4;
}
static int writeInt64(u8 *p, i64 i){
-#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
- i = (i64)__builtin_bswap64((u64)i);
- memcpy(p, &i, 8);
-#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
- i = (i64)_byteswap_uint64((u64)i);
- memcpy(p, &i, 8);
-#elif SQLITE_BYTEORDER==4321
- memcpy(p, &i, 8);
-#else
+#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+ i = (i64)__builtin_bswap64((u64)i);
+ memcpy(p, &i, 8);
+#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+ i = (i64)_byteswap_uint64((u64)i);
+ memcpy(p, &i, 8);
+#elif SQLITE_BYTEORDER==4321
+ memcpy(p, &i, 8);
+#else
p[0] = (i>>56)&0xFF;
p[1] = (i>>48)&0xFF;
p[2] = (i>>40)&0xFF;
@@ -194557,7 +194557,7 @@ static int writeInt64(u8 *p, i64 i){
p[5] = (i>>16)&0xFF;
p[6] = (i>> 8)&0xFF;
p[7] = (i>> 0)&0xFF;
-#endif
+#endif
return 8;
}
@@ -194643,17 +194643,17 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
}
/*
-** Clear the Rtree.pNodeBlob object
-*/
-static void nodeBlobReset(Rtree *pRtree){
- if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
- sqlite3_blob *pBlob = pRtree->pNodeBlob;
- pRtree->pNodeBlob = 0;
- sqlite3_blob_close(pBlob);
- }
-}
-
-/*
+** Clear the Rtree.pNodeBlob object
+*/
+static void nodeBlobReset(Rtree *pRtree){
+ if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
+ sqlite3_blob *pBlob = pRtree->pNodeBlob;
+ pRtree->pNodeBlob = 0;
+ sqlite3_blob_close(pBlob);
+ }
+}
+
+/*
** Obtain a reference to an r-tree node.
*/
static int nodeAcquire(
@@ -194662,8 +194662,8 @@ static int nodeAcquire(
RtreeNode *pParent, /* Either the parent node or NULL */
RtreeNode **ppNode /* OUT: Acquired node */
){
- int rc = SQLITE_OK;
- RtreeNode *pNode = 0;
+ int rc = SQLITE_OK;
+ RtreeNode *pNode = 0;
/* Check if the requested node is already in the hash table. If so,
** increase its reference count and return it.
@@ -194678,48 +194678,48 @@ static int nodeAcquire(
return SQLITE_OK;
}
- if( pRtree->pNodeBlob ){
- sqlite3_blob *pBlob = pRtree->pNodeBlob;
- pRtree->pNodeBlob = 0;
- rc = sqlite3_blob_reopen(pBlob, iNode);
- pRtree->pNodeBlob = pBlob;
- if( rc ){
- nodeBlobReset(pRtree);
- if( rc==SQLITE_NOMEM ) return SQLITE_NOMEM;
- }
- }
- if( pRtree->pNodeBlob==0 ){
- char *zTab = sqlite3_mprintf("%s_node", pRtree->zName);
- if( zTab==0 ) return SQLITE_NOMEM;
- rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, zTab, "data", iNode, 0,
- &pRtree->pNodeBlob);
- sqlite3_free(zTab);
- }
- if( rc ){
- nodeBlobReset(pRtree);
- *ppNode = 0;
- /* If unable to open an sqlite3_blob on the desired row, that can only
- ** be because the shadow tables hold erroneous data. */
+ if( pRtree->pNodeBlob ){
+ sqlite3_blob *pBlob = pRtree->pNodeBlob;
+ pRtree->pNodeBlob = 0;
+ rc = sqlite3_blob_reopen(pBlob, iNode);
+ pRtree->pNodeBlob = pBlob;
+ if( rc ){
+ nodeBlobReset(pRtree);
+ if( rc==SQLITE_NOMEM ) return SQLITE_NOMEM;
+ }
+ }
+ if( pRtree->pNodeBlob==0 ){
+ char *zTab = sqlite3_mprintf("%s_node", pRtree->zName);
+ if( zTab==0 ) return SQLITE_NOMEM;
+ rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, zTab, "data", iNode, 0,
+ &pRtree->pNodeBlob);
+ sqlite3_free(zTab);
+ }
+ if( rc ){
+ nodeBlobReset(pRtree);
+ *ppNode = 0;
+ /* If unable to open an sqlite3_blob on the desired row, that can only
+ ** be because the shadow tables hold erroneous data. */
if( rc==SQLITE_ERROR ){
rc = SQLITE_CORRUPT_VTAB;
RTREE_IS_CORRUPT(pRtree);
}
- }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
+ }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize);
- if( !pNode ){
- rc = SQLITE_NOMEM;
- }else{
- pNode->pParent = pParent;
- pNode->zData = (u8 *)&pNode[1];
- pNode->nRef = 1;
+ if( !pNode ){
+ rc = SQLITE_NOMEM;
+ }else{
+ pNode->pParent = pParent;
+ pNode->zData = (u8 *)&pNode[1];
+ pNode->nRef = 1;
pRtree->nNodeRef++;
- pNode->iNode = iNode;
- pNode->isDirty = 0;
- pNode->pNext = 0;
- rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData,
- pRtree->iNodeSize, 0);
- }
- }
+ pNode->iNode = iNode;
+ pNode->isDirty = 0;
+ pNode->pNext = 0;
+ rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData,
+ pRtree->iNodeSize, 0);
+ }
+ }
/* If the root node was just loaded, set pRtree->iDepth to the height
** of the r-tree structure. A height of zero means all data is stored on
@@ -194778,7 +194778,7 @@ static void nodeOverwriteCell(
int ii;
u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
p += writeInt64(p, pCell->iRowid);
- for(ii=0; ii<pRtree->nDim2; ii++){
+ for(ii=0; ii<pRtree->nDim2; ii++){
p += writeCoord(p, &pCell->aCoord[ii]);
}
pNode->isDirty = 1;
@@ -194915,16 +194915,16 @@ static void nodeGetCell(
){
u8 *pData;
RtreeCoord *pCoord;
- int ii = 0;
+ int ii = 0;
pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell);
pCoord = pCell->aCoord;
- do{
- readCoord(pData, &pCoord[ii]);
- readCoord(pData+4, &pCoord[ii+1]);
- pData += 8;
- ii += 2;
- }while( ii<pRtree->nDim2 );
+ do{
+ readCoord(pData, &pCoord[ii]);
+ readCoord(pData+4, &pCoord[ii+1]);
+ pData += 8;
+ ii += 2;
+ }while( ii<pRtree->nDim2 );
}
@@ -194975,9 +194975,9 @@ static void rtreeReference(Rtree *pRtree){
static void rtreeRelease(Rtree *pRtree){
pRtree->nBusy--;
if( pRtree->nBusy==0 ){
- pRtree->inWrTrans = 0;
+ pRtree->inWrTrans = 0;
assert( pRtree->nCursor==0 );
- nodeBlobReset(pRtree);
+ nodeBlobReset(pRtree);
assert( pRtree->nNodeRef==0 || pRtree->bCorrupt );
sqlite3_finalize(pRtree->pWriteNode);
sqlite3_finalize(pRtree->pDeleteNode);
@@ -195018,7 +195018,7 @@ static int rtreeDestroy(sqlite3_vtab *pVtab){
if( !zCreate ){
rc = SQLITE_NOMEM;
}else{
- nodeBlobReset(pRtree);
+ nodeBlobReset(pRtree);
rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0);
sqlite3_free(zCreate);
}
@@ -195034,7 +195034,7 @@ static int rtreeDestroy(sqlite3_vtab *pVtab){
*/
static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
int rc = SQLITE_NOMEM;
- Rtree *pRtree = (Rtree *)pVTab;
+ Rtree *pRtree = (Rtree *)pVTab;
RtreeCursor *pCsr;
pCsr = (RtreeCursor *)sqlite3_malloc64(sizeof(RtreeCursor));
@@ -195042,7 +195042,7 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
memset(pCsr, 0, sizeof(RtreeCursor));
pCsr->base.pVtab = pVTab;
rc = SQLITE_OK;
- pRtree->nCursor++;
+ pRtree->nCursor++;
}
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
@@ -195084,12 +195084,12 @@ static void resetCursor(RtreeCursor *pCsr){
static int rtreeClose(sqlite3_vtab_cursor *cur){
Rtree *pRtree = (Rtree *)(cur->pVtab);
RtreeCursor *pCsr = (RtreeCursor *)cur;
- assert( pRtree->nCursor>0 );
+ assert( pRtree->nCursor>0 );
resetCursor(pCsr);
sqlite3_finalize(pCsr->pReadAux);
sqlite3_free(pCsr);
- pRtree->nCursor--;
- nodeBlobReset(pRtree);
+ pRtree->nCursor--;
+ nodeBlobReset(pRtree);
return SQLITE_OK;
}
@@ -195112,30 +195112,30 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){
** false. a[] is the four bytes of the on-disk record to be decoded.
** Store the results in "r".
**
-** There are five versions of this macro. The last one is generic. The
-** other four are various architectures-specific optimizations.
+** There are five versions of this macro. The last one is generic. The
+** other four are various architectures-specific optimizations.
*/
-#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+#define RTREE_DECODE_COORD(eInt, a, r) { \
+ RtreeCoord c; /* Coordinate decoded */ \
+ c.u = _byteswap_ulong(*(u32*)a); \
+ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
+}
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+#define RTREE_DECODE_COORD(eInt, a, r) { \
+ RtreeCoord c; /* Coordinate decoded */ \
+ c.u = __builtin_bswap32(*(u32*)a); \
+ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
+}
+#elif SQLITE_BYTEORDER==1234
#define RTREE_DECODE_COORD(eInt, a, r) { \
RtreeCoord c; /* Coordinate decoded */ \
- c.u = _byteswap_ulong(*(u32*)a); \
- r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
-}
-#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
-#define RTREE_DECODE_COORD(eInt, a, r) { \
- RtreeCoord c; /* Coordinate decoded */ \
- c.u = __builtin_bswap32(*(u32*)a); \
- r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
-}
-#elif SQLITE_BYTEORDER==1234
-#define RTREE_DECODE_COORD(eInt, a, r) { \
- RtreeCoord c; /* Coordinate decoded */ \
memcpy(&c.u,a,4); \
c.u = ((c.u>>24)&0xff)|((c.u>>8)&0xff00)| \
((c.u&0xff)<<24)|((c.u&0xff00)<<8); \
r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
}
-#elif SQLITE_BYTEORDER==4321
+#elif SQLITE_BYTEORDER==4321
#define RTREE_DECODE_COORD(eInt, a, r) { \
RtreeCoord c; /* Coordinate decoded */ \
memcpy(&c.u,a,4); \
@@ -195165,7 +195165,7 @@ static int rtreeCallbackConstraint(
sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */
int nCoord = pInfo->nCoord; /* No. of coordinates */
int rc; /* Callback return code */
- RtreeCoord c; /* Translator union */
+ RtreeCoord c; /* Translator union */
sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */
assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY );
@@ -195175,41 +195175,41 @@ static int rtreeCallbackConstraint(
pInfo->iRowid = readInt64(pCellData);
}
pCellData += 8;
-#ifndef SQLITE_RTREE_INT_ONLY
- if( eInt==0 ){
- switch( nCoord ){
- case 10: readCoord(pCellData+36, &c); aCoord[9] = c.f;
- readCoord(pCellData+32, &c); aCoord[8] = c.f;
- case 8: readCoord(pCellData+28, &c); aCoord[7] = c.f;
- readCoord(pCellData+24, &c); aCoord[6] = c.f;
- case 6: readCoord(pCellData+20, &c); aCoord[5] = c.f;
- readCoord(pCellData+16, &c); aCoord[4] = c.f;
- case 4: readCoord(pCellData+12, &c); aCoord[3] = c.f;
- readCoord(pCellData+8, &c); aCoord[2] = c.f;
- default: readCoord(pCellData+4, &c); aCoord[1] = c.f;
- readCoord(pCellData, &c); aCoord[0] = c.f;
- }
- }else
-#endif
- {
- switch( nCoord ){
- case 10: readCoord(pCellData+36, &c); aCoord[9] = c.i;
- readCoord(pCellData+32, &c); aCoord[8] = c.i;
- case 8: readCoord(pCellData+28, &c); aCoord[7] = c.i;
- readCoord(pCellData+24, &c); aCoord[6] = c.i;
- case 6: readCoord(pCellData+20, &c); aCoord[5] = c.i;
- readCoord(pCellData+16, &c); aCoord[4] = c.i;
- case 4: readCoord(pCellData+12, &c); aCoord[3] = c.i;
- readCoord(pCellData+8, &c); aCoord[2] = c.i;
- default: readCoord(pCellData+4, &c); aCoord[1] = c.i;
- readCoord(pCellData, &c); aCoord[0] = c.i;
- }
+#ifndef SQLITE_RTREE_INT_ONLY
+ if( eInt==0 ){
+ switch( nCoord ){
+ case 10: readCoord(pCellData+36, &c); aCoord[9] = c.f;
+ readCoord(pCellData+32, &c); aCoord[8] = c.f;
+ case 8: readCoord(pCellData+28, &c); aCoord[7] = c.f;
+ readCoord(pCellData+24, &c); aCoord[6] = c.f;
+ case 6: readCoord(pCellData+20, &c); aCoord[5] = c.f;
+ readCoord(pCellData+16, &c); aCoord[4] = c.f;
+ case 4: readCoord(pCellData+12, &c); aCoord[3] = c.f;
+ readCoord(pCellData+8, &c); aCoord[2] = c.f;
+ default: readCoord(pCellData+4, &c); aCoord[1] = c.f;
+ readCoord(pCellData, &c); aCoord[0] = c.f;
+ }
+ }else
+#endif
+ {
+ switch( nCoord ){
+ case 10: readCoord(pCellData+36, &c); aCoord[9] = c.i;
+ readCoord(pCellData+32, &c); aCoord[8] = c.i;
+ case 8: readCoord(pCellData+28, &c); aCoord[7] = c.i;
+ readCoord(pCellData+24, &c); aCoord[6] = c.i;
+ case 6: readCoord(pCellData+20, &c); aCoord[5] = c.i;
+ readCoord(pCellData+16, &c); aCoord[4] = c.i;
+ case 4: readCoord(pCellData+12, &c); aCoord[3] = c.i;
+ readCoord(pCellData+8, &c); aCoord[2] = c.i;
+ default: readCoord(pCellData+4, &c); aCoord[1] = c.i;
+ readCoord(pCellData, &c); aCoord[0] = c.i;
+ }
}
if( pConstraint->op==RTREE_MATCH ){
- int eWithin = 0;
+ int eWithin = 0;
rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo,
- nCoord, aCoord, &eWithin);
- if( eWithin==0 ) *peWithin = NOT_WITHIN;
+ nCoord, aCoord, &eWithin);
+ if( eWithin==0 ) *peWithin = NOT_WITHIN;
*prScore = RTREE_ZERO;
}else{
pInfo->aCoord = aCoord;
@@ -195246,7 +195246,7 @@ static void rtreeNonleafConstraint(
assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
|| p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE
|| p->op==RTREE_FALSE );
- assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
+ assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
switch( p->op ){
case RTREE_TRUE: return; /* Always satisfied */
case RTREE_FALSE: break; /* Never satisfied */
@@ -195299,7 +195299,7 @@ static void rtreeLeafConstraint(
|| p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE
|| p->op==RTREE_FALSE );
pCellData += 8 + p->iCoord*4;
- assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
+ assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
RTREE_DECODE_COORD(eInt, pCellData, xN);
switch( p->op ){
case RTREE_TRUE: return; /* Always satisfied */
@@ -195372,7 +195372,7 @@ static int rtreeSearchPointCompare(
}
/*
-** Interchange two search points in a cursor.
+** Interchange two search points in a cursor.
*/
static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){
RtreeSearchPoint t = p->aPoint[i];
@@ -195632,7 +195632,7 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){
if( rScore<RTREE_ZERO ) rScore = RTREE_ZERO;
p = rtreeSearchPointNew(pCur, rScore, x.iLevel);
if( p==0 ) return SQLITE_NOMEM;
- p->eWithin = (u8)eWithin;
+ p->eWithin = (u8)eWithin;
p->id = x.id;
p->iCell = x.iCell;
RTREE_QUEUE_TRACE(pCur, "PUSH-S:");
@@ -195763,17 +195763,17 @@ static int findLeafNode(
** operator.
*/
static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
- RtreeMatchArg *pBlob, *pSrc; /* BLOB returned by geometry function */
+ RtreeMatchArg *pBlob, *pSrc; /* BLOB returned by geometry function */
sqlite3_rtree_query_info *pInfo; /* Callback information */
- pSrc = sqlite3_value_pointer(pValue, "RtreeMatchArg");
- if( pSrc==0 ) return SQLITE_ERROR;
- pInfo = (sqlite3_rtree_query_info*)
- sqlite3_malloc64( sizeof(*pInfo)+pSrc->iSize );
+ pSrc = sqlite3_value_pointer(pValue, "RtreeMatchArg");
+ if( pSrc==0 ) return SQLITE_ERROR;
+ pInfo = (sqlite3_rtree_query_info*)
+ sqlite3_malloc64( sizeof(*pInfo)+pSrc->iSize );
if( !pInfo ) return SQLITE_NOMEM;
memset(pInfo, 0, sizeof(*pInfo));
pBlob = (RtreeMatchArg*)&pInfo[1];
- memcpy(pBlob, pSrc, pSrc->iSize);
+ memcpy(pBlob, pSrc, pSrc->iSize);
pInfo->pContext = pBlob->cb.pContext;
pInfo->nParam = pBlob->nParam;
pInfo->aParam = pBlob->aParam;
@@ -195813,7 +195813,7 @@ static int rtreeFilter(
if( idxNum==1 ){
/* Special case - lookup by rowid. */
RtreeNode *pLeaf; /* Leaf on which the required cell resides */
- RtreeSearchPoint *p; /* Search point for the leaf */
+ RtreeSearchPoint *p; /* Search point for the leaf */
i64 iRowid = sqlite3_value_int64(argv[0]);
i64 iNode = 0;
int eType = sqlite3_value_numeric_type(argv[0]);
@@ -195832,7 +195832,7 @@ static int rtreeFilter(
p->id = iNode;
p->eWithin = PARTLY_WITHIN;
rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell);
- p->iCell = (u8)iCell;
+ p->iCell = (u8)iCell;
RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:");
}else{
pCsr->atEOF = 1;
@@ -195866,7 +195866,7 @@ static int rtreeFilter(
if( rc!=SQLITE_OK ){
break;
}
- p->pInfo->nCoord = pRtree->nDim2;
+ p->pInfo->nCoord = pRtree->nDim2;
p->pInfo->anQueue = pCsr->anQueue;
p->pInfo->mxLevel = pRtree->iDepth + 1;
}else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
@@ -195891,7 +195891,7 @@ static int rtreeFilter(
if( rc==SQLITE_OK ){
RtreeSearchPoint *pNew;
assert( pCsr->bPoint==0 ); /* Due to the resetCursor() call above */
- pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1));
+ pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1));
if( NEVER(pNew==0) ){ /* Because pCsr->bPoint was FALSE */
return SQLITE_NOMEM;
}
@@ -195990,7 +195990,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
** a single row.
*/
pIdxInfo->estimatedCost = 30.0;
- pIdxInfo->estimatedRows = 1;
+ pIdxInfo->estimatedRows = 1;
pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
return SQLITE_OK;
}
@@ -196024,9 +196024,9 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
return SQLITE_NOMEM;
}
- nRow = pRtree->nRowEst >> (iIdx/2);
+ nRow = pRtree->nRowEst >> (iIdx/2);
pIdxInfo->estimatedCost = (double)6.0 * (double)nRow;
- pIdxInfo->estimatedRows = nRow;
+ pIdxInfo->estimatedRows = nRow;
return rc;
}
@@ -196036,26 +196036,26 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
*/
static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
RtreeDValue area = (RtreeDValue)1;
- assert( pRtree->nDim>=1 && pRtree->nDim<=5 );
-#ifndef SQLITE_RTREE_INT_ONLY
- if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- switch( pRtree->nDim ){
- case 5: area = p->aCoord[9].f - p->aCoord[8].f;
- case 4: area *= p->aCoord[7].f - p->aCoord[6].f;
- case 3: area *= p->aCoord[5].f - p->aCoord[4].f;
- case 2: area *= p->aCoord[3].f - p->aCoord[2].f;
- default: area *= p->aCoord[1].f - p->aCoord[0].f;
- }
- }else
-#endif
- {
- switch( pRtree->nDim ){
+ assert( pRtree->nDim>=1 && pRtree->nDim<=5 );
+#ifndef SQLITE_RTREE_INT_ONLY
+ if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+ switch( pRtree->nDim ){
+ case 5: area = p->aCoord[9].f - p->aCoord[8].f;
+ case 4: area *= p->aCoord[7].f - p->aCoord[6].f;
+ case 3: area *= p->aCoord[5].f - p->aCoord[4].f;
+ case 2: area *= p->aCoord[3].f - p->aCoord[2].f;
+ default: area *= p->aCoord[1].f - p->aCoord[0].f;
+ }
+ }else
+#endif
+ {
+ switch( pRtree->nDim ){
case 5: area = (i64)p->aCoord[9].i - (i64)p->aCoord[8].i;
case 4: area *= (i64)p->aCoord[7].i - (i64)p->aCoord[6].i;
case 3: area *= (i64)p->aCoord[5].i - (i64)p->aCoord[4].i;
case 2: area *= (i64)p->aCoord[3].i - (i64)p->aCoord[2].i;
default: area *= (i64)p->aCoord[1].i - (i64)p->aCoord[0].i;
- }
+ }
}
return area;
}
@@ -196065,12 +196065,12 @@ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
** of the objects size in each dimension.
*/
static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
- RtreeDValue margin = 0;
- int ii = pRtree->nDim2 - 2;
- do{
+ RtreeDValue margin = 0;
+ int ii = pRtree->nDim2 - 2;
+ do{
margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
- ii -= 2;
- }while( ii>=0 );
+ ii -= 2;
+ }while( ii>=0 );
return margin;
}
@@ -196078,19 +196078,19 @@ static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
** Store the union of cells p1 and p2 in p1.
*/
static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
- int ii = 0;
+ int ii = 0;
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- do{
+ do{
p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f);
p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f);
- ii += 2;
- }while( ii<pRtree->nDim2 );
+ ii += 2;
+ }while( ii<pRtree->nDim2 );
}else{
- do{
+ do{
p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i);
p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i);
- ii += 2;
- }while( ii<pRtree->nDim2 );
+ ii += 2;
+ }while( ii<pRtree->nDim2 );
}
}
@@ -196101,7 +196101,7 @@ static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
int ii;
int isInt = (pRtree->eCoordType==RTREE_COORD_INT32);
- for(ii=0; ii<pRtree->nDim2; ii+=2){
+ for(ii=0; ii<pRtree->nDim2; ii+=2){
RtreeCoord *a1 = &p1->aCoord[ii];
RtreeCoord *a2 = &p2->aCoord[ii];
if( (!isInt && (a2[0].f<a1[0].f || a2[1].f>a1[1].f))
@@ -196136,7 +196136,7 @@ static RtreeDValue cellOverlap(
for(ii=0; ii<nCell; ii++){
int jj;
RtreeDValue o = (RtreeDValue)1;
- for(jj=0; jj<pRtree->nDim2; jj+=2){
+ for(jj=0; jj<pRtree->nDim2; jj+=2){
RtreeDValue x1, x2;
x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj]));
x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1]));
@@ -196165,7 +196165,7 @@ static int ChooseLeaf(
){
int rc;
int ii;
- RtreeNode *pNode = 0;
+ RtreeNode *pNode = 0;
rc = nodeAcquire(pRtree, 1, 0, &pNode);
for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
@@ -197016,7 +197016,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
int rc; /* Return code */
RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */
int iCell; /* Index of iDelete cell in pLeaf */
- RtreeNode *pRoot = 0; /* Root node of rtree structure */
+ RtreeNode *pRoot = 0; /* Root node of rtree structure */
/* Obtain a reference to the root node to initialize Rtree.iDepth */
@@ -197063,7 +197063,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
*/
if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){
int rc2;
- RtreeNode *pChild = 0;
+ RtreeNode *pChild = 0;
i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); /* tag-20210916a */
if( rc==SQLITE_OK ){
@@ -197127,54 +197127,54 @@ static RtreeValue rtreeValueUp(sqlite3_value *v){
}
#endif /* !defined(SQLITE_RTREE_INT_ONLY) */
-/*
+/*
** A constraint has failed while inserting a row into an rtree table.
** Assuming no OOM error occurs, this function sets the error message
-** (at pRtree->base.zErrMsg) to an appropriate value and returns
-** SQLITE_CONSTRAINT.
-**
-** Parameter iCol is the index of the leftmost column involved in the
-** constraint failure. If it is 0, then the constraint that failed is
-** the unique constraint on the id column. Otherwise, it is the rtree
-** (c1<=c2) constraint on columns iCol and iCol+1 that has failed.
-**
-** If an OOM occurs, SQLITE_NOMEM is returned instead of SQLITE_CONSTRAINT.
-*/
-static int rtreeConstraintError(Rtree *pRtree, int iCol){
- sqlite3_stmt *pStmt = 0;
+** (at pRtree->base.zErrMsg) to an appropriate value and returns
+** SQLITE_CONSTRAINT.
+**
+** Parameter iCol is the index of the leftmost column involved in the
+** constraint failure. If it is 0, then the constraint that failed is
+** the unique constraint on the id column. Otherwise, it is the rtree
+** (c1<=c2) constraint on columns iCol and iCol+1 that has failed.
+**
+** If an OOM occurs, SQLITE_NOMEM is returned instead of SQLITE_CONSTRAINT.
+*/
+static int rtreeConstraintError(Rtree *pRtree, int iCol){
+ sqlite3_stmt *pStmt = 0;
char *zSql;
- int rc;
-
- assert( iCol==0 || iCol%2 );
- zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", pRtree->zDb, pRtree->zName);
- if( zSql ){
- rc = sqlite3_prepare_v2(pRtree->db, zSql, -1, &pStmt, 0);
- }else{
- rc = SQLITE_NOMEM;
- }
- sqlite3_free(zSql);
-
- if( rc==SQLITE_OK ){
- if( iCol==0 ){
- const char *zCol = sqlite3_column_name(pStmt, 0);
- pRtree->base.zErrMsg = sqlite3_mprintf(
- "UNIQUE constraint failed: %s.%s", pRtree->zName, zCol
- );
- }else{
- const char *zCol1 = sqlite3_column_name(pStmt, iCol);
- const char *zCol2 = sqlite3_column_name(pStmt, iCol+1);
- pRtree->base.zErrMsg = sqlite3_mprintf(
- "rtree constraint failed: %s.(%s<=%s)", pRtree->zName, zCol1, zCol2
- );
- }
- }
-
- sqlite3_finalize(pStmt);
- return (rc==SQLITE_OK ? SQLITE_CONSTRAINT : rc);
-}
-
-
-
+ int rc;
+
+ assert( iCol==0 || iCol%2 );
+ zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", pRtree->zDb, pRtree->zName);
+ if( zSql ){
+ rc = sqlite3_prepare_v2(pRtree->db, zSql, -1, &pStmt, 0);
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ sqlite3_free(zSql);
+
+ if( rc==SQLITE_OK ){
+ if( iCol==0 ){
+ const char *zCol = sqlite3_column_name(pStmt, 0);
+ pRtree->base.zErrMsg = sqlite3_mprintf(
+ "UNIQUE constraint failed: %s.%s", pRtree->zName, zCol
+ );
+ }else{
+ const char *zCol1 = sqlite3_column_name(pStmt, iCol);
+ const char *zCol2 = sqlite3_column_name(pStmt, iCol+1);
+ pRtree->base.zErrMsg = sqlite3_mprintf(
+ "rtree constraint failed: %s.(%s<=%s)", pRtree->zName, zCol1, zCol2
+ );
+ }
+ }
+
+ sqlite3_finalize(pStmt);
+ return (rc==SQLITE_OK ? SQLITE_CONSTRAINT : rc);
+}
+
+
+
/*
** The xUpdate method for rtree module virtual tables.
*/
@@ -197231,7 +197231,7 @@ static int rtreeUpdate(
cell.aCoord[ii].f = rtreeValueDown(aData[ii+3]);
cell.aCoord[ii+1].f = rtreeValueUp(aData[ii+4]);
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
- rc = rtreeConstraintError(pRtree, ii+1);
+ rc = rtreeConstraintError(pRtree, ii+1);
goto constraint;
}
}
@@ -197242,7 +197242,7 @@ static int rtreeUpdate(
cell.aCoord[ii].i = sqlite3_value_int(aData[ii+3]);
cell.aCoord[ii+1].i = sqlite3_value_int(aData[ii+4]);
if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
- rc = rtreeConstraintError(pRtree, ii+1);
+ rc = rtreeConstraintError(pRtree, ii+1);
goto constraint;
}
}
@@ -197263,7 +197263,7 @@ static int rtreeUpdate(
if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){
rc = rtreeDeleteRowid(pRtree, cell.iRowid);
}else{
- rc = rtreeConstraintError(pRtree, 0);
+ rc = rtreeConstraintError(pRtree, 0);
goto constraint;
}
}
@@ -197324,27 +197324,27 @@ constraint:
}
/*
-** Called when a transaction starts.
-*/
-static int rtreeBeginTransaction(sqlite3_vtab *pVtab){
- Rtree *pRtree = (Rtree *)pVtab;
- assert( pRtree->inWrTrans==0 );
- pRtree->inWrTrans++;
- return SQLITE_OK;
-}
-
-/*
-** Called when a transaction completes (either by COMMIT or ROLLBACK).
-** The sqlite3_blob object should be released at this point.
-*/
-static int rtreeEndTransaction(sqlite3_vtab *pVtab){
- Rtree *pRtree = (Rtree *)pVtab;
- pRtree->inWrTrans = 0;
- nodeBlobReset(pRtree);
- return SQLITE_OK;
-}
-
-/*
+** Called when a transaction starts.
+*/
+static int rtreeBeginTransaction(sqlite3_vtab *pVtab){
+ Rtree *pRtree = (Rtree *)pVtab;
+ assert( pRtree->inWrTrans==0 );
+ pRtree->inWrTrans++;
+ return SQLITE_OK;
+}
+
+/*
+** Called when a transaction completes (either by COMMIT or ROLLBACK).
+** The sqlite3_blob object should be released at this point.
+*/
+static int rtreeEndTransaction(sqlite3_vtab *pVtab){
+ Rtree *pRtree = (Rtree *)pVtab;
+ pRtree->inWrTrans = 0;
+ nodeBlobReset(pRtree);
+ return SQLITE_OK;
+}
+
+/*
** The xRename method for rtree module virtual tables.
*/
static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
@@ -197359,7 +197359,7 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
, pRtree->zDb, pRtree->zName, zNewName
);
if( zSql ){
- nodeBlobReset(pRtree);
+ nodeBlobReset(pRtree);
rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
@@ -197367,30 +197367,30 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
}
/*
-** The xSavepoint method.
-**
-** This module does not need to do anything to support savepoints. However,
+** The xSavepoint method.
+**
+** This module does not need to do anything to support savepoints. However,
** it uses this hook to close any open blob handle. This is done because a
** DROP TABLE command - which fortunately always opens a savepoint - cannot
-** succeed if there are any open blob handles. i.e. if the blob handle were
-** not closed here, the following would fail:
-**
-** BEGIN;
-** INSERT INTO rtree...
-** DROP TABLE <tablename>; -- Would fail with SQLITE_LOCKED
-** COMMIT;
-*/
-static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
- Rtree *pRtree = (Rtree *)pVtab;
+** succeed if there are any open blob handles. i.e. if the blob handle were
+** not closed here, the following would fail:
+**
+** BEGIN;
+** INSERT INTO rtree...
+** DROP TABLE <tablename>; -- Would fail with SQLITE_LOCKED
+** COMMIT;
+*/
+static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
+ Rtree *pRtree = (Rtree *)pVtab;
u8 iwt = pRtree->inWrTrans;
- UNUSED_PARAMETER(iSavepoint);
- pRtree->inWrTrans = 0;
- nodeBlobReset(pRtree);
- pRtree->inWrTrans = iwt;
- return SQLITE_OK;
-}
-
-/*
+ UNUSED_PARAMETER(iSavepoint);
+ pRtree->inWrTrans = 0;
+ nodeBlobReset(pRtree);
+ pRtree->inWrTrans = iwt;
+ return SQLITE_OK;
+}
+
+/*
** This function populates the pRtree->nRowEst variable with an estimate
** of the number of rows in the virtual table. If possible, this is based
** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
@@ -197402,13 +197402,13 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
int rc;
i64 nRow = RTREE_MIN_ROWEST;
- rc = sqlite3_table_column_metadata(
- db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0
- );
- if( rc!=SQLITE_OK ){
- pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
- return rc==SQLITE_ERROR ? SQLITE_OK : rc;
- }
+ rc = sqlite3_table_column_metadata(
+ db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0
+ );
+ if( rc!=SQLITE_OK ){
+ pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
+ return rc==SQLITE_ERROR ? SQLITE_OK : rc;
+ }
zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
if( zSql==0 ){
rc = SQLITE_NOMEM;
@@ -197455,15 +197455,15 @@ static sqlite3_module rtreeModule = {
rtreeColumn, /* xColumn - read data */
rtreeRowid, /* xRowid - read data */
rtreeUpdate, /* xUpdate - write data */
- rtreeBeginTransaction, /* xBegin - begin transaction */
- rtreeEndTransaction, /* xSync - sync transaction */
- rtreeEndTransaction, /* xCommit - commit transaction */
- rtreeEndTransaction, /* xRollback - rollback transaction */
+ rtreeBeginTransaction, /* xBegin - begin transaction */
+ rtreeEndTransaction, /* xSync - sync transaction */
+ rtreeEndTransaction, /* xCommit - commit transaction */
+ rtreeEndTransaction, /* xRollback - rollback transaction */
0, /* xFindFunction - function overloading */
rtreeRename, /* xRename - rename the table */
- rtreeSavepoint, /* xSavepoint */
+ rtreeSavepoint, /* xSavepoint */
0, /* xRelease */
- 0, /* xRollbackTo */
+ 0, /* xRollbackTo */
rtreeShadowName /* xShadowName */
};
@@ -197476,9 +197476,9 @@ static int rtreeSqlInit(
){
int rc = SQLITE_OK;
- #define N_STATEMENT 8
+ #define N_STATEMENT 8
static const char *azSql[N_STATEMENT] = {
- /* Write the xxx_node table */
+ /* Write the xxx_node table */
"INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(?1, ?2)",
"DELETE FROM '%q'.'%q_node' WHERE nodeno = ?1",
@@ -197528,14 +197528,14 @@ static int rtreeSqlInit(
}
}
- appStmt[0] = &pRtree->pWriteNode;
- appStmt[1] = &pRtree->pDeleteNode;
- appStmt[2] = &pRtree->pReadRowid;
- appStmt[3] = &pRtree->pWriteRowid;
- appStmt[4] = &pRtree->pDeleteRowid;
- appStmt[5] = &pRtree->pReadParent;
- appStmt[6] = &pRtree->pWriteParent;
- appStmt[7] = &pRtree->pDeleteParent;
+ appStmt[0] = &pRtree->pWriteNode;
+ appStmt[1] = &pRtree->pDeleteNode;
+ appStmt[2] = &pRtree->pReadRowid;
+ appStmt[3] = &pRtree->pWriteRowid;
+ appStmt[4] = &pRtree->pDeleteRowid;
+ appStmt[5] = &pRtree->pReadParent;
+ appStmt[6] = &pRtree->pWriteParent;
+ appStmt[7] = &pRtree->pDeleteParent;
rc = rtreeQueryStat1(db, pRtree);
for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
@@ -197658,11 +197658,11 @@ static int getNodeSize(
rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize);
if( rc!=SQLITE_OK ){
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
- }else if( pRtree->iNodeSize<(512-64) ){
- rc = SQLITE_CORRUPT_VTAB;
+ }else if( pRtree->iNodeSize<(512-64) ){
+ rc = SQLITE_CORRUPT_VTAB;
RTREE_IS_CORRUPT(pRtree);
- *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
- pRtree->zName);
+ *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
+ pRtree->zName);
}
}
@@ -197733,7 +197733,7 @@ static int rtreeInit(
pRtree->base.pModule = &rtreeModule;
pRtree->zDb = (char *)&pRtree[1];
pRtree->zName = &pRtree->zDb[nDb+1];
- pRtree->eCoordType = (u8)eCoordType;
+ pRtree->eCoordType = (u8)eCoordType;
memcpy(pRtree->zDb, argv[1], nDb);
memcpy(pRtree->zName, argv[2], nName);
@@ -197835,9 +197835,9 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
UNUSED_PARAMETER(nArg);
memset(&node, 0, sizeof(RtreeNode));
memset(&tree, 0, sizeof(Rtree));
- tree.nDim = (u8)sqlite3_value_int(apArg[0]);
+ tree.nDim = (u8)sqlite3_value_int(apArg[0]);
if( tree.nDim<1 || tree.nDim>5 ) return;
- tree.nDim2 = tree.nDim*2;
+ tree.nDim2 = tree.nDim*2;
tree.nBytesPerCell = 8 + 8 * tree.nDim;
node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
if( node.zData==0 ) return;
@@ -197853,7 +197853,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
nodeGetCell(&tree, &node, ii, &cell);
if( ii>0 ) sqlite3_str_append(pOut, " ", 1);
sqlite3_str_appendf(pOut, "{%lld", cell.iRowid);
- for(jj=0; jj<tree.nDim2; jj++){
+ for(jj=0; jj<tree.nDim2; jj++){
#ifndef SQLITE_RTREE_INT_ONLY
sqlite3_str_appendf(pOut, " %g", (double)cell.aCoord[jj].f);
#else
@@ -197894,361 +197894,361 @@ static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
}
/*
-** Context object passed between the various routines that make up the
-** implementation of integrity-check function rtreecheck().
-*/
-typedef struct RtreeCheck RtreeCheck;
-struct RtreeCheck {
- sqlite3 *db; /* Database handle */
- const char *zDb; /* Database containing rtree table */
- const char *zTab; /* Name of rtree table */
- int bInt; /* True for rtree_i32 table */
- int nDim; /* Number of dimensions for this rtree tbl */
- sqlite3_stmt *pGetNode; /* Statement used to retrieve nodes */
- sqlite3_stmt *aCheckMapping[2]; /* Statements to query %_parent/%_rowid */
- int nLeaf; /* Number of leaf cells in table */
- int nNonLeaf; /* Number of non-leaf cells in table */
- int rc; /* Return code */
- char *zReport; /* Message to report */
- int nErr; /* Number of lines in zReport */
-};
-
-#define RTREE_CHECK_MAX_ERROR 100
-
-/*
-** Reset SQL statement pStmt. If the sqlite3_reset() call returns an error,
-** and RtreeCheck.rc==SQLITE_OK, set RtreeCheck.rc to the error code.
-*/
-static void rtreeCheckReset(RtreeCheck *pCheck, sqlite3_stmt *pStmt){
- int rc = sqlite3_reset(pStmt);
- if( pCheck->rc==SQLITE_OK ) pCheck->rc = rc;
-}
-
-/*
-** The second and subsequent arguments to this function are a format string
-** and printf style arguments. This function formats the string and attempts
-** to compile it as an SQL statement.
-**
-** If successful, a pointer to the new SQL statement is returned. Otherwise,
-** NULL is returned and an error code left in RtreeCheck.rc.
-*/
-static sqlite3_stmt *rtreeCheckPrepare(
- RtreeCheck *pCheck, /* RtreeCheck object */
- const char *zFmt, ... /* Format string and trailing args */
-){
- va_list ap;
- char *z;
- sqlite3_stmt *pRet = 0;
-
- va_start(ap, zFmt);
- z = sqlite3_vmprintf(zFmt, ap);
-
- if( pCheck->rc==SQLITE_OK ){
- if( z==0 ){
- pCheck->rc = SQLITE_NOMEM;
- }else{
- pCheck->rc = sqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0);
- }
- }
-
- sqlite3_free(z);
- va_end(ap);
- return pRet;
-}
-
-/*
-** The second and subsequent arguments to this function are a printf()
-** style format string and arguments. This function formats the string and
-** appends it to the report being accumuated in pCheck.
-*/
-static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){
- va_list ap;
- va_start(ap, zFmt);
- if( pCheck->rc==SQLITE_OK && pCheck->nErr<RTREE_CHECK_MAX_ERROR ){
- char *z = sqlite3_vmprintf(zFmt, ap);
- if( z==0 ){
- pCheck->rc = SQLITE_NOMEM;
- }else{
+** Context object passed between the various routines that make up the
+** implementation of integrity-check function rtreecheck().
+*/
+typedef struct RtreeCheck RtreeCheck;
+struct RtreeCheck {
+ sqlite3 *db; /* Database handle */
+ const char *zDb; /* Database containing rtree table */
+ const char *zTab; /* Name of rtree table */
+ int bInt; /* True for rtree_i32 table */
+ int nDim; /* Number of dimensions for this rtree tbl */
+ sqlite3_stmt *pGetNode; /* Statement used to retrieve nodes */
+ sqlite3_stmt *aCheckMapping[2]; /* Statements to query %_parent/%_rowid */
+ int nLeaf; /* Number of leaf cells in table */
+ int nNonLeaf; /* Number of non-leaf cells in table */
+ int rc; /* Return code */
+ char *zReport; /* Message to report */
+ int nErr; /* Number of lines in zReport */
+};
+
+#define RTREE_CHECK_MAX_ERROR 100
+
+/*
+** Reset SQL statement pStmt. If the sqlite3_reset() call returns an error,
+** and RtreeCheck.rc==SQLITE_OK, set RtreeCheck.rc to the error code.
+*/
+static void rtreeCheckReset(RtreeCheck *pCheck, sqlite3_stmt *pStmt){
+ int rc = sqlite3_reset(pStmt);
+ if( pCheck->rc==SQLITE_OK ) pCheck->rc = rc;
+}
+
+/*
+** The second and subsequent arguments to this function are a format string
+** and printf style arguments. This function formats the string and attempts
+** to compile it as an SQL statement.
+**
+** If successful, a pointer to the new SQL statement is returned. Otherwise,
+** NULL is returned and an error code left in RtreeCheck.rc.
+*/
+static sqlite3_stmt *rtreeCheckPrepare(
+ RtreeCheck *pCheck, /* RtreeCheck object */
+ const char *zFmt, ... /* Format string and trailing args */
+){
+ va_list ap;
+ char *z;
+ sqlite3_stmt *pRet = 0;
+
+ va_start(ap, zFmt);
+ z = sqlite3_vmprintf(zFmt, ap);
+
+ if( pCheck->rc==SQLITE_OK ){
+ if( z==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }else{
+ pCheck->rc = sqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0);
+ }
+ }
+
+ sqlite3_free(z);
+ va_end(ap);
+ return pRet;
+}
+
+/*
+** The second and subsequent arguments to this function are a printf()
+** style format string and arguments. This function formats the string and
+** appends it to the report being accumuated in pCheck.
+*/
+static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){
+ va_list ap;
+ va_start(ap, zFmt);
+ if( pCheck->rc==SQLITE_OK && pCheck->nErr<RTREE_CHECK_MAX_ERROR ){
+ char *z = sqlite3_vmprintf(zFmt, ap);
+ if( z==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }else{
pCheck->zReport = sqlite3_mprintf("%z%s%z",
- pCheck->zReport, (pCheck->zReport ? "\n" : ""), z
- );
- if( pCheck->zReport==0 ){
- pCheck->rc = SQLITE_NOMEM;
- }
- }
- pCheck->nErr++;
- }
- va_end(ap);
-}
-
-/*
-** This function is a no-op if there is already an error code stored
-** in the RtreeCheck object indicated by the first argument. NULL is
-** returned in this case.
-**
-** Otherwise, the contents of rtree table node iNode are loaded from
-** the database and copied into a buffer obtained from sqlite3_malloc().
-** If no error occurs, a pointer to the buffer is returned and (*pnNode)
-** is set to the size of the buffer in bytes.
-**
-** Or, if an error does occur, NULL is returned and an error code left
-** in the RtreeCheck object. The final value of *pnNode is undefined in
-** this case.
-*/
-static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
- u8 *pRet = 0; /* Return value */
-
+ pCheck->zReport, (pCheck->zReport ? "\n" : ""), z
+ );
+ if( pCheck->zReport==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }
+ }
+ pCheck->nErr++;
+ }
+ va_end(ap);
+}
+
+/*
+** This function is a no-op if there is already an error code stored
+** in the RtreeCheck object indicated by the first argument. NULL is
+** returned in this case.
+**
+** Otherwise, the contents of rtree table node iNode are loaded from
+** the database and copied into a buffer obtained from sqlite3_malloc().
+** If no error occurs, a pointer to the buffer is returned and (*pnNode)
+** is set to the size of the buffer in bytes.
+**
+** Or, if an error does occur, NULL is returned and an error code left
+** in the RtreeCheck object. The final value of *pnNode is undefined in
+** this case.
+*/
+static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
+ u8 *pRet = 0; /* Return value */
+
if( pCheck->rc==SQLITE_OK && pCheck->pGetNode==0 ){
- pCheck->pGetNode = rtreeCheckPrepare(pCheck,
+ pCheck->pGetNode = rtreeCheckPrepare(pCheck,
"SELECT data FROM %Q.'%q_node' WHERE nodeno=?",
- pCheck->zDb, pCheck->zTab
- );
- }
-
- if( pCheck->rc==SQLITE_OK ){
- sqlite3_bind_int64(pCheck->pGetNode, 1, iNode);
- if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){
- int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0);
- const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0);
+ pCheck->zDb, pCheck->zTab
+ );
+ }
+
+ if( pCheck->rc==SQLITE_OK ){
+ sqlite3_bind_int64(pCheck->pGetNode, 1, iNode);
+ if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){
+ int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0);
+ const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0);
pRet = sqlite3_malloc64(nNode);
- if( pRet==0 ){
- pCheck->rc = SQLITE_NOMEM;
- }else{
- memcpy(pRet, pNode, nNode);
- *pnNode = nNode;
- }
- }
- rtreeCheckReset(pCheck, pCheck->pGetNode);
- if( pCheck->rc==SQLITE_OK && pRet==0 ){
- rtreeCheckAppendMsg(pCheck, "Node %lld missing from database", iNode);
- }
- }
-
- return pRet;
-}
-
-/*
-** This function is used to check that the %_parent (if bLeaf==0) or %_rowid
-** (if bLeaf==1) table contains a specified entry. The schemas of the
-** two tables are:
-**
-** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
+ if( pRet==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }else{
+ memcpy(pRet, pNode, nNode);
+ *pnNode = nNode;
+ }
+ }
+ rtreeCheckReset(pCheck, pCheck->pGetNode);
+ if( pCheck->rc==SQLITE_OK && pRet==0 ){
+ rtreeCheckAppendMsg(pCheck, "Node %lld missing from database", iNode);
+ }
+ }
+
+ return pRet;
+}
+
+/*
+** This function is used to check that the %_parent (if bLeaf==0) or %_rowid
+** (if bLeaf==1) table contains a specified entry. The schemas of the
+** two tables are:
+**
+** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...)
-**
-** In both cases, this function checks that there exists an entry with
-** IPK value iKey and the second column set to iVal.
-**
-*/
-static void rtreeCheckMapping(
- RtreeCheck *pCheck, /* RtreeCheck object */
- int bLeaf, /* True for a leaf cell, false for interior */
- i64 iKey, /* Key for mapping */
- i64 iVal /* Expected value for mapping */
-){
- int rc;
- sqlite3_stmt *pStmt;
- const char *azSql[2] = {
+**
+** In both cases, this function checks that there exists an entry with
+** IPK value iKey and the second column set to iVal.
+**
+*/
+static void rtreeCheckMapping(
+ RtreeCheck *pCheck, /* RtreeCheck object */
+ int bLeaf, /* True for a leaf cell, false for interior */
+ i64 iKey, /* Key for mapping */
+ i64 iVal /* Expected value for mapping */
+){
+ int rc;
+ sqlite3_stmt *pStmt;
+ const char *azSql[2] = {
"SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?1",
"SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?1"
- };
-
- assert( bLeaf==0 || bLeaf==1 );
- if( pCheck->aCheckMapping[bLeaf]==0 ){
- pCheck->aCheckMapping[bLeaf] = rtreeCheckPrepare(pCheck,
- azSql[bLeaf], pCheck->zDb, pCheck->zTab
- );
- }
- if( pCheck->rc!=SQLITE_OK ) return;
-
- pStmt = pCheck->aCheckMapping[bLeaf];
- sqlite3_bind_int64(pStmt, 1, iKey);
- rc = sqlite3_step(pStmt);
- if( rc==SQLITE_DONE ){
- rtreeCheckAppendMsg(pCheck, "Mapping (%lld -> %lld) missing from %s table",
- iKey, iVal, (bLeaf ? "%_rowid" : "%_parent")
- );
- }else if( rc==SQLITE_ROW ){
- i64 ii = sqlite3_column_int64(pStmt, 0);
- if( ii!=iVal ){
+ };
+
+ assert( bLeaf==0 || bLeaf==1 );
+ if( pCheck->aCheckMapping[bLeaf]==0 ){
+ pCheck->aCheckMapping[bLeaf] = rtreeCheckPrepare(pCheck,
+ azSql[bLeaf], pCheck->zDb, pCheck->zTab
+ );
+ }
+ if( pCheck->rc!=SQLITE_OK ) return;
+
+ pStmt = pCheck->aCheckMapping[bLeaf];
+ sqlite3_bind_int64(pStmt, 1, iKey);
+ rc = sqlite3_step(pStmt);
+ if( rc==SQLITE_DONE ){
+ rtreeCheckAppendMsg(pCheck, "Mapping (%lld -> %lld) missing from %s table",
+ iKey, iVal, (bLeaf ? "%_rowid" : "%_parent")
+ );
+ }else if( rc==SQLITE_ROW ){
+ i64 ii = sqlite3_column_int64(pStmt, 0);
+ if( ii!=iVal ){
rtreeCheckAppendMsg(pCheck,
- "Found (%lld -> %lld) in %s table, expected (%lld -> %lld)",
- iKey, ii, (bLeaf ? "%_rowid" : "%_parent"), iKey, iVal
- );
- }
- }
- rtreeCheckReset(pCheck, pStmt);
-}
-
-/*
-** Argument pCell points to an array of coordinates stored on an rtree page.
-** This function checks that the coordinates are internally consistent (no
-** x1>x2 conditions) and adds an error message to the RtreeCheck object
-** if they are not.
-**
-** Additionally, if pParent is not NULL, then it is assumed to point to
+ "Found (%lld -> %lld) in %s table, expected (%lld -> %lld)",
+ iKey, ii, (bLeaf ? "%_rowid" : "%_parent"), iKey, iVal
+ );
+ }
+ }
+ rtreeCheckReset(pCheck, pStmt);
+}
+
+/*
+** Argument pCell points to an array of coordinates stored on an rtree page.
+** This function checks that the coordinates are internally consistent (no
+** x1>x2 conditions) and adds an error message to the RtreeCheck object
+** if they are not.
+**
+** Additionally, if pParent is not NULL, then it is assumed to point to
** the array of coordinates on the parent page that bound the page
-** containing pCell. In this case it is also verified that the two
-** sets of coordinates are mutually consistent and an error message added
-** to the RtreeCheck object if they are not.
-*/
-static void rtreeCheckCellCoord(
+** containing pCell. In this case it is also verified that the two
+** sets of coordinates are mutually consistent and an error message added
+** to the RtreeCheck object if they are not.
+*/
+static void rtreeCheckCellCoord(
RtreeCheck *pCheck,
- i64 iNode, /* Node id to use in error messages */
- int iCell, /* Cell number to use in error messages */
- u8 *pCell, /* Pointer to cell coordinates */
- u8 *pParent /* Pointer to parent coordinates */
-){
- RtreeCoord c1, c2;
- RtreeCoord p1, p2;
- int i;
-
- for(i=0; i<pCheck->nDim; i++){
- readCoord(&pCell[4*2*i], &c1);
- readCoord(&pCell[4*(2*i + 1)], &c2);
-
- /* printf("%e, %e\n", c1.u.f, c2.u.f); */
- if( pCheck->bInt ? c1.i>c2.i : c1.f>c2.f ){
+ i64 iNode, /* Node id to use in error messages */
+ int iCell, /* Cell number to use in error messages */
+ u8 *pCell, /* Pointer to cell coordinates */
+ u8 *pParent /* Pointer to parent coordinates */
+){
+ RtreeCoord c1, c2;
+ RtreeCoord p1, p2;
+ int i;
+
+ for(i=0; i<pCheck->nDim; i++){
+ readCoord(&pCell[4*2*i], &c1);
+ readCoord(&pCell[4*(2*i + 1)], &c2);
+
+ /* printf("%e, %e\n", c1.u.f, c2.u.f); */
+ if( pCheck->bInt ? c1.i>c2.i : c1.f>c2.f ){
rtreeCheckAppendMsg(pCheck,
- "Dimension %d of cell %d on node %lld is corrupt", i, iCell, iNode
- );
- }
-
- if( pParent ){
- readCoord(&pParent[4*2*i], &p1);
- readCoord(&pParent[4*(2*i + 1)], &p2);
-
+ "Dimension %d of cell %d on node %lld is corrupt", i, iCell, iNode
+ );
+ }
+
+ if( pParent ){
+ readCoord(&pParent[4*2*i], &p1);
+ readCoord(&pParent[4*(2*i + 1)], &p2);
+
if( (pCheck->bInt ? c1.i<p1.i : c1.f<p1.f)
- || (pCheck->bInt ? c2.i>p2.i : c2.f>p2.f)
- ){
+ || (pCheck->bInt ? c2.i>p2.i : c2.f>p2.f)
+ ){
rtreeCheckAppendMsg(pCheck,
- "Dimension %d of cell %d on node %lld is corrupt relative to parent"
- , i, iCell, iNode
- );
- }
- }
- }
-}
-
-/*
-** Run rtreecheck() checks on node iNode, which is at depth iDepth within
-** the r-tree structure. Argument aParent points to the array of coordinates
-** that bound node iNode on the parent node.
-**
-** If any problems are discovered, an error message is appended to the
-** report accumulated in the RtreeCheck object.
-*/
-static void rtreeCheckNode(
- RtreeCheck *pCheck,
- int iDepth, /* Depth of iNode (0==leaf) */
- u8 *aParent, /* Buffer containing parent coords */
- i64 iNode /* Node to check */
-){
- u8 *aNode = 0;
- int nNode = 0;
-
- assert( iNode==1 || aParent!=0 );
- assert( pCheck->nDim>0 );
-
- aNode = rtreeCheckGetNode(pCheck, iNode, &nNode);
- if( aNode ){
- if( nNode<4 ){
+ "Dimension %d of cell %d on node %lld is corrupt relative to parent"
+ , i, iCell, iNode
+ );
+ }
+ }
+ }
+}
+
+/*
+** Run rtreecheck() checks on node iNode, which is at depth iDepth within
+** the r-tree structure. Argument aParent points to the array of coordinates
+** that bound node iNode on the parent node.
+**
+** If any problems are discovered, an error message is appended to the
+** report accumulated in the RtreeCheck object.
+*/
+static void rtreeCheckNode(
+ RtreeCheck *pCheck,
+ int iDepth, /* Depth of iNode (0==leaf) */
+ u8 *aParent, /* Buffer containing parent coords */
+ i64 iNode /* Node to check */
+){
+ u8 *aNode = 0;
+ int nNode = 0;
+
+ assert( iNode==1 || aParent!=0 );
+ assert( pCheck->nDim>0 );
+
+ aNode = rtreeCheckGetNode(pCheck, iNode, &nNode);
+ if( aNode ){
+ if( nNode<4 ){
rtreeCheckAppendMsg(pCheck,
- "Node %lld is too small (%d bytes)", iNode, nNode
- );
- }else{
- int nCell; /* Number of cells on page */
- int i; /* Used to iterate through cells */
- if( aParent==0 ){
- iDepth = readInt16(aNode);
- if( iDepth>RTREE_MAX_DEPTH ){
- rtreeCheckAppendMsg(pCheck, "Rtree depth out of range (%d)", iDepth);
- sqlite3_free(aNode);
- return;
- }
- }
- nCell = readInt16(&aNode[2]);
- if( (4 + nCell*(8 + pCheck->nDim*2*4))>nNode ){
+ "Node %lld is too small (%d bytes)", iNode, nNode
+ );
+ }else{
+ int nCell; /* Number of cells on page */
+ int i; /* Used to iterate through cells */
+ if( aParent==0 ){
+ iDepth = readInt16(aNode);
+ if( iDepth>RTREE_MAX_DEPTH ){
+ rtreeCheckAppendMsg(pCheck, "Rtree depth out of range (%d)", iDepth);
+ sqlite3_free(aNode);
+ return;
+ }
+ }
+ nCell = readInt16(&aNode[2]);
+ if( (4 + nCell*(8 + pCheck->nDim*2*4))>nNode ){
rtreeCheckAppendMsg(pCheck,
"Node %lld is too small for cell count of %d (%d bytes)",
- iNode, nCell, nNode
- );
- }else{
- for(i=0; i<nCell; i++){
- u8 *pCell = &aNode[4 + i*(8 + pCheck->nDim*2*4)];
- i64 iVal = readInt64(pCell);
- rtreeCheckCellCoord(pCheck, iNode, i, &pCell[8], aParent);
-
- if( iDepth>0 ){
- rtreeCheckMapping(pCheck, 0, iVal, iNode);
- rtreeCheckNode(pCheck, iDepth-1, &pCell[8], iVal);
- pCheck->nNonLeaf++;
- }else{
- rtreeCheckMapping(pCheck, 1, iVal, iNode);
- pCheck->nLeaf++;
- }
- }
- }
- }
- sqlite3_free(aNode);
- }
-}
-
-/*
-** The second argument to this function must be either "_rowid" or
-** "_parent". This function checks that the number of entries in the
-** %_rowid or %_parent table is exactly nExpect. If not, it adds
-** an error message to the report in the RtreeCheck object indicated
-** by the first argument.
-*/
-static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){
- if( pCheck->rc==SQLITE_OK ){
- sqlite3_stmt *pCount;
- pCount = rtreeCheckPrepare(pCheck, "SELECT count(*) FROM %Q.'%q%s'",
- pCheck->zDb, pCheck->zTab, zTbl
- );
- if( pCount ){
- if( sqlite3_step(pCount)==SQLITE_ROW ){
- i64 nActual = sqlite3_column_int64(pCount, 0);
- if( nActual!=nExpect ){
- rtreeCheckAppendMsg(pCheck, "Wrong number of entries in %%%s table"
- " - expected %lld, actual %lld" , zTbl, nExpect, nActual
- );
- }
- }
- pCheck->rc = sqlite3_finalize(pCount);
- }
- }
-}
-
-/*
-** This function does the bulk of the work for the rtree integrity-check.
-** It is called by rtreecheck(), which is the SQL function implementation.
-*/
-static int rtreeCheckTable(
- sqlite3 *db, /* Database handle to access db through */
- const char *zDb, /* Name of db ("main", "temp" etc.) */
- const char *zTab, /* Name of rtree table to check */
- char **pzReport /* OUT: sqlite3_malloc'd report text */
-){
- RtreeCheck check; /* Common context for various routines */
- sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */
- int bEnd = 0; /* True if transaction should be closed */
+ iNode, nCell, nNode
+ );
+ }else{
+ for(i=0; i<nCell; i++){
+ u8 *pCell = &aNode[4 + i*(8 + pCheck->nDim*2*4)];
+ i64 iVal = readInt64(pCell);
+ rtreeCheckCellCoord(pCheck, iNode, i, &pCell[8], aParent);
+
+ if( iDepth>0 ){
+ rtreeCheckMapping(pCheck, 0, iVal, iNode);
+ rtreeCheckNode(pCheck, iDepth-1, &pCell[8], iVal);
+ pCheck->nNonLeaf++;
+ }else{
+ rtreeCheckMapping(pCheck, 1, iVal, iNode);
+ pCheck->nLeaf++;
+ }
+ }
+ }
+ }
+ sqlite3_free(aNode);
+ }
+}
+
+/*
+** The second argument to this function must be either "_rowid" or
+** "_parent". This function checks that the number of entries in the
+** %_rowid or %_parent table is exactly nExpect. If not, it adds
+** an error message to the report in the RtreeCheck object indicated
+** by the first argument.
+*/
+static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){
+ if( pCheck->rc==SQLITE_OK ){
+ sqlite3_stmt *pCount;
+ pCount = rtreeCheckPrepare(pCheck, "SELECT count(*) FROM %Q.'%q%s'",
+ pCheck->zDb, pCheck->zTab, zTbl
+ );
+ if( pCount ){
+ if( sqlite3_step(pCount)==SQLITE_ROW ){
+ i64 nActual = sqlite3_column_int64(pCount, 0);
+ if( nActual!=nExpect ){
+ rtreeCheckAppendMsg(pCheck, "Wrong number of entries in %%%s table"
+ " - expected %lld, actual %lld" , zTbl, nExpect, nActual
+ );
+ }
+ }
+ pCheck->rc = sqlite3_finalize(pCount);
+ }
+ }
+}
+
+/*
+** This function does the bulk of the work for the rtree integrity-check.
+** It is called by rtreecheck(), which is the SQL function implementation.
+*/
+static int rtreeCheckTable(
+ sqlite3 *db, /* Database handle to access db through */
+ const char *zDb, /* Name of db ("main", "temp" etc.) */
+ const char *zTab, /* Name of rtree table to check */
+ char **pzReport /* OUT: sqlite3_malloc'd report text */
+){
+ RtreeCheck check; /* Common context for various routines */
+ sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */
+ int bEnd = 0; /* True if transaction should be closed */
int nAux = 0; /* Number of extra columns. */
-
- /* Initialize the context object */
- memset(&check, 0, sizeof(check));
- check.db = db;
- check.zDb = zDb;
- check.zTab = zTab;
-
- /* If there is not already an open transaction, open one now. This is
- ** to ensure that the queries run as part of this integrity-check operate
- ** on a consistent snapshot. */
- if( sqlite3_get_autocommit(db) ){
- check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0);
- bEnd = 1;
- }
-
+
+ /* Initialize the context object */
+ memset(&check, 0, sizeof(check));
+ check.db = db;
+ check.zDb = zDb;
+ check.zTab = zTab;
+
+ /* If there is not already an open transaction, open one now. This is
+ ** to ensure that the queries run as part of this integrity-check operate
+ ** on a consistent snapshot. */
+ if( sqlite3_get_autocommit(db) ){
+ check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0);
+ bEnd = 1;
+ }
+
/* Find the number of auxiliary columns */
if( check.rc==SQLITE_OK ){
pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab);
@@ -198261,106 +198261,106 @@ static int rtreeCheckTable(
}
}
- /* Find number of dimensions in the rtree table. */
- pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab);
- if( pStmt ){
- int rc;
+ /* Find number of dimensions in the rtree table. */
+ pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab);
+ if( pStmt ){
+ int rc;
check.nDim = (sqlite3_column_count(pStmt) - 1 - nAux) / 2;
- if( check.nDim<1 ){
- rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree");
- }else if( SQLITE_ROW==sqlite3_step(pStmt) ){
- check.bInt = (sqlite3_column_type(pStmt, 1)==SQLITE_INTEGER);
- }
- rc = sqlite3_finalize(pStmt);
- if( rc!=SQLITE_CORRUPT ) check.rc = rc;
- }
-
- /* Do the actual integrity-check */
- if( check.nDim>=1 ){
- if( check.rc==SQLITE_OK ){
- rtreeCheckNode(&check, 0, 0, 1);
- }
- rtreeCheckCount(&check, "_rowid", check.nLeaf);
- rtreeCheckCount(&check, "_parent", check.nNonLeaf);
- }
-
- /* Finalize SQL statements used by the integrity-check */
- sqlite3_finalize(check.pGetNode);
- sqlite3_finalize(check.aCheckMapping[0]);
- sqlite3_finalize(check.aCheckMapping[1]);
-
- /* If one was opened, close the transaction */
- if( bEnd ){
- int rc = sqlite3_exec(db, "END", 0, 0, 0);
- if( check.rc==SQLITE_OK ) check.rc = rc;
- }
- *pzReport = check.zReport;
- return check.rc;
-}
-
-/*
-** Usage:
-**
-** rtreecheck(<rtree-table>);
-** rtreecheck(<database>, <rtree-table>);
-**
-** Invoking this SQL function runs an integrity-check on the named rtree
-** table. The integrity-check verifies the following:
-**
-** 1. For each cell in the r-tree structure (%_node table), that:
-**
-** a) for each dimension, (coord1 <= coord2).
-**
-** b) unless the cell is on the root node, that the cell is bounded
-** by the parent cell on the parent node.
-**
+ if( check.nDim<1 ){
+ rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree");
+ }else if( SQLITE_ROW==sqlite3_step(pStmt) ){
+ check.bInt = (sqlite3_column_type(pStmt, 1)==SQLITE_INTEGER);
+ }
+ rc = sqlite3_finalize(pStmt);
+ if( rc!=SQLITE_CORRUPT ) check.rc = rc;
+ }
+
+ /* Do the actual integrity-check */
+ if( check.nDim>=1 ){
+ if( check.rc==SQLITE_OK ){
+ rtreeCheckNode(&check, 0, 0, 1);
+ }
+ rtreeCheckCount(&check, "_rowid", check.nLeaf);
+ rtreeCheckCount(&check, "_parent", check.nNonLeaf);
+ }
+
+ /* Finalize SQL statements used by the integrity-check */
+ sqlite3_finalize(check.pGetNode);
+ sqlite3_finalize(check.aCheckMapping[0]);
+ sqlite3_finalize(check.aCheckMapping[1]);
+
+ /* If one was opened, close the transaction */
+ if( bEnd ){
+ int rc = sqlite3_exec(db, "END", 0, 0, 0);
+ if( check.rc==SQLITE_OK ) check.rc = rc;
+ }
+ *pzReport = check.zReport;
+ return check.rc;
+}
+
+/*
+** Usage:
+**
+** rtreecheck(<rtree-table>);
+** rtreecheck(<database>, <rtree-table>);
+**
+** Invoking this SQL function runs an integrity-check on the named rtree
+** table. The integrity-check verifies the following:
+**
+** 1. For each cell in the r-tree structure (%_node table), that:
+**
+** a) for each dimension, (coord1 <= coord2).
+**
+** b) unless the cell is on the root node, that the cell is bounded
+** by the parent cell on the parent node.
+**
** c) for leaf nodes, that there is an entry in the %_rowid
** table corresponding to the cell's rowid value that
-** points to the correct node.
-**
+** points to the correct node.
+**
** d) for cells on non-leaf nodes, that there is an entry in the
-** %_parent table mapping from the cell's child node to the
-** node that it resides on.
-**
-** 2. That there are the same number of entries in the %_rowid table
-** as there are leaf cells in the r-tree structure, and that there
-** is a leaf cell that corresponds to each entry in the %_rowid table.
-**
-** 3. That there are the same number of entries in the %_parent table
+** %_parent table mapping from the cell's child node to the
+** node that it resides on.
+**
+** 2. That there are the same number of entries in the %_rowid table
+** as there are leaf cells in the r-tree structure, and that there
+** is a leaf cell that corresponds to each entry in the %_rowid table.
+**
+** 3. That there are the same number of entries in the %_parent table
** as there are non-leaf cells in the r-tree structure, and that
** there is a non-leaf cell that corresponds to each entry in the
-** %_parent table.
-*/
-static void rtreecheck(
+** %_parent table.
+*/
+static void rtreecheck(
sqlite3_context *ctx,
int nArg,
- sqlite3_value **apArg
-){
- if( nArg!=1 && nArg!=2 ){
+ sqlite3_value **apArg
+){
+ if( nArg!=1 && nArg!=2 ){
sqlite3_result_error(ctx,
- "wrong number of arguments to function rtreecheck()", -1
- );
- }else{
- int rc;
- char *zReport = 0;
- const char *zDb = (const char*)sqlite3_value_text(apArg[0]);
- const char *zTab;
- if( nArg==1 ){
- zTab = zDb;
- zDb = "main";
- }else{
- zTab = (const char*)sqlite3_value_text(apArg[1]);
- }
- rc = rtreeCheckTable(sqlite3_context_db_handle(ctx), zDb, zTab, &zReport);
- if( rc==SQLITE_OK ){
- sqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT);
- }else{
- sqlite3_result_error_code(ctx, rc);
- }
- sqlite3_free(zReport);
- }
-}
-
+ "wrong number of arguments to function rtreecheck()", -1
+ );
+ }else{
+ int rc;
+ char *zReport = 0;
+ const char *zDb = (const char*)sqlite3_value_text(apArg[0]);
+ const char *zTab;
+ if( nArg==1 ){
+ zTab = zDb;
+ zDb = "main";
+ }else{
+ zTab = (const char*)sqlite3_value_text(apArg[1]);
+ }
+ rc = rtreeCheckTable(sqlite3_context_db_handle(ctx), zDb, zTab, &zReport);
+ if( rc==SQLITE_OK ){
+ sqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_result_error_code(ctx, rc);
+ }
+ sqlite3_free(zReport);
+ }
+}
+
/* Conditionally include the geopoly code */
#ifdef SQLITE_ENABLE_GEOPOLY
/************** Include geopoly.c in the middle of rtree.c *******************/
@@ -198384,7 +198384,7 @@ static void rtreecheck(
** access to all of the R-Tree internals.
*/
/* #include <stdlib.h> */
-
+
/* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */
#ifdef GEOPOLY_ENABLE_DEBUG
static int geo_debug = 0;
@@ -198394,7 +198394,7 @@ static void rtreecheck(
#endif
#ifndef JSON_NULL /* The following stuff repeats things found in json1 */
-/*
+/*
** Versions of isspace(), isalnum() and isdigit() to which it is safe
** to pass signed char values.
*/
@@ -200201,9 +200201,9 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){
rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
}
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "rtreecheck", -1, utf8, 0,rtreecheck, 0,0);
- }
- if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "rtreecheck", -1, utf8, 0,rtreecheck, 0,0);
+ }
+ if( rc==SQLITE_OK ){
#ifdef SQLITE_RTREE_INT_ONLY
void *c = (void *)RTREE_COORD_INT32;
#else
@@ -200276,7 +200276,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
sqlite3_result_error_nomem(ctx);
}else{
int i;
- pBlob->iSize = nBlob;
+ pBlob->iSize = nBlob;
pBlob->cb = pGeomCtx[0];
pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg];
pBlob->nParam = nArg;
@@ -200293,7 +200293,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
sqlite3_result_error_nomem(ctx);
rtreeMatchArgFree(pBlob);
}else{
- sqlite3_result_pointer(ctx, pBlob, "RtreeMatchArg", rtreeMatchArgFree);
+ sqlite3_result_pointer(ctx, pBlob, "RtreeMatchArg", rtreeMatchArgFree);
}
}
}
@@ -200301,7 +200301,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
/*
** Register a new geometry function for use with the r-tree MATCH operator.
*/
-SQLITE_API int sqlite3_rtree_geometry_callback(
+SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db, /* Register SQL function on this connection */
const char *zGeom, /* Name of the new SQL function */
int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */
@@ -200325,7 +200325,7 @@ SQLITE_API int sqlite3_rtree_geometry_callback(
** Register a new 2nd-generation geometry function for use with the
** r-tree MATCH operator.
*/
-SQLITE_API int sqlite3_rtree_query_callback(
+SQLITE_API int sqlite3_rtree_query_callback(
sqlite3 *db, /* Register SQL function on this connection */
const char *zQueryFunc, /* Name of new SQL function */
int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */
@@ -200353,7 +200353,7 @@ SQLITE_API int sqlite3_rtree_query_callback(
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int sqlite3_rtree_init(
+SQLITE_API int sqlite3_rtree_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -200397,9 +200397,9 @@ SQLITE_API int sqlite3_rtree_init(
** provide case-independent matching.
*/
-#if !defined(SQLITE_CORE) \
- || defined(SQLITE_ENABLE_ICU) \
- || defined(SQLITE_ENABLE_ICU_COLLATIONS)
+#if !defined(SQLITE_CORE) \
+ || defined(SQLITE_ENABLE_ICU) \
+ || defined(SQLITE_ENABLE_ICU_COLLATIONS)
/* Include ICU headers */
#include <unicode/utypes.h>
@@ -200417,26 +200417,26 @@ SQLITE_API int sqlite3_rtree_init(
#endif
/*
-** This function is called when an ICU function called from within
-** the implementation of an SQL scalar function returns an error.
-**
+** This function is called when an ICU function called from within
+** the implementation of an SQL scalar function returns an error.
+**
** The scalar function context passed as the first argument is
-** loaded with an error message based on the following two args.
-*/
-static void icuFunctionError(
- sqlite3_context *pCtx, /* SQLite scalar function context */
- const char *zName, /* Name of ICU function that failed */
- UErrorCode e /* Error code returned by ICU function */
-){
- char zBuf[128];
- sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
- zBuf[127] = '\0';
- sqlite3_result_error(pCtx, zBuf, -1);
-}
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
-
-/*
+** loaded with an error message based on the following two args.
+*/
+static void icuFunctionError(
+ sqlite3_context *pCtx, /* SQLite scalar function context */
+ const char *zName, /* Name of ICU function that failed */
+ UErrorCode e /* Error code returned by ICU function */
+){
+ char zBuf[128];
+ sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
+ zBuf[127] = '\0';
+ sqlite3_result_error(pCtx, zBuf, -1);
+}
+
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
+
+/*
** Maximum length (in bytes) of the pattern in a LIKE or GLOB
** operator.
*/
@@ -200452,38 +200452,38 @@ static void xFree(void *p){
}
/*
-** This lookup table is used to help decode the first byte of
-** a multi-byte UTF8 character. It is copied here from SQLite source
-** code file utf8.c.
-*/
-static const unsigned char icuUtf8Trans1[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
-};
-
-#define SQLITE_ICU_READ_UTF8(zIn, c) \
- c = *(zIn++); \
- if( c>=0xc0 ){ \
- c = icuUtf8Trans1[c-0xc0]; \
- while( (*zIn & 0xc0)==0x80 ){ \
- c = (c<<6) + (0x3f & *(zIn++)); \
- } \
- }
-
-#define SQLITE_ICU_SKIP_UTF8(zIn) \
- assert( *zIn ); \
- if( *(zIn++)>=0xc0 ){ \
- while( (*zIn & 0xc0)==0x80 ){zIn++;} \
- }
-
-
-/*
+** This lookup table is used to help decode the first byte of
+** a multi-byte UTF8 character. It is copied here from SQLite source
+** code file utf8.c.
+*/
+static const unsigned char icuUtf8Trans1[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
+};
+
+#define SQLITE_ICU_READ_UTF8(zIn, c) \
+ c = *(zIn++); \
+ if( c>=0xc0 ){ \
+ c = icuUtf8Trans1[c-0xc0]; \
+ while( (*zIn & 0xc0)==0x80 ){ \
+ c = (c<<6) + (0x3f & *(zIn++)); \
+ } \
+ }
+
+#define SQLITE_ICU_SKIP_UTF8(zIn) \
+ assert( *zIn ); \
+ if( *(zIn++)>=0xc0 ){ \
+ while( (*zIn & 0xc0)==0x80 ){zIn++;} \
+ }
+
+
+/*
** Compare two UTF-8 strings for equality where the first string is
** a "LIKE" expression. Return true (1) if they are the same and
** false (0) if they are different.
@@ -200493,17 +200493,17 @@ static int icuLikeCompare(
const uint8_t *zString, /* The UTF-8 string to compare against */
const UChar32 uEsc /* The escape character */
){
- static const uint32_t MATCH_ONE = (uint32_t)'_';
- static const uint32_t MATCH_ALL = (uint32_t)'%';
+ static const uint32_t MATCH_ONE = (uint32_t)'_';
+ static const uint32_t MATCH_ALL = (uint32_t)'%';
int prevEscape = 0; /* True if the previous character was uEsc */
- while( 1 ){
+ while( 1 ){
/* Read (and consume) the next character from the input pattern. */
- uint32_t uPattern;
- SQLITE_ICU_READ_UTF8(zPattern, uPattern);
- if( uPattern==0 ) break;
+ uint32_t uPattern;
+ SQLITE_ICU_READ_UTF8(zPattern, uPattern);
+ if( uPattern==0 ) break;
/* There are now 4 possibilities:
**
@@ -200520,28 +200520,28 @@ static int icuLikeCompare(
** MATCH_ALL. For each MATCH_ONE, skip one character in the
** test string.
*/
- while( (c=*zPattern) == MATCH_ALL || c == MATCH_ONE ){
+ while( (c=*zPattern) == MATCH_ALL || c == MATCH_ONE ){
if( c==MATCH_ONE ){
- if( *zString==0 ) return 0;
- SQLITE_ICU_SKIP_UTF8(zString);
+ if( *zString==0 ) return 0;
+ SQLITE_ICU_SKIP_UTF8(zString);
}
- zPattern++;
+ zPattern++;
}
- if( *zPattern==0 ) return 1;
+ if( *zPattern==0 ) return 1;
- while( *zString ){
- if( icuLikeCompare(zPattern, zString, uEsc) ){
+ while( *zString ){
+ if( icuLikeCompare(zPattern, zString, uEsc) ){
return 1;
}
- SQLITE_ICU_SKIP_UTF8(zString);
+ SQLITE_ICU_SKIP_UTF8(zString);
}
return 0;
}else if( uPattern==MATCH_ONE && !prevEscape && uPattern!=(uint32_t)uEsc ){
/* Case 2. */
- if( *zString==0 ) return 0;
- SQLITE_ICU_SKIP_UTF8(zString);
+ if( *zString==0 ) return 0;
+ SQLITE_ICU_SKIP_UTF8(zString);
}else if( uPattern==(uint32_t)uEsc && !prevEscape ){
/* Case 3. */
@@ -200549,10 +200549,10 @@ static int icuLikeCompare(
}else{
/* Case 4. */
- uint32_t uString;
- SQLITE_ICU_READ_UTF8(zString, uString);
- uString = (uint32_t)u_foldCase((UChar32)uString, U_FOLD_CASE_DEFAULT);
- uPattern = (uint32_t)u_foldCase((UChar32)uPattern, U_FOLD_CASE_DEFAULT);
+ uint32_t uString;
+ SQLITE_ICU_READ_UTF8(zString, uString);
+ uString = (uint32_t)u_foldCase((UChar32)uString, U_FOLD_CASE_DEFAULT);
+ uPattern = (uint32_t)u_foldCase((UChar32)uPattern, U_FOLD_CASE_DEFAULT);
if( uString!=uPattern ){
return 0;
}
@@ -200560,7 +200560,7 @@ static int icuLikeCompare(
}
}
- return *zString==0;
+ return *zString==0;
}
/*
@@ -200722,22 +200722,22 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
** of upper() or lower().
**
** lower('I', 'en_us') -> 'i'
-** lower('I', 'tr_tr') -> '\u131' (small dotless i)
+** lower('I', 'tr_tr') -> '\u131' (small dotless i)
**
** http://www.icu-project.org/userguide/posix.html#case_mappings
*/
static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
- const UChar *zInput; /* Pointer to input string */
- UChar *zOutput = 0; /* Pointer to output buffer */
- int nInput; /* Size of utf-16 input string in bytes */
- int nOut; /* Size of output buffer in bytes */
- int cnt;
- int bToUpper; /* True for toupper(), false for tolower() */
- UErrorCode status;
+ const UChar *zInput; /* Pointer to input string */
+ UChar *zOutput = 0; /* Pointer to output buffer */
+ int nInput; /* Size of utf-16 input string in bytes */
+ int nOut; /* Size of output buffer in bytes */
+ int cnt;
+ int bToUpper; /* True for toupper(), false for tolower() */
+ UErrorCode status;
const char *zLocale = 0;
assert(nArg==1 || nArg==2);
- bToUpper = (sqlite3_user_data(p)!=0);
+ bToUpper = (sqlite3_user_data(p)!=0);
if( nArg==2 ){
zLocale = (const char *)sqlite3_value_text(apArg[1]);
}
@@ -200746,42 +200746,42 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
if( !zInput ){
return;
}
- nOut = nInput = sqlite3_value_bytes16(apArg[0]);
- if( nOut==0 ){
- sqlite3_result_text16(p, "", 0, SQLITE_STATIC);
+ nOut = nInput = sqlite3_value_bytes16(apArg[0]);
+ if( nOut==0 ){
+ sqlite3_result_text16(p, "", 0, SQLITE_STATIC);
return;
}
- for(cnt=0; cnt<2; cnt++){
- UChar *zNew = sqlite3_realloc(zOutput, nOut);
- if( zNew==0 ){
- sqlite3_free(zOutput);
- sqlite3_result_error_nomem(p);
- return;
- }
- zOutput = zNew;
- status = U_ZERO_ERROR;
- if( bToUpper ){
- nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
- }else{
- nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
- }
-
- if( U_SUCCESS(status) ){
- sqlite3_result_text16(p, zOutput, nOut, xFree);
- }else if( status==U_BUFFER_OVERFLOW_ERROR ){
- assert( cnt==0 );
- continue;
- }else{
- icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status);
- }
+ for(cnt=0; cnt<2; cnt++){
+ UChar *zNew = sqlite3_realloc(zOutput, nOut);
+ if( zNew==0 ){
+ sqlite3_free(zOutput);
+ sqlite3_result_error_nomem(p);
+ return;
+ }
+ zOutput = zNew;
+ status = U_ZERO_ERROR;
+ if( bToUpper ){
+ nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
+ }else{
+ nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
+ }
+
+ if( U_SUCCESS(status) ){
+ sqlite3_result_text16(p, zOutput, nOut, xFree);
+ }else if( status==U_BUFFER_OVERFLOW_ERROR ){
+ assert( cnt==0 );
+ continue;
+ }else{
+ icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status);
+ }
return;
}
- assert( 0 ); /* Unreachable */
+ assert( 0 ); /* Unreachable */
}
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
-
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
+
/*
** Collation sequence destructor function. The pCtx argument points to
** a UCollator structure previously allocated using ucol_open().
@@ -200869,15 +200869,15 @@ static void icuLoadCollation(
*/
SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
# define SQLITEICU_EXTRAFLAGS (SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS)
- static const struct IcuScalar {
+ static const struct IcuScalar {
const char *zName; /* Function name */
- unsigned char nArg; /* Number of arguments */
+ unsigned char nArg; /* Number of arguments */
unsigned int enc; /* Optimal text encoding */
- unsigned char iContext; /* sqlite3_user_data() context */
+ unsigned char iContext; /* sqlite3_user_data() context */
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
} scalars[] = {
{"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation},
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
{"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc},
{"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
{"lower", 2, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16},
@@ -200889,17 +200889,17 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
{"upper", 2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 1, icuCaseFunc16},
{"like", 2, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuLikeFunc},
{"like", 3, SQLITE_UTF8|SQLITEICU_EXTRAFLAGS, 0, icuLikeFunc},
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
};
int rc = SQLITE_OK;
int i;
for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){
- const struct IcuScalar *p = &scalars[i];
+ const struct IcuScalar *p = &scalars[i];
rc = sqlite3_create_function(
db, p->zName, p->nArg, p->enc,
- p->iContext ? (void*)db : (void*)0,
- p->xFunc, 0, 0
+ p->iContext ? (void*)db : (void*)0,
+ p->xFunc, 0, 0
);
}
@@ -200910,7 +200910,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int sqlite3_icu_init(
+SQLITE_API int sqlite3_icu_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -201379,18 +201379,18 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
**
** The order of the columns in the data_% table does not matter.
**
-** Instead of a regular table, the RBU database may also contain virtual
+** Instead of a regular table, the RBU database may also contain virtual
** tables or view named using the data_<target> naming scheme.
-**
+**
** Instead of the plain data_<target> naming scheme, RBU database tables
-** may also be named data<integer>_<target>, where <integer> is any sequence
-** of zero or more numeric characters (0-9). This can be significant because
+** may also be named data<integer>_<target>, where <integer> is any sequence
+** of zero or more numeric characters (0-9). This can be significant because
** tables within the RBU database are always processed in order sorted by
-** name. By judicious selection of the <integer> portion of the names
-** of the RBU tables the user can therefore control the order in which they
-** are processed. This can be useful, for example, to ensure that "external
-** content" FTS4 tables are updated before their underlying content tables.
-**
+** name. By judicious selection of the <integer> portion of the names
+** of the RBU tables the user can therefore control the order in which they
+** are processed. This can be useful, for example, to ensure that "external
+** content" FTS4 tables are updated before their underlying content tables.
+**
** If the target database table is a virtual table or a table that has no
** PRIMARY KEY declaration, the data_% table must also contain a column
** named "rbu_rowid". This column is mapped to the tables implicit primary
@@ -201472,13 +201472,13 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
** UPDATE t1 SET c = rbu_delta(c, 'usa') WHERE a = 4;
**
** Finally, if an 'f' character appears in place of a 'd' or 's' in an
-** ota_control string, the contents of the data_xxx table column is assumed
-** to be a "fossil delta" - a patch to be applied to a blob value in the
-** format used by the fossil source-code management system. In this case
+** ota_control string, the contents of the data_xxx table column is assumed
+** to be a "fossil delta" - a patch to be applied to a blob value in the
+** format used by the fossil source-code management system. In this case
** the existing value within the target database table must be of type BLOB.
-** It is replaced by the result of applying the specified fossil delta to
-** itself.
-**
+** It is replaced by the result of applying the specified fossil delta to
+** itself.
+**
** If the target database table is a virtual table or a table with no PRIMARY
** KEY, the rbu_control value should not include a character corresponding
** to the rbu_rowid value. For example, this:
@@ -201551,10 +201551,10 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
/* #include "sqlite3.h" ** Required for error code definitions ** */
-#if 0
-extern "C" {
-#endif
-
+#if 0
+extern "C" {
+#endif
+
typedef struct sqlite3rbu sqlite3rbu;
/*
@@ -201590,77 +201590,77 @@ typedef struct sqlite3rbu sqlite3rbu;
** not work out of the box with zipvfs. Refer to the comment describing
** the zipvfs_create_vfs() API below for details on using RBU with zipvfs.
*/
-SQLITE_API sqlite3rbu *sqlite3rbu_open(
+SQLITE_API sqlite3rbu *sqlite3rbu_open(
const char *zTarget,
const char *zRbu,
const char *zState
);
/*
-** Open an RBU handle to perform an RBU vacuum on database file zTarget.
-** An RBU vacuum is similar to SQLite's built-in VACUUM command, except
-** that it can be suspended and resumed like an RBU update.
-**
+** Open an RBU handle to perform an RBU vacuum on database file zTarget.
+** An RBU vacuum is similar to SQLite's built-in VACUUM command, except
+** that it can be suspended and resumed like an RBU update.
+**
** The second argument to this function identifies a database in which
** to store the state of the RBU vacuum operation if it is suspended. The
-** first time sqlite3rbu_vacuum() is called, to start an RBU vacuum
-** operation, the state database should either not exist or be empty
+** first time sqlite3rbu_vacuum() is called, to start an RBU vacuum
+** operation, the state database should either not exist or be empty
** (contain no tables). If an RBU vacuum is suspended by calling
-** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has
+** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has
** returned SQLITE_DONE, the vacuum state is stored in the state database.
-** The vacuum can be resumed by calling this function to open a new RBU
-** handle specifying the same target and state databases.
-**
-** If the second argument passed to this function is NULL, then the
-** name of the state database is "<database>-vacuum", where <database>
-** is the name of the target database file. In this case, on UNIX, if the
-** state database is not already present in the file-system, it is created
+** The vacuum can be resumed by calling this function to open a new RBU
+** handle specifying the same target and state databases.
+**
+** If the second argument passed to this function is NULL, then the
+** name of the state database is "<database>-vacuum", where <database>
+** is the name of the target database file. In this case, on UNIX, if the
+** state database is not already present in the file-system, it is created
** with the same permissions as the target db is made.
-**
+**
** With an RBU vacuum, it is an SQLITE_MISUSE error if the name of the
** state database ends with "-vactmp". This name is reserved for internal
** use.
**
-** This function does not delete the state database after an RBU vacuum
-** is completed, even if it created it. However, if the call to
-** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents
-** of the state tables within the state database are zeroed. This way,
+** This function does not delete the state database after an RBU vacuum
+** is completed, even if it created it. However, if the call to
+** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents
+** of the state tables within the state database are zeroed. This way,
** the next call to sqlite3rbu_vacuum() opens a handle that starts a
-** new RBU vacuum operation.
-**
-** As with sqlite3rbu_open(), Zipvfs users should rever to the comment
+** new RBU vacuum operation.
+**
+** As with sqlite3rbu_open(), Zipvfs users should rever to the comment
** describing the sqlite3rbu_create_vfs() API function below for
** a description of the complications associated with using RBU with
-** zipvfs databases.
-*/
-SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
+** zipvfs databases.
+*/
+SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
const char *zTarget,
- const char *zState
-);
-
-/*
-** Configure a limit for the amount of temp space that may be used by
-** the RBU handle passed as the first argument. The new limit is specified
-** in bytes by the second parameter. If it is positive, the limit is updated.
-** If the second parameter to this function is passed zero, then the limit
-** is removed entirely. If the second parameter is negative, the limit is
-** not modified (this is useful for querying the current limit).
-**
+ const char *zState
+);
+
+/*
+** Configure a limit for the amount of temp space that may be used by
+** the RBU handle passed as the first argument. The new limit is specified
+** in bytes by the second parameter. If it is positive, the limit is updated.
+** If the second parameter to this function is passed zero, then the limit
+** is removed entirely. If the second parameter is negative, the limit is
+** not modified (this is useful for querying the current limit).
+**
** In all cases the returned value is the current limit in bytes (zero
-** indicates unlimited).
-**
-** If the temp space limit is exceeded during operation, an SQLITE_FULL
-** error is returned.
-*/
-SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu*, sqlite3_int64);
-
-/*
+** indicates unlimited).
+**
+** If the temp space limit is exceeded during operation, an SQLITE_FULL
+** error is returned.
+*/
+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu*, sqlite3_int64);
+
+/*
** Return the current amount of temp file space, in bytes, currently used by
-** the RBU handle passed as the only argument.
-*/
-SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu*);
-
-/*
+** the RBU handle passed as the only argument.
+*/
+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu*);
+
+/*
** Internally, each RBU connection uses a separate SQLite database
** connection to access the target and rbu update databases. This
** API allows the application direct access to these database handles.
@@ -201687,11 +201687,11 @@ SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu*);
** If an error has occurred, either while opening or stepping the RBU object,
** this function may return NULL. The error code and message may be collected
** when sqlite3rbu_close() is called.
-**
-** Database handles returned by this function remain valid until the next
-** call to any sqlite3rbu_xxx() function other than sqlite3rbu_db().
+**
+** Database handles returned by this function remain valid until the next
+** call to any sqlite3rbu_xxx() function other than sqlite3rbu_db().
*/
-SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu);
+SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu);
/*
** Do some work towards applying the RBU update to the target db.
@@ -201705,21 +201705,21 @@ SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu);
** SQLITE_OK, all subsequent calls on the same RBU handle are no-ops
** that immediately return the same value.
*/
-SQLITE_API int sqlite3rbu_step(sqlite3rbu *pRbu);
+SQLITE_API int sqlite3rbu_step(sqlite3rbu *pRbu);
/*
-** Force RBU to save its state to disk.
-**
-** If a power failure or application crash occurs during an update, following
-** system recovery RBU may resume the update from the point at which the state
+** Force RBU to save its state to disk.
+**
+** If a power failure or application crash occurs during an update, following
+** system recovery RBU may resume the update from the point at which the state
** was last saved. In other words, from the most recent successful call to
-** sqlite3rbu_close() or this function.
-**
-** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
-*/
-SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu);
-
-/*
+** sqlite3rbu_close() or this function.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu);
+
+/*
** Close an RBU handle.
**
** If the RBU update has been completely applied, mark the RBU database
@@ -201728,105 +201728,105 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu);
**
** If an error has already occurred as part of an sqlite3rbu_step()
** or sqlite3rbu_open() call, or if one occurs within this function, an
-** SQLite error code is returned. Additionally, if pzErrmsg is not NULL,
-** *pzErrmsg may be set to point to a buffer containing a utf-8 formatted
-** English language error message. It is the responsibility of the caller to
-** eventually free any such buffer using sqlite3_free().
+** SQLite error code is returned. Additionally, if pzErrmsg is not NULL,
+** *pzErrmsg may be set to point to a buffer containing a utf-8 formatted
+** English language error message. It is the responsibility of the caller to
+** eventually free any such buffer using sqlite3_free().
**
** Otherwise, if no error occurs, this function returns SQLITE_OK if the
** update has been partially applied, or SQLITE_DONE if it has been
** completely applied.
*/
-SQLITE_API int sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg);
+SQLITE_API int sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg);
/*
** Return the total number of key-value operations (inserts, deletes or
** updates) that have been performed on the target database since the
** current RBU update was started.
*/
-SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu);
+SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu);
/*
** Obtain permyriadage (permyriadage is to 10000 as percentage is to 100)
-** progress indications for the two stages of an RBU update. This API may
-** be useful for driving GUI progress indicators and similar.
-**
-** An RBU update is divided into two stages:
-**
-** * Stage 1, in which changes are accumulated in an oal/wal file, and
-** * Stage 2, in which the contents of the wal file are copied into the
-** main database.
-**
-** The update is visible to non-RBU clients during stage 2. During stage 1
-** non-RBU reader clients may see the original database.
-**
+** progress indications for the two stages of an RBU update. This API may
+** be useful for driving GUI progress indicators and similar.
+**
+** An RBU update is divided into two stages:
+**
+** * Stage 1, in which changes are accumulated in an oal/wal file, and
+** * Stage 2, in which the contents of the wal file are copied into the
+** main database.
+**
+** The update is visible to non-RBU clients during stage 2. During stage 1
+** non-RBU reader clients may see the original database.
+**
** If this API is called during stage 2 of the update, output variable
-** (*pnOne) is set to 10000 to indicate that stage 1 has finished and (*pnTwo)
-** to a value between 0 and 10000 to indicate the permyriadage progress of
+** (*pnOne) is set to 10000 to indicate that stage 1 has finished and (*pnTwo)
+** to a value between 0 and 10000 to indicate the permyriadage progress of
** stage 2. A value of 5000 indicates that stage 2 is half finished,
-** 9000 indicates that it is 90% finished, and so on.
-**
+** 9000 indicates that it is 90% finished, and so on.
+**
** If this API is called during stage 1 of the update, output variable
-** (*pnTwo) is set to 0 to indicate that stage 2 has not yet started. The
+** (*pnTwo) is set to 0 to indicate that stage 2 has not yet started. The
** value to which (*pnOne) is set depends on whether or not the RBU
** database contains an "rbu_count" table. The rbu_count table, if it
-** exists, must contain the same columns as the following:
-**
-** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
-**
-** There must be one row in the table for each source (data_xxx) table within
-** the RBU database. The 'tbl' column should contain the name of the source
-** table. The 'cnt' column should contain the number of rows within the
-** source table.
-**
-** If the rbu_count table is present and populated correctly and this
-** API is called during stage 1, the *pnOne output variable is set to the
-** permyriadage progress of the same stage. If the rbu_count table does
-** not exist, then (*pnOne) is set to -1 during stage 1. If the rbu_count
-** table exists but is not correctly populated, the value of the *pnOne
-** output variable during stage 1 is undefined.
-*/
-SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int*pnTwo);
-
-/*
-** Obtain an indication as to the current stage of an RBU update or vacuum.
-** This function always returns one of the SQLITE_RBU_STATE_XXX constants
-** defined in this file. Return values should be interpreted as follows:
-**
-** SQLITE_RBU_STATE_OAL:
-** RBU is currently building a *-oal file. The next call to sqlite3rbu_step()
-** may either add further data to the *-oal file, or compute data that will
-** be added by a subsequent call.
-**
-** SQLITE_RBU_STATE_MOVE:
-** RBU has finished building the *-oal file. The next call to sqlite3rbu_step()
-** will move the *-oal file to the equivalent *-wal path. If the current
-** operation is an RBU update, then the updated version of the database
-** file will become visible to ordinary SQLite clients following the next
-** call to sqlite3rbu_step().
-**
-** SQLITE_RBU_STATE_CHECKPOINT:
-** RBU is currently performing an incremental checkpoint. The next call to
-** sqlite3rbu_step() will copy a page of data from the *-wal file into
-** the target database file.
-**
-** SQLITE_RBU_STATE_DONE:
-** The RBU operation has finished. Any subsequent calls to sqlite3rbu_step()
-** will immediately return SQLITE_DONE.
-**
-** SQLITE_RBU_STATE_ERROR:
-** An error has occurred. Any subsequent calls to sqlite3rbu_step() will
-** immediately return the SQLite error code associated with the error.
-*/
-#define SQLITE_RBU_STATE_OAL 1
-#define SQLITE_RBU_STATE_MOVE 2
-#define SQLITE_RBU_STATE_CHECKPOINT 3
-#define SQLITE_RBU_STATE_DONE 4
-#define SQLITE_RBU_STATE_ERROR 5
-
-SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu);
-
-/*
+** exists, must contain the same columns as the following:
+**
+** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
+**
+** There must be one row in the table for each source (data_xxx) table within
+** the RBU database. The 'tbl' column should contain the name of the source
+** table. The 'cnt' column should contain the number of rows within the
+** source table.
+**
+** If the rbu_count table is present and populated correctly and this
+** API is called during stage 1, the *pnOne output variable is set to the
+** permyriadage progress of the same stage. If the rbu_count table does
+** not exist, then (*pnOne) is set to -1 during stage 1. If the rbu_count
+** table exists but is not correctly populated, the value of the *pnOne
+** output variable during stage 1 is undefined.
+*/
+SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int*pnTwo);
+
+/*
+** Obtain an indication as to the current stage of an RBU update or vacuum.
+** This function always returns one of the SQLITE_RBU_STATE_XXX constants
+** defined in this file. Return values should be interpreted as follows:
+**
+** SQLITE_RBU_STATE_OAL:
+** RBU is currently building a *-oal file. The next call to sqlite3rbu_step()
+** may either add further data to the *-oal file, or compute data that will
+** be added by a subsequent call.
+**
+** SQLITE_RBU_STATE_MOVE:
+** RBU has finished building the *-oal file. The next call to sqlite3rbu_step()
+** will move the *-oal file to the equivalent *-wal path. If the current
+** operation is an RBU update, then the updated version of the database
+** file will become visible to ordinary SQLite clients following the next
+** call to sqlite3rbu_step().
+**
+** SQLITE_RBU_STATE_CHECKPOINT:
+** RBU is currently performing an incremental checkpoint. The next call to
+** sqlite3rbu_step() will copy a page of data from the *-wal file into
+** the target database file.
+**
+** SQLITE_RBU_STATE_DONE:
+** The RBU operation has finished. Any subsequent calls to sqlite3rbu_step()
+** will immediately return SQLITE_DONE.
+**
+** SQLITE_RBU_STATE_ERROR:
+** An error has occurred. Any subsequent calls to sqlite3rbu_step() will
+** immediately return the SQLite error code associated with the error.
+*/
+#define SQLITE_RBU_STATE_OAL 1
+#define SQLITE_RBU_STATE_MOVE 2
+#define SQLITE_RBU_STATE_CHECKPOINT 3
+#define SQLITE_RBU_STATE_DONE 4
+#define SQLITE_RBU_STATE_ERROR 5
+
+SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu);
+
+/*
** Create an RBU VFS named zName that accesses the underlying file-system
** via existing VFS zParent. Or, if the zParent parameter is passed NULL,
** then the new RBU VFS uses the default system VFS to access the file-system.
@@ -201868,7 +201868,7 @@ SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu);
** file-system via "rbu" all the time, even if it only uses RBU functionality
** occasionally.
*/
-SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent);
+SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent);
/*
** Deregister and destroy an RBU vfs created by an earlier call to
@@ -201878,31 +201878,31 @@ SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent);
** before all database handles that use it have been closed, the results
** are undefined.
*/
-SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName);
+SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName);
+
+#if 0
+} /* end of the 'extern "C"' block */
+#endif
-#if 0
-} /* end of the 'extern "C"' block */
-#endif
-
#endif /* _SQLITE3RBU_H */
/************** End of sqlite3rbu.h ******************************************/
/************** Continuing where we left off in sqlite3rbu.c *****************/
-#if defined(_WIN32_WCE)
-/* #include "windows.h" */
-#endif
-
+#if defined(_WIN32_WCE)
+/* #include "windows.h" */
+#endif
+
/* Maximum number of prepared UPDATE statements held by this module */
#define SQLITE_RBU_UPDATE_CACHESIZE 16
-/* Delta checksums disabled by default. Compile with -DRBU_ENABLE_DELTA_CKSUM
-** to enable checksum verification.
-*/
-#ifndef RBU_ENABLE_DELTA_CKSUM
-# define RBU_ENABLE_DELTA_CKSUM 0
-#endif
-
+/* Delta checksums disabled by default. Compile with -DRBU_ENABLE_DELTA_CKSUM
+** to enable checksum verification.
+*/
+#ifndef RBU_ENABLE_DELTA_CKSUM
+# define RBU_ENABLE_DELTA_CKSUM 0
+#endif
+
/*
** Swap two objects of type TYPE.
*/
@@ -201965,15 +201965,15 @@ SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName);
** Only valid if STAGE==1. The RBU database name of the table
** currently being read.
*/
-#define RBU_STATE_STAGE 1
-#define RBU_STATE_TBL 2
-#define RBU_STATE_IDX 3
-#define RBU_STATE_ROW 4
-#define RBU_STATE_PROGRESS 5
-#define RBU_STATE_CKPT 6
-#define RBU_STATE_COOKIE 7
-#define RBU_STATE_OALSZ 8
-#define RBU_STATE_PHASEONESTEP 9
+#define RBU_STATE_STAGE 1
+#define RBU_STATE_TBL 2
+#define RBU_STATE_IDX 3
+#define RBU_STATE_ROW 4
+#define RBU_STATE_PROGRESS 5
+#define RBU_STATE_CKPT 6
+#define RBU_STATE_COOKIE 7
+#define RBU_STATE_OALSZ 8
+#define RBU_STATE_PHASEONESTEP 9
#define RBU_STATE_DATATBL 10
#define RBU_STAGE_OAL 1
@@ -201996,7 +201996,7 @@ typedef struct RbuUpdateStmt RbuUpdateStmt;
#if !defined(SQLITE_AMALGAMATION)
typedef unsigned int u32;
-typedef unsigned short u16;
+typedef unsigned short u16;
typedef unsigned char u8;
typedef sqlite3_int64 i64;
#endif
@@ -202010,8 +202010,8 @@ typedef sqlite3_int64 i64;
#define WAL_LOCK_CKPT 1
#define WAL_LOCK_READ0 3
-#define SQLITE_FCNTL_RBUCNT 5149216
-
+#define SQLITE_FCNTL_RBUCNT 5149216
+
/*
** A structure to store values read from the rbu_state table in memory.
*/
@@ -202025,7 +202025,7 @@ struct RbuState {
i64 nProgress;
u32 iCookie;
i64 iOalSz;
- i64 nPhaseOneStep;
+ i64 nPhaseOneStep;
};
struct RbuUpdateStmt {
@@ -202075,19 +202075,19 @@ struct RbuObjIter {
/* Output variables. zTbl==0 implies EOF. */
int bCleanup; /* True in "cleanup" state */
const char *zTbl; /* Name of target db table */
- const char *zDataTbl; /* Name of rbu db table (or null) */
+ const char *zDataTbl; /* Name of rbu db table (or null) */
const char *zIdx; /* Name of target db index (or null) */
int iTnum; /* Root page of current object */
int iPkTnum; /* If eType==EXTERNAL, root of PK index */
int bUnique; /* Current index is unique */
- int nIndex; /* Number of aux. indexes on table zTbl */
+ int nIndex; /* Number of aux. indexes on table zTbl */
/* Statements created by rbuObjIterPrepareAll() */
int nCol; /* Number of columns in current object */
sqlite3_stmt *pSelect; /* Source data */
sqlite3_stmt *pInsert; /* Statement for INSERT operations */
sqlite3_stmt *pDelete; /* Statement for DELETE ops */
- sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */
+ sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */
int nIdxCol;
RbuSpan *aIdxCol;
char *zIdxSql;
@@ -202120,11 +202120,11 @@ struct RbuObjIter {
*/
#define RBU_INSERT 1 /* Insert on a main table b-tree */
#define RBU_DELETE 2 /* Delete a row from a main table b-tree */
-#define RBU_REPLACE 3 /* Delete and then insert a row */
-#define RBU_IDX_DELETE 4 /* Delete a row from an aux. index b-tree */
-#define RBU_IDX_INSERT 5 /* Insert on an aux. index b-tree */
+#define RBU_REPLACE 3 /* Delete and then insert a row */
+#define RBU_IDX_DELETE 4 /* Delete a row from an aux. index b-tree */
+#define RBU_IDX_INSERT 5 /* Insert on an aux. index b-tree */
-#define RBU_UPDATE 6 /* Update a row in a main table b-tree */
+#define RBU_UPDATE 6 /* Update a row in a main table b-tree */
/*
** A single step of an incremental checkpoint - frame iWalFrame of the wal
@@ -202137,43 +202137,43 @@ struct RbuFrame {
/*
** RBU handle.
-**
-** nPhaseOneStep:
-** If the RBU database contains an rbu_count table, this value is set to
+**
+** nPhaseOneStep:
+** If the RBU database contains an rbu_count table, this value is set to
** a running estimate of the number of b-tree operations required to
-** finish populating the *-oal file. This allows the sqlite3_bp_progress()
-** API to calculate the permyriadage progress of populating the *-oal file
-** using the formula:
-**
-** permyriadage = (10000 * nProgress) / nPhaseOneStep
-**
-** nPhaseOneStep is initialized to the sum of:
-**
-** nRow * (nIndex + 1)
-**
-** for all source tables in the RBU database, where nRow is the number
-** of rows in the source table and nIndex the number of indexes on the
-** corresponding target database table.
-**
-** This estimate is accurate if the RBU update consists entirely of
-** INSERT operations. However, it is inaccurate if:
-**
-** * the RBU update contains any UPDATE operations. If the PK specified
-** for an UPDATE operation does not exist in the target table, then
+** finish populating the *-oal file. This allows the sqlite3_bp_progress()
+** API to calculate the permyriadage progress of populating the *-oal file
+** using the formula:
+**
+** permyriadage = (10000 * nProgress) / nPhaseOneStep
+**
+** nPhaseOneStep is initialized to the sum of:
+**
+** nRow * (nIndex + 1)
+**
+** for all source tables in the RBU database, where nRow is the number
+** of rows in the source table and nIndex the number of indexes on the
+** corresponding target database table.
+**
+** This estimate is accurate if the RBU update consists entirely of
+** INSERT operations. However, it is inaccurate if:
+**
+** * the RBU update contains any UPDATE operations. If the PK specified
+** for an UPDATE operation does not exist in the target table, then
** no b-tree operations are required on index b-trees. Or if the
-** specified PK does exist, then (nIndex*2) such operations are
-** required (one delete and one insert on each index b-tree).
-**
-** * the RBU update contains any DELETE operations for which the specified
-** PK does not exist. In this case no operations are required on index
-** b-trees.
-**
-** * the RBU update contains REPLACE operations. These are similar to
-** UPDATE operations.
-**
-** nPhaseOneStep is updated to account for the conditions above during the
-** first pass of each source table. The updated nPhaseOneStep value is
-** stored in the rbu_state table if the RBU update is suspended.
+** specified PK does exist, then (nIndex*2) such operations are
+** required (one delete and one insert on each index b-tree).
+**
+** * the RBU update contains any DELETE operations for which the specified
+** PK does not exist. In this case no operations are required on index
+** b-trees.
+**
+** * the RBU update contains REPLACE operations. These are similar to
+** UPDATE operations.
+**
+** nPhaseOneStep is updated to account for the conditions above during the
+** first pass of each source table. The updated nPhaseOneStep value is
+** stored in the rbu_state table if the RBU update is suspended.
*/
struct sqlite3rbu {
int eStage; /* Value of RBU_STATE_STAGE field */
@@ -202190,9 +202190,9 @@ struct sqlite3rbu {
RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
const char *zVfsName; /* Name of automatically created rbu vfs */
rbu_file *pTargetFd; /* File handle open on target db */
- int nPagePerSector; /* Pages per sector for pTargetFd */
+ int nPagePerSector; /* Pages per sector for pTargetFd */
i64 iOalSz;
- i64 nPhaseOneStep;
+ i64 nPhaseOneStep;
/* The following state variables are used as part of the incremental
** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding
@@ -202205,27 +202205,27 @@ struct sqlite3rbu {
int pgsz;
u8 *aBuf;
i64 iWalCksum;
- i64 szTemp; /* Current size of all temp files in use */
- i64 szTempLimit; /* Total size limit for temp files */
-
- /* Used in RBU vacuum mode only */
- int nRbu; /* Number of RBU VFS in the stack */
- rbu_file *pRbuFd; /* Fd for main db of dbRbu */
+ i64 szTemp; /* Current size of all temp files in use */
+ i64 szTempLimit; /* Total size limit for temp files */
+
+ /* Used in RBU vacuum mode only */
+ int nRbu; /* Number of RBU VFS in the stack */
+ rbu_file *pRbuFd; /* Fd for main db of dbRbu */
};
/*
** An rbu VFS is implemented using an instance of this structure.
-**
-** Variable pRbu is only non-NULL for automatically created RBU VFS objects.
-** It is NULL for RBU VFS objects created explicitly using
-** sqlite3rbu_create_vfs(). It is used to track the total amount of temp
-** space used by the RBU handle.
+**
+** Variable pRbu is only non-NULL for automatically created RBU VFS objects.
+** It is NULL for RBU VFS objects created explicitly using
+** sqlite3rbu_create_vfs(). It is used to track the total amount of temp
+** space used by the RBU handle.
*/
struct rbu_vfs {
sqlite3_vfs base; /* rbu VFS shim methods */
sqlite3_vfs *pRealVfs; /* Underlying VFS */
sqlite3_mutex *mutex; /* Mutex to protect pMain */
- sqlite3rbu *pRbu; /* Owner RBU object */
+ sqlite3rbu *pRbu; /* Owner RBU object */
rbu_file *pMain; /* List of main db files */
rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */
};
@@ -202233,21 +202233,21 @@ struct rbu_vfs {
/*
** Each file opened by an rbu VFS is represented by an instance of
** the following structure.
-**
-** If this is a temporary file (pRbu!=0 && flags&DELETE_ON_CLOSE), variable
-** "sz" is set to the current size of the database file.
+**
+** If this is a temporary file (pRbu!=0 && flags&DELETE_ON_CLOSE), variable
+** "sz" is set to the current size of the database file.
*/
struct rbu_file {
sqlite3_file base; /* sqlite3_file methods */
sqlite3_file *pReal; /* Underlying file handle */
rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */
sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */
- i64 sz; /* Size of file in bytes (temp only) */
+ i64 sz; /* Size of file in bytes (temp only) */
int openFlags; /* Flags this file was opened with */
u32 iCookie; /* Cookie value for main db files */
u8 iWriteVer; /* "write-version" value for main db files */
- u8 bNolock; /* True to fail EXCLUSIVE locks */
+ u8 bNolock; /* True to fail EXCLUSIVE locks */
int nShm; /* Number of entries in apShm[] array */
char **apShm; /* Array of mmap'd *-shm regions */
@@ -202259,262 +202259,262 @@ struct rbu_file {
rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */
};
-/*
-** True for an RBU vacuum handle, or false otherwise.
-*/
-#define rbuIsVacuum(p) ((p)->zTarget==0)
-
-
-/*************************************************************************
-** The following three functions, found below:
-**
-** rbuDeltaGetInt()
-** rbuDeltaChecksum()
-** rbuDeltaApply()
-**
-** are lifted from the fossil source code (http://fossil-scm.org). They
-** are used to implement the scalar SQL function rbu_fossil_delta().
-*/
-
-/*
-** Read bytes from *pz and convert them into a positive integer. When
-** finished, leave *pz pointing to the first character past the end of
-** the integer. The *pLen parameter holds the length of the string
-** in *pz and is decremented once for each character in the integer.
-*/
-static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){
- static const signed char zValue[] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
- -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36,
- -1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1,
- };
- unsigned int v = 0;
- int c;
- unsigned char *z = (unsigned char*)*pz;
- unsigned char *zStart = z;
- while( (c = zValue[0x7f&*(z++)])>=0 ){
- v = (v<<6) + c;
- }
- z--;
- *pLen -= z - zStart;
- *pz = (char*)z;
- return v;
-}
-
-#if RBU_ENABLE_DELTA_CKSUM
-/*
-** Compute a 32-bit checksum on the N-byte buffer. Return the result.
-*/
-static unsigned int rbuDeltaChecksum(const char *zIn, size_t N){
- const unsigned char *z = (const unsigned char *)zIn;
- unsigned sum0 = 0;
- unsigned sum1 = 0;
- unsigned sum2 = 0;
- unsigned sum3 = 0;
- while(N >= 16){
- sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
- sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
- sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
- sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
- z += 16;
- N -= 16;
- }
- while(N >= 4){
- sum0 += z[0];
- sum1 += z[1];
- sum2 += z[2];
- sum3 += z[3];
- z += 4;
- N -= 4;
- }
- sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
- switch(N){
- case 3: sum3 += (z[2] << 8);
- case 2: sum3 += (z[1] << 16);
- case 1: sum3 += (z[0] << 24);
- default: ;
- }
- return sum3;
-}
-#endif
-
-/*
-** Apply a delta.
-**
-** The output buffer should be big enough to hold the whole output
-** file and a NUL terminator at the end. The delta_output_size()
-** routine will determine this size for you.
-**
-** The delta string should be null-terminated. But the delta string
-** may contain embedded NUL characters (if the input and output are
-** binary files) so we also have to pass in the length of the delta in
-** the lenDelta parameter.
-**
-** This function returns the size of the output file in bytes (excluding
-** the final NUL terminator character). Except, if the delta string is
-** malformed or intended for use with a source file other than zSrc,
-** then this routine returns -1.
-**
-** Refer to the delta_create() documentation above for a description
-** of the delta file format.
-*/
-static int rbuDeltaApply(
- const char *zSrc, /* The source or pattern file */
- int lenSrc, /* Length of the source file */
- const char *zDelta, /* Delta to apply to the pattern */
- int lenDelta, /* Length of the delta */
- char *zOut /* Write the output into this preallocated buffer */
-){
- unsigned int limit;
- unsigned int total = 0;
-#if RBU_ENABLE_DELTA_CKSUM
- char *zOrigOut = zOut;
-#endif
-
- limit = rbuDeltaGetInt(&zDelta, &lenDelta);
- if( *zDelta!='\n' ){
- /* ERROR: size integer not terminated by "\n" */
- return -1;
- }
- zDelta++; lenDelta--;
- while( *zDelta && lenDelta>0 ){
- unsigned int cnt, ofst;
- cnt = rbuDeltaGetInt(&zDelta, &lenDelta);
- switch( zDelta[0] ){
- case '@': {
- zDelta++; lenDelta--;
- ofst = rbuDeltaGetInt(&zDelta, &lenDelta);
- if( lenDelta>0 && zDelta[0]!=',' ){
- /* ERROR: copy command not terminated by ',' */
- return -1;
- }
- zDelta++; lenDelta--;
- total += cnt;
- if( total>limit ){
- /* ERROR: copy exceeds output file size */
- return -1;
- }
- if( (int)(ofst+cnt) > lenSrc ){
- /* ERROR: copy extends past end of input */
- return -1;
- }
- memcpy(zOut, &zSrc[ofst], cnt);
- zOut += cnt;
- break;
- }
- case ':': {
- zDelta++; lenDelta--;
- total += cnt;
- if( total>limit ){
- /* ERROR: insert command gives an output larger than predicted */
- return -1;
- }
- if( (int)cnt>lenDelta ){
- /* ERROR: insert count exceeds size of delta */
- return -1;
- }
- memcpy(zOut, zDelta, cnt);
- zOut += cnt;
- zDelta += cnt;
- lenDelta -= cnt;
- break;
- }
- case ';': {
- zDelta++; lenDelta--;
- zOut[0] = 0;
-#if RBU_ENABLE_DELTA_CKSUM
- if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){
- /* ERROR: bad checksum */
- return -1;
- }
-#endif
- if( total!=limit ){
- /* ERROR: generated size does not match predicted size */
- return -1;
- }
- return total;
- }
- default: {
- /* ERROR: unknown delta operator */
- return -1;
- }
- }
- }
- /* ERROR: unterminated delta */
- return -1;
-}
-
-static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){
- int size;
- size = rbuDeltaGetInt(&zDelta, &lenDelta);
- if( *zDelta!='\n' ){
- /* ERROR: size integer not terminated by "\n" */
- return -1;
- }
- return size;
-}
-
-/*
-** End of code taken from fossil.
-*************************************************************************/
-
-/*
-** Implementation of SQL scalar function rbu_fossil_delta().
-**
-** This function applies a fossil delta patch to a blob. Exactly two
-** arguments must be passed to this function. The first is the blob to
-** patch and the second the patch to apply. If no error occurs, this
-** function returns the patched blob.
-*/
-static void rbuFossilDeltaFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *aDelta;
- int nDelta;
- const char *aOrig;
- int nOrig;
-
- int nOut;
- int nOut2;
- char *aOut;
-
- assert( argc==2 );
-
- nOrig = sqlite3_value_bytes(argv[0]);
- aOrig = (const char*)sqlite3_value_blob(argv[0]);
- nDelta = sqlite3_value_bytes(argv[1]);
- aDelta = (const char*)sqlite3_value_blob(argv[1]);
-
- /* Figure out the size of the output */
- nOut = rbuDeltaOutputSize(aDelta, nDelta);
- if( nOut<0 ){
- sqlite3_result_error(context, "corrupt fossil delta", -1);
- return;
- }
-
- aOut = sqlite3_malloc(nOut+1);
- if( aOut==0 ){
- sqlite3_result_error_nomem(context);
- }else{
- nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut);
- if( nOut2!=nOut ){
+/*
+** True for an RBU vacuum handle, or false otherwise.
+*/
+#define rbuIsVacuum(p) ((p)->zTarget==0)
+
+
+/*************************************************************************
+** The following three functions, found below:
+**
+** rbuDeltaGetInt()
+** rbuDeltaChecksum()
+** rbuDeltaApply()
+**
+** are lifted from the fossil source code (http://fossil-scm.org). They
+** are used to implement the scalar SQL function rbu_fossil_delta().
+*/
+
+/*
+** Read bytes from *pz and convert them into a positive integer. When
+** finished, leave *pz pointing to the first character past the end of
+** the integer. The *pLen parameter holds the length of the string
+** in *pz and is decremented once for each character in the integer.
+*/
+static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){
+ static const signed char zValue[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36,
+ -1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1,
+ };
+ unsigned int v = 0;
+ int c;
+ unsigned char *z = (unsigned char*)*pz;
+ unsigned char *zStart = z;
+ while( (c = zValue[0x7f&*(z++)])>=0 ){
+ v = (v<<6) + c;
+ }
+ z--;
+ *pLen -= z - zStart;
+ *pz = (char*)z;
+ return v;
+}
+
+#if RBU_ENABLE_DELTA_CKSUM
+/*
+** Compute a 32-bit checksum on the N-byte buffer. Return the result.
+*/
+static unsigned int rbuDeltaChecksum(const char *zIn, size_t N){
+ const unsigned char *z = (const unsigned char *)zIn;
+ unsigned sum0 = 0;
+ unsigned sum1 = 0;
+ unsigned sum2 = 0;
+ unsigned sum3 = 0;
+ while(N >= 16){
+ sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
+ sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
+ sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
+ sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
+ z += 16;
+ N -= 16;
+ }
+ while(N >= 4){
+ sum0 += z[0];
+ sum1 += z[1];
+ sum2 += z[2];
+ sum3 += z[3];
+ z += 4;
+ N -= 4;
+ }
+ sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
+ switch(N){
+ case 3: sum3 += (z[2] << 8);
+ case 2: sum3 += (z[1] << 16);
+ case 1: sum3 += (z[0] << 24);
+ default: ;
+ }
+ return sum3;
+}
+#endif
+
+/*
+** Apply a delta.
+**
+** The output buffer should be big enough to hold the whole output
+** file and a NUL terminator at the end. The delta_output_size()
+** routine will determine this size for you.
+**
+** The delta string should be null-terminated. But the delta string
+** may contain embedded NUL characters (if the input and output are
+** binary files) so we also have to pass in the length of the delta in
+** the lenDelta parameter.
+**
+** This function returns the size of the output file in bytes (excluding
+** the final NUL terminator character). Except, if the delta string is
+** malformed or intended for use with a source file other than zSrc,
+** then this routine returns -1.
+**
+** Refer to the delta_create() documentation above for a description
+** of the delta file format.
+*/
+static int rbuDeltaApply(
+ const char *zSrc, /* The source or pattern file */
+ int lenSrc, /* Length of the source file */
+ const char *zDelta, /* Delta to apply to the pattern */
+ int lenDelta, /* Length of the delta */
+ char *zOut /* Write the output into this preallocated buffer */
+){
+ unsigned int limit;
+ unsigned int total = 0;
+#if RBU_ENABLE_DELTA_CKSUM
+ char *zOrigOut = zOut;
+#endif
+
+ limit = rbuDeltaGetInt(&zDelta, &lenDelta);
+ if( *zDelta!='\n' ){
+ /* ERROR: size integer not terminated by "\n" */
+ return -1;
+ }
+ zDelta++; lenDelta--;
+ while( *zDelta && lenDelta>0 ){
+ unsigned int cnt, ofst;
+ cnt = rbuDeltaGetInt(&zDelta, &lenDelta);
+ switch( zDelta[0] ){
+ case '@': {
+ zDelta++; lenDelta--;
+ ofst = rbuDeltaGetInt(&zDelta, &lenDelta);
+ if( lenDelta>0 && zDelta[0]!=',' ){
+ /* ERROR: copy command not terminated by ',' */
+ return -1;
+ }
+ zDelta++; lenDelta--;
+ total += cnt;
+ if( total>limit ){
+ /* ERROR: copy exceeds output file size */
+ return -1;
+ }
+ if( (int)(ofst+cnt) > lenSrc ){
+ /* ERROR: copy extends past end of input */
+ return -1;
+ }
+ memcpy(zOut, &zSrc[ofst], cnt);
+ zOut += cnt;
+ break;
+ }
+ case ':': {
+ zDelta++; lenDelta--;
+ total += cnt;
+ if( total>limit ){
+ /* ERROR: insert command gives an output larger than predicted */
+ return -1;
+ }
+ if( (int)cnt>lenDelta ){
+ /* ERROR: insert count exceeds size of delta */
+ return -1;
+ }
+ memcpy(zOut, zDelta, cnt);
+ zOut += cnt;
+ zDelta += cnt;
+ lenDelta -= cnt;
+ break;
+ }
+ case ';': {
+ zDelta++; lenDelta--;
+ zOut[0] = 0;
+#if RBU_ENABLE_DELTA_CKSUM
+ if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){
+ /* ERROR: bad checksum */
+ return -1;
+ }
+#endif
+ if( total!=limit ){
+ /* ERROR: generated size does not match predicted size */
+ return -1;
+ }
+ return total;
+ }
+ default: {
+ /* ERROR: unknown delta operator */
+ return -1;
+ }
+ }
+ }
+ /* ERROR: unterminated delta */
+ return -1;
+}
+
+static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){
+ int size;
+ size = rbuDeltaGetInt(&zDelta, &lenDelta);
+ if( *zDelta!='\n' ){
+ /* ERROR: size integer not terminated by "\n" */
+ return -1;
+ }
+ return size;
+}
+
+/*
+** End of code taken from fossil.
+*************************************************************************/
+
+/*
+** Implementation of SQL scalar function rbu_fossil_delta().
+**
+** This function applies a fossil delta patch to a blob. Exactly two
+** arguments must be passed to this function. The first is the blob to
+** patch and the second the patch to apply. If no error occurs, this
+** function returns the patched blob.
+*/
+static void rbuFossilDeltaFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *aDelta;
+ int nDelta;
+ const char *aOrig;
+ int nOrig;
+
+ int nOut;
+ int nOut2;
+ char *aOut;
+
+ assert( argc==2 );
+
+ nOrig = sqlite3_value_bytes(argv[0]);
+ aOrig = (const char*)sqlite3_value_blob(argv[0]);
+ nDelta = sqlite3_value_bytes(argv[1]);
+ aDelta = (const char*)sqlite3_value_blob(argv[1]);
+
+ /* Figure out the size of the output */
+ nOut = rbuDeltaOutputSize(aDelta, nDelta);
+ if( nOut<0 ){
+ sqlite3_result_error(context, "corrupt fossil delta", -1);
+ return;
+ }
+
+ aOut = sqlite3_malloc(nOut+1);
+ if( aOut==0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut);
+ if( nOut2!=nOut ){
sqlite3_free(aOut);
- sqlite3_result_error(context, "corrupt fossil delta", -1);
- }else{
- sqlite3_result_blob(context, aOut, nOut, sqlite3_free);
- }
- }
-}
-
-
-/*
+ sqlite3_result_error(context, "corrupt fossil delta", -1);
+ }else{
+ sqlite3_result_blob(context, aOut, nOut, sqlite3_free);
+ }
+ }
+}
+
+
+/*
** Prepare the SQL statement in buffer zSql against database handle db.
** If successful, set *ppStmt to point to the new statement and return
** SQLITE_OK.
@@ -202685,8 +202685,8 @@ static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){
pIter->zTbl = 0;
}else{
pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0);
- pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1);
- rc = (pIter->zDataTbl && pIter->zTbl) ? SQLITE_OK : SQLITE_NOMEM;
+ pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1);
+ rc = (pIter->zDataTbl && pIter->zTbl) ? SQLITE_OK : SQLITE_NOMEM;
}
}else{
if( pIter->zIdx==0 ){
@@ -202717,57 +202717,57 @@ static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){
return rc;
}
-
+
/*
-** The implementation of the rbu_target_name() SQL function. This function
-** accepts one or two arguments. The first argument is the name of a table -
-** the name of a table in the RBU database. The second, if it is present, is 1
+** The implementation of the rbu_target_name() SQL function. This function
+** accepts one or two arguments. The first argument is the name of a table -
+** the name of a table in the RBU database. The second, if it is present, is 1
** for a view or 0 for a table.
-**
-** For a non-vacuum RBU handle, if the table name matches the pattern:
-**
-** data[0-9]_<name>
-**
-** where <name> is any sequence of 1 or more characters, <name> is returned.
-** Otherwise, if the only argument does not match the above pattern, an SQL
-** NULL is returned.
-**
-** "data_t1" -> "t1"
-** "data0123_t2" -> "t2"
-** "dataAB_t3" -> NULL
-**
-** For an rbu vacuum handle, a copy of the first argument is returned if
-** the second argument is either missing or 0 (not a view).
-*/
-static void rbuTargetNameFunc(
- sqlite3_context *pCtx,
- int argc,
- sqlite3_value **argv
-){
- sqlite3rbu *p = sqlite3_user_data(pCtx);
- const char *zIn;
- assert( argc==1 || argc==2 );
-
- zIn = (const char*)sqlite3_value_text(argv[0]);
- if( zIn ){
- if( rbuIsVacuum(p) ){
+**
+** For a non-vacuum RBU handle, if the table name matches the pattern:
+**
+** data[0-9]_<name>
+**
+** where <name> is any sequence of 1 or more characters, <name> is returned.
+** Otherwise, if the only argument does not match the above pattern, an SQL
+** NULL is returned.
+**
+** "data_t1" -> "t1"
+** "data0123_t2" -> "t2"
+** "dataAB_t3" -> NULL
+**
+** For an rbu vacuum handle, a copy of the first argument is returned if
+** the second argument is either missing or 0 (not a view).
+*/
+static void rbuTargetNameFunc(
+ sqlite3_context *pCtx,
+ int argc,
+ sqlite3_value **argv
+){
+ sqlite3rbu *p = sqlite3_user_data(pCtx);
+ const char *zIn;
+ assert( argc==1 || argc==2 );
+
+ zIn = (const char*)sqlite3_value_text(argv[0]);
+ if( zIn ){
+ if( rbuIsVacuum(p) ){
assert( argc==2 || argc==1 );
if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
- sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
- }
- }else{
- if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
- int i;
- for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++);
- if( zIn[i]=='_' && zIn[i+1] ){
- sqlite3_result_text(pCtx, &zIn[i+1], -1, SQLITE_STATIC);
- }
- }
- }
- }
-}
-
-/*
+ sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
+ }
+ }else{
+ if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
+ int i;
+ for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++);
+ if( zIn[i]=='_' && zIn[i+1] ){
+ sqlite3_result_text(pCtx, &zIn[i+1], -1, SQLITE_STATIC);
+ }
+ }
+ }
+ }
+}
+
+/*
** Initialize the iterator structure passed as the second argument.
**
** If no error occurs, SQLITE_OK is returned and the iterator is left
@@ -202780,13 +202780,13 @@ static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){
memset(pIter, 0, sizeof(RbuObjIter));
rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg,
- sqlite3_mprintf(
- "SELECT rbu_target_name(name, type='view') AS target, name "
+ sqlite3_mprintf(
+ "SELECT rbu_target_name(name, type='view') AS target, name "
"FROM sqlite_schema "
- "WHERE type IN ('table', 'view') AND target IS NOT NULL "
- " %s "
- "ORDER BY name"
- , rbuIsVacuum(p) ? "AND rootpage!=0 AND rootpage IS NOT NULL" : ""));
+ "WHERE type IN ('table', 'view') AND target IS NOT NULL "
+ " %s "
+ "ORDER BY name"
+ , rbuIsVacuum(p) ? "AND rootpage!=0 AND rootpage IS NOT NULL" : ""));
if( rc==SQLITE_OK ){
rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg,
@@ -202866,7 +202866,7 @@ static void *rbuMalloc(sqlite3rbu *p, sqlite3_int64 nByte){
void *pRet = 0;
if( p->rc==SQLITE_OK ){
assert( nByte>0 );
- pRet = sqlite3_malloc64(nByte);
+ pRet = sqlite3_malloc64(nByte);
if( pRet==0 ){
p->rc = SQLITE_NOMEM;
}else{
@@ -203055,7 +203055,7 @@ static void rbuTableType(
}
rbuTableType_end: {
- unsigned int i;
+ unsigned int i;
for(i=0; i<sizeof(aStmt)/sizeof(aStmt[0]); i++){
rbuFinalize(p, aStmt[i]);
}
@@ -203077,7 +203077,7 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){
);
}
- pIter->nIndex = 0;
+ pIter->nIndex = 0;
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
int bPartial = sqlite3_column_int(pList, 4);
@@ -203098,14 +203098,14 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){
}
rbuFinalize(p, pXInfo);
bIndex = 1;
- pIter->nIndex++;
+ pIter->nIndex++;
+ }
+
+ if( pIter->eType==RBU_PK_WITHOUT_ROWID ){
+ /* "PRAGMA index_list" includes the main PK b-tree */
+ pIter->nIndex--;
}
- if( pIter->eType==RBU_PK_WITHOUT_ROWID ){
- /* "PRAGMA index_list" includes the main PK b-tree */
- pIter->nIndex--;
- }
-
rbuFinalize(p, pList);
if( bIndex==0 ) pIter->abIndexed = 0;
}
@@ -203148,7 +203148,7 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
** of the input table. Ignore any input table columns that begin with
** "rbu_". */
p->rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
- sqlite3_mprintf("SELECT * FROM '%q'", pIter->zDataTbl)
+ sqlite3_mprintf("SELECT * FROM '%q'", pIter->zDataTbl)
);
if( p->rc==SQLITE_OK ){
nCol = sqlite3_column_count(pStmt);
@@ -203169,12 +203169,12 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
pStmt = 0;
if( p->rc==SQLITE_OK
- && rbuIsVacuum(p)==0
+ && rbuIsVacuum(p)==0
&& bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
){
p->rc = SQLITE_ERROR;
p->zErrmsg = sqlite3_mprintf(
- "table %q %s rbu_rowid column", pIter->zDataTbl,
+ "table %q %s rbu_rowid column", pIter->zDataTbl,
(bRbuRowid ? "may not have" : "requires")
);
}
@@ -203195,8 +203195,8 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
}
if( i==pIter->nTblCol ){
p->rc = SQLITE_ERROR;
- p->zErrmsg = sqlite3_mprintf("column missing from %q: %s",
- pIter->zDataTbl, zName
+ p->zErrmsg = sqlite3_mprintf("column missing from %q: %s",
+ pIter->zDataTbl, zName
);
}else{
int iPk = sqlite3_column_int(pStmt, 5);
@@ -203219,7 +203219,7 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
rbuFinalize(p, pStmt);
rbuObjIterCacheIndexedCols(p, pIter);
assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 );
- assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 );
+ assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 );
}
return p->rc;
@@ -203704,7 +203704,7 @@ static char *rbuObjIterGetSetlist(
if( p->rc==SQLITE_OK ){
int i;
- if( (int)strlen(zMask)!=pIter->nTblCol ){
+ if( (int)strlen(zMask)!=pIter->nTblCol ){
rbuBadControlError(p);
}else{
const char *zSep = "";
@@ -203716,18 +203716,18 @@ static char *rbuObjIterGetSetlist(
);
zSep = ", ";
}
- else if( c=='d' ){
+ else if( c=='d' ){
zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_delta(\"%w\", ?%d)",
zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
);
zSep = ", ";
}
- else if( c=='f' ){
+ else if( c=='f' ){
zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_fossil_delta(\"%w\", ?%d)",
- zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
- );
- zSep = ", ";
- }
+ zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
+ );
+ zSep = ", ";
+ }
}
}
}
@@ -203978,7 +203978,7 @@ static void rbuObjIterPrepareTmpInsert(
p->rc = prepareFreeAndCollectError(
p->dbRbu, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf(
"INSERT INTO %s.'rbu_tmp_%q'(rbu_control,%s%s) VALUES(%z)",
- p->zStateDb, pIter->zDataTbl, zCollist, zRbuRowid, zBind
+ p->zStateDb, pIter->zDataTbl, zCollist, zRbuRowid, zBind
));
}
}
@@ -203992,14 +203992,14 @@ static void rbuTmpInsertFunc(
int rc = SQLITE_OK;
int i;
- assert( sqlite3_value_int(apVal[0])!=0
+ assert( sqlite3_value_int(apVal[0])!=0
|| p->objiter.eType==RBU_PK_EXTERNAL
|| p->objiter.eType==RBU_PK_NONE
- );
- if( sqlite3_value_int(apVal[0])!=0 ){
- p->nPhaseOneStep += p->objiter.nIndex;
- }
-
+ );
+ if( sqlite3_value_int(apVal[0])!=0 ){
+ p->nPhaseOneStep += p->objiter.nIndex;
+ }
+
for(i=0; rc==SQLITE_OK && i<nVal; i++){
rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]);
}
@@ -204166,7 +204166,7 @@ static int rbuObjIterPrepareAll(
}
/* And to delete index entries */
- if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){
+ if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(
p->dbMain, &pIter->pDelete, &p->zErrmsg,
sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere)
@@ -204176,7 +204176,7 @@ static int rbuObjIterPrepareAll(
/* Create the SELECT statement to read keys in sorted order */
if( p->rc==SQLITE_OK ){
char *zSql;
- if( rbuIsVacuum(p) ){
+ if( rbuIsVacuum(p) ){
char *zStart = 0;
if( nOffset ){
zStart = rbuVacuumIndexStart(p, pIter);
@@ -204186,28 +204186,28 @@ static int rbuObjIterPrepareAll(
}
}
- zSql = sqlite3_mprintf(
+ zSql = sqlite3_mprintf(
"SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s",
zCollist,
- pIter->zDataTbl,
+ pIter->zDataTbl,
zPart,
(zStart ? (zPart ? "AND" : "WHERE") : ""), zStart,
- zCollist, zLimit
- );
+ zCollist, zLimit
+ );
sqlite3_free(zStart);
- }else
-
+ }else
+
if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
zSql = sqlite3_mprintf(
"SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s",
- zCollist, p->zStateDb, pIter->zDataTbl,
+ zCollist, p->zStateDb, pIter->zDataTbl,
zPart, zCollist, zLimit
);
}else{
zSql = sqlite3_mprintf(
"SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s "
- "UNION ALL "
- "SELECT %s, rbu_control FROM '%q' "
+ "UNION ALL "
+ "SELECT %s, rbu_control FROM '%q' "
"%s %s typeof(rbu_control)='integer' AND rbu_control!=1 "
"ORDER BY %s%s",
zCollist, p->zStateDb, pIter->zDataTbl, zPart,
@@ -204230,9 +204230,9 @@ static int rbuObjIterPrepareAll(
sqlite3_free(zBind);
sqlite3_free(zPart);
}else{
- int bRbuRowid = (pIter->eType==RBU_PK_VTAB)
- ||(pIter->eType==RBU_PK_NONE)
- ||(pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p));
+ int bRbuRowid = (pIter->eType==RBU_PK_VTAB)
+ ||(pIter->eType==RBU_PK_NONE)
+ ||(pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p));
const char *zTbl = pIter->zTbl; /* Table this step applies to */
const char *zWrite; /* Imposter table name */
@@ -204259,10 +204259,10 @@ static int rbuObjIterPrepareAll(
);
}
- /* Create the DELETE statement to write to the target PK b-tree.
- ** Because it only performs INSERT operations, this is not required for
- ** an rbu vacuum handle. */
- if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){
+ /* Create the DELETE statement to write to the target PK b-tree.
+ ** Because it only performs INSERT operations, this is not required for
+ ** an rbu vacuum handle. */
+ if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz,
sqlite3_mprintf(
"DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere
@@ -204270,7 +204270,7 @@ static int rbuObjIterPrepareAll(
);
}
- if( rbuIsVacuum(p)==0 && pIter->abIndexed ){
+ if( rbuIsVacuum(p)==0 && pIter->abIndexed ){
const char *zRbuRowid = "";
if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
zRbuRowid = ", rbu_rowid";
@@ -204279,26 +204279,26 @@ static int rbuObjIterPrepareAll(
/* Create the rbu_tmp_xxx table and the triggers to populate it. */
rbuMPrintfExec(p, p->dbRbu,
"CREATE TABLE IF NOT EXISTS %s.'rbu_tmp_%q' AS "
- "SELECT *%s FROM '%q' WHERE 0;"
- , p->zStateDb, pIter->zDataTbl
- , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "")
- , pIter->zDataTbl
+ "SELECT *%s FROM '%q' WHERE 0;"
+ , p->zStateDb, pIter->zDataTbl
+ , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "")
+ , pIter->zDataTbl
);
rbuMPrintfExec(p, p->dbMain,
"CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" "
"BEGIN "
- " SELECT rbu_tmp_insert(3, %s);"
+ " SELECT rbu_tmp_insert(3, %s);"
"END;"
"CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" "
"BEGIN "
- " SELECT rbu_tmp_insert(3, %s);"
+ " SELECT rbu_tmp_insert(3, %s);"
"END;"
"CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" "
"BEGIN "
- " SELECT rbu_tmp_insert(4, %s);"
+ " SELECT rbu_tmp_insert(4, %s);"
"END;",
zWrite, zTbl, zOldlist,
zWrite, zTbl, zOldlist,
@@ -204318,14 +204318,14 @@ static int rbuObjIterPrepareAll(
rbuObjIterPrepareTmpInsert(p, pIter, zCollist, zRbuRowid);
}
- /* Create the SELECT statement to read keys from data_xxx */
- if( p->rc==SQLITE_OK ){
- const char *zRbuRowid = "";
+ /* Create the SELECT statement to read keys from data_xxx */
+ if( p->rc==SQLITE_OK ){
+ const char *zRbuRowid = "";
char *zStart = 0;
char *zOrder = 0;
- if( bRbuRowid ){
- zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
- }
+ if( bRbuRowid ){
+ zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
+ }
if( rbuIsVacuum(p) ){
if( nOffset ){
@@ -204357,8 +204357,8 @@ static int rbuObjIterPrepareAll(
}
sqlite3_free(zStart);
sqlite3_free(zOrder);
- }
-
+ }
+
sqlite3_free(zWhere);
sqlite3_free(zOldlist);
sqlite3_free(zNewlist);
@@ -204448,15 +204448,15 @@ static int rbuGetUpdateStmt(
return p->rc;
}
-static sqlite3 *rbuOpenDbhandle(
+static sqlite3 *rbuOpenDbhandle(
sqlite3rbu *p,
const char *zName,
- int bUseVfs
-){
+ int bUseVfs
+){
sqlite3 *db = 0;
if( p->rc==SQLITE_OK ){
const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI;
- p->rc = sqlite3_open_v2(zName, &db, flags, bUseVfs ? p->zVfsName : 0);
+ p->rc = sqlite3_open_v2(zName, &db, flags, bUseVfs ? p->zVfsName : 0);
if( p->rc ){
p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
sqlite3_close(db);
@@ -204467,100 +204467,100 @@ static sqlite3 *rbuOpenDbhandle(
}
/*
-** Free an RbuState object allocated by rbuLoadState().
-*/
-static void rbuFreeState(RbuState *p){
- if( p ){
- sqlite3_free(p->zTbl);
+** Free an RbuState object allocated by rbuLoadState().
+*/
+static void rbuFreeState(RbuState *p){
+ if( p ){
+ sqlite3_free(p->zTbl);
sqlite3_free(p->zDataTbl);
- sqlite3_free(p->zIdx);
- sqlite3_free(p);
- }
-}
-
-/*
+ sqlite3_free(p->zIdx);
+ sqlite3_free(p);
+ }
+}
+
+/*
** Allocate an RbuState object and load the contents of the rbu_state
** table into it. Return a pointer to the new object. It is the
-** responsibility of the caller to eventually free the object using
-** sqlite3_free().
-**
-** If an error occurs, leave an error code and message in the rbu handle
-** and return NULL.
-*/
-static RbuState *rbuLoadState(sqlite3rbu *p){
- RbuState *pRet = 0;
- sqlite3_stmt *pStmt = 0;
- int rc;
- int rc2;
-
- pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState));
- if( pRet==0 ) return 0;
-
+** responsibility of the caller to eventually free the object using
+** sqlite3_free().
+**
+** If an error occurs, leave an error code and message in the rbu handle
+** and return NULL.
+*/
+static RbuState *rbuLoadState(sqlite3rbu *p){
+ RbuState *pRet = 0;
+ sqlite3_stmt *pStmt = 0;
+ int rc;
+ int rc2;
+
+ pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState));
+ if( pRet==0 ) return 0;
+
rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
- sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb)
- );
- while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
- switch( sqlite3_column_int(pStmt, 0) ){
- case RBU_STATE_STAGE:
- pRet->eStage = sqlite3_column_int(pStmt, 1);
- if( pRet->eStage!=RBU_STAGE_OAL
- && pRet->eStage!=RBU_STAGE_MOVE
- && pRet->eStage!=RBU_STAGE_CKPT
- ){
- p->rc = SQLITE_CORRUPT;
- }
- break;
-
- case RBU_STATE_TBL:
- pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
- break;
-
- case RBU_STATE_IDX:
- pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
- break;
-
- case RBU_STATE_ROW:
- pRet->nRow = sqlite3_column_int(pStmt, 1);
- break;
-
- case RBU_STATE_PROGRESS:
- pRet->nProgress = sqlite3_column_int64(pStmt, 1);
- break;
-
- case RBU_STATE_CKPT:
- pRet->iWalCksum = sqlite3_column_int64(pStmt, 1);
- break;
-
- case RBU_STATE_COOKIE:
- pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
- break;
-
- case RBU_STATE_OALSZ:
+ sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb)
+ );
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
+ switch( sqlite3_column_int(pStmt, 0) ){
+ case RBU_STATE_STAGE:
+ pRet->eStage = sqlite3_column_int(pStmt, 1);
+ if( pRet->eStage!=RBU_STAGE_OAL
+ && pRet->eStage!=RBU_STAGE_MOVE
+ && pRet->eStage!=RBU_STAGE_CKPT
+ ){
+ p->rc = SQLITE_CORRUPT;
+ }
+ break;
+
+ case RBU_STATE_TBL:
+ pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
+ break;
+
+ case RBU_STATE_IDX:
+ pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
+ break;
+
+ case RBU_STATE_ROW:
+ pRet->nRow = sqlite3_column_int(pStmt, 1);
+ break;
+
+ case RBU_STATE_PROGRESS:
+ pRet->nProgress = sqlite3_column_int64(pStmt, 1);
+ break;
+
+ case RBU_STATE_CKPT:
+ pRet->iWalCksum = sqlite3_column_int64(pStmt, 1);
+ break;
+
+ case RBU_STATE_COOKIE:
+ pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
+ break;
+
+ case RBU_STATE_OALSZ:
pRet->iOalSz = sqlite3_column_int64(pStmt, 1);
- break;
-
- case RBU_STATE_PHASEONESTEP:
- pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1);
- break;
-
+ break;
+
+ case RBU_STATE_PHASEONESTEP:
+ pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1);
+ break;
+
case RBU_STATE_DATATBL:
pRet->zDataTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
break;
- default:
- rc = SQLITE_CORRUPT;
- break;
- }
- }
- rc2 = sqlite3_finalize(pStmt);
- if( rc==SQLITE_OK ) rc = rc2;
-
- p->rc = rc;
- return pRet;
-}
-
-
-/*
+ default:
+ rc = SQLITE_CORRUPT;
+ break;
+ }
+ }
+ rc2 = sqlite3_finalize(pStmt);
+ if( rc==SQLITE_OK ) rc = rc2;
+
+ p->rc = rc;
+ return pRet;
+}
+
+
+/*
** Open the database handle and attach the RBU database as "rbu". If an
** error occurs, leave an error code and message in the RBU handle.
**
@@ -204569,22 +204569,22 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
** one.
*/
static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){
- assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
- assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
+ assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
+ assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
assert( dbMain==0 || rbuIsVacuum(p)==0 );
- /* Open the RBU database */
- p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
+ /* Open the RBU database */
+ p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
p->dbMain = dbMain;
- if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
- sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
- if( p->zState==0 ){
- const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
- p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile);
- }
- }
-
+ if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
+ sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
+ if( p->zState==0 ){
+ const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
+ p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile);
+ }
+ }
+
/* If using separate RBU and state databases, attach the state database to
** the RBU db handle now. */
if( p->zState ){
@@ -204594,105 +204594,105 @@ static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){
memcpy(p->zStateDb, "main", 4);
}
-#if 0
- if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
- p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, 0);
- }
-#endif
-
- /* If it has not already been created, create the rbu_state table */
- rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb);
-
-#if 0
- if( rbuIsVacuum(p) ){
- if( p->rc==SQLITE_OK ){
- int rc2;
- int bOk = 0;
- sqlite3_stmt *pCnt = 0;
- p->rc = prepareAndCollectError(p->dbRbu, &pCnt, &p->zErrmsg,
+#if 0
+ if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
+ p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, 0);
+ }
+#endif
+
+ /* If it has not already been created, create the rbu_state table */
+ rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb);
+
+#if 0
+ if( rbuIsVacuum(p) ){
+ if( p->rc==SQLITE_OK ){
+ int rc2;
+ int bOk = 0;
+ sqlite3_stmt *pCnt = 0;
+ p->rc = prepareAndCollectError(p->dbRbu, &pCnt, &p->zErrmsg,
"SELECT count(*) FROM stat.sqlite_schema"
- );
+ );
if( p->rc==SQLITE_OK
- && sqlite3_step(pCnt)==SQLITE_ROW
- && 1==sqlite3_column_int(pCnt, 0)
- ){
- bOk = 1;
- }
- rc2 = sqlite3_finalize(pCnt);
- if( p->rc==SQLITE_OK ) p->rc = rc2;
-
- if( p->rc==SQLITE_OK && bOk==0 ){
- p->rc = SQLITE_ERROR;
- p->zErrmsg = sqlite3_mprintf("invalid state database");
- }
-
- if( p->rc==SQLITE_OK ){
- p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
- }
- }
- }
-#endif
-
- if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
- int bOpen = 0;
- int rc;
- p->nRbu = 0;
- p->pRbuFd = 0;
- rc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
- if( rc!=SQLITE_NOTFOUND ) p->rc = rc;
- if( p->eStage>=RBU_STAGE_MOVE ){
- bOpen = 1;
- }else{
- RbuState *pState = rbuLoadState(p);
- if( pState ){
- bOpen = (pState->eStage>=RBU_STAGE_MOVE);
- rbuFreeState(pState);
- }
- }
- if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, p->nRbu<=1);
- }
-
- p->eStage = 0;
- if( p->rc==SQLITE_OK && p->dbMain==0 ){
- if( !rbuIsVacuum(p) ){
- p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
- }else if( p->pRbuFd->pWalFd ){
- if( pbRetry ){
- p->pRbuFd->bNolock = 0;
- sqlite3_close(p->dbRbu);
- sqlite3_close(p->dbMain);
- p->dbMain = 0;
- p->dbRbu = 0;
- *pbRetry = 1;
- return;
- }
- p->rc = SQLITE_ERROR;
- p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database");
- }else{
- char *zTarget;
- char *zExtra = 0;
- if( strlen(p->zRbu)>=5 && 0==memcmp("file:", p->zRbu, 5) ){
- zExtra = &p->zRbu[5];
- while( *zExtra ){
- if( *zExtra++=='?' ) break;
- }
- if( *zExtra=='\0' ) zExtra = 0;
- }
-
+ && sqlite3_step(pCnt)==SQLITE_ROW
+ && 1==sqlite3_column_int(pCnt, 0)
+ ){
+ bOk = 1;
+ }
+ rc2 = sqlite3_finalize(pCnt);
+ if( p->rc==SQLITE_OK ) p->rc = rc2;
+
+ if( p->rc==SQLITE_OK && bOk==0 ){
+ p->rc = SQLITE_ERROR;
+ p->zErrmsg = sqlite3_mprintf("invalid state database");
+ }
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
+ }
+ }
+ }
+#endif
+
+ if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
+ int bOpen = 0;
+ int rc;
+ p->nRbu = 0;
+ p->pRbuFd = 0;
+ rc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
+ if( rc!=SQLITE_NOTFOUND ) p->rc = rc;
+ if( p->eStage>=RBU_STAGE_MOVE ){
+ bOpen = 1;
+ }else{
+ RbuState *pState = rbuLoadState(p);
+ if( pState ){
+ bOpen = (pState->eStage>=RBU_STAGE_MOVE);
+ rbuFreeState(pState);
+ }
+ }
+ if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, p->nRbu<=1);
+ }
+
+ p->eStage = 0;
+ if( p->rc==SQLITE_OK && p->dbMain==0 ){
+ if( !rbuIsVacuum(p) ){
+ p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
+ }else if( p->pRbuFd->pWalFd ){
+ if( pbRetry ){
+ p->pRbuFd->bNolock = 0;
+ sqlite3_close(p->dbRbu);
+ sqlite3_close(p->dbMain);
+ p->dbMain = 0;
+ p->dbRbu = 0;
+ *pbRetry = 1;
+ return;
+ }
+ p->rc = SQLITE_ERROR;
+ p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database");
+ }else{
+ char *zTarget;
+ char *zExtra = 0;
+ if( strlen(p->zRbu)>=5 && 0==memcmp("file:", p->zRbu, 5) ){
+ zExtra = &p->zRbu[5];
+ while( *zExtra ){
+ if( *zExtra++=='?' ) break;
+ }
+ if( *zExtra=='\0' ) zExtra = 0;
+ }
+
zTarget = sqlite3_mprintf("file:%s-vactmp?rbu_memory=1%s%s",
- sqlite3_db_filename(p->dbRbu, "main"),
- (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra)
- );
-
- if( zTarget==0 ){
- p->rc = SQLITE_NOMEM;
- return;
- }
- p->dbMain = rbuOpenDbhandle(p, zTarget, p->nRbu<=1);
- sqlite3_free(zTarget);
- }
- }
-
+ sqlite3_db_filename(p->dbRbu, "main"),
+ (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra)
+ );
+
+ if( zTarget==0 ){
+ p->rc = SQLITE_NOMEM;
+ return;
+ }
+ p->dbMain = rbuOpenDbhandle(p, zTarget, p->nRbu<=1);
+ sqlite3_free(zTarget);
+ }
+ }
+
if( p->rc==SQLITE_OK ){
p->rc = sqlite3_create_function(p->dbMain,
"rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0
@@ -204701,17 +204701,17 @@ static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){
if( p->rc==SQLITE_OK ){
p->rc = sqlite3_create_function(p->dbMain,
- "rbu_fossil_delta", 2, SQLITE_UTF8, 0, rbuFossilDeltaFunc, 0, 0
- );
- }
-
- if( p->rc==SQLITE_OK ){
+ "rbu_fossil_delta", 2, SQLITE_UTF8, 0, rbuFossilDeltaFunc, 0, 0
+ );
+ }
+
+ if( p->rc==SQLITE_OK ){
p->rc = sqlite3_create_function(p->dbRbu,
- "rbu_target_name", -1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0
- );
- }
-
- if( p->rc==SQLITE_OK ){
+ "rbu_target_name", -1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0
+ );
+ }
+
+ if( p->rc==SQLITE_OK ){
p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p);
}
rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_schema");
@@ -204756,9 +204756,9 @@ static void rbuFileSuffix3(const char *zBase, char *z){
#endif
{
int i, sz;
- sz = (int)strlen(z)&0xffffff;
+ sz = (int)strlen(z)&0xffffff;
for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
- if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
+ if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
}
#endif
}
@@ -204846,35 +204846,35 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
if( rc2!=SQLITE_INTERNAL ) p->rc = rc2;
}
- if( p->rc==SQLITE_OK && p->nFrame>0 ){
+ if( p->rc==SQLITE_OK && p->nFrame>0 ){
p->eStage = RBU_STAGE_CKPT;
p->nStep = (pState ? pState->nRow : 0);
p->aBuf = rbuMalloc(p, p->pgsz);
p->iWalCksum = rbuShmChecksum(p);
}
- if( p->rc==SQLITE_OK ){
- if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){
- p->rc = SQLITE_DONE;
- p->eStage = RBU_STAGE_DONE;
- }else{
- int nSectorSize;
- sqlite3_file *pDb = p->pTargetFd->pReal;
- sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
- assert( p->nPagePerSector==0 );
- nSectorSize = pDb->pMethods->xSectorSize(pDb);
- if( nSectorSize>p->pgsz ){
- p->nPagePerSector = nSectorSize / p->pgsz;
- }else{
- p->nPagePerSector = 1;
- }
-
+ if( p->rc==SQLITE_OK ){
+ if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){
+ p->rc = SQLITE_DONE;
+ p->eStage = RBU_STAGE_DONE;
+ }else{
+ int nSectorSize;
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+ sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
+ assert( p->nPagePerSector==0 );
+ nSectorSize = pDb->pMethods->xSectorSize(pDb);
+ if( nSectorSize>p->pgsz ){
+ p->nPagePerSector = nSectorSize / p->pgsz;
+ }else{
+ p->nPagePerSector = 1;
+ }
+
/* Call xSync() on the wal file. This causes SQLite to sync the
** directory in which the target database and the wal file reside, in
** case it has not been synced since the rename() call in
- ** rbuMoveOalFile(). */
- p->rc = pWal->pMethods->xSync(pWal, SQLITE_SYNC_NORMAL);
- }
+ ** rbuMoveOalFile(). */
+ p->rc = pWal->pMethods->xSync(pWal, SQLITE_SYNC_NORMAL);
+ }
}
}
@@ -204896,7 +204896,7 @@ static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){
if( pRbu->nFrame==pRbu->nFrameAlloc ){
int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2;
RbuFrame *aNew;
- aNew = (RbuFrame*)sqlite3_realloc64(pRbu->aFrame, nNew * sizeof(RbuFrame));
+ aNew = (RbuFrame*)sqlite3_realloc64(pRbu->aFrame, nNew * sizeof(RbuFrame));
if( aNew==0 ) return SQLITE_NOMEM;
pRbu->aFrame = aNew;
pRbu->nFrameAlloc = nNew;
@@ -204968,30 +204968,30 @@ static int rbuExclusiveCheckpoint(sqlite3 *db){
return sqlite3_uri_boolean(zUri, RBU_EXCLUSIVE_CHECKPOINT, 0);
}
-#if defined(_WIN32_WCE)
-static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
- int nChar;
- LPWSTR zWideFilename;
-
- nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
- if( nChar==0 ){
- return 0;
- }
- zWideFilename = sqlite3_malloc64( nChar*sizeof(zWideFilename[0]) );
- if( zWideFilename==0 ){
- return 0;
- }
- memset(zWideFilename, 0, nChar*sizeof(zWideFilename[0]));
- nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
- nChar);
- if( nChar==0 ){
- sqlite3_free(zWideFilename);
- zWideFilename = 0;
- }
- return zWideFilename;
-}
-#endif
-
+#if defined(_WIN32_WCE)
+static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
+ int nChar;
+ LPWSTR zWideFilename;
+
+ nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
+ if( nChar==0 ){
+ return 0;
+ }
+ zWideFilename = sqlite3_malloc64( nChar*sizeof(zWideFilename[0]) );
+ if( zWideFilename==0 ){
+ return 0;
+ }
+ memset(zWideFilename, 0, nChar*sizeof(zWideFilename[0]));
+ nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
+ nChar);
+ if( nChar==0 ){
+ sqlite3_free(zWideFilename);
+ zWideFilename = 0;
+ }
+ return zWideFilename;
+}
+#endif
+
/*
** The RBU handle is currently in RBU_STAGE_OAL state, with a SHARED lock
** on the database file. This proc moves the *-oal file to the *-wal path,
@@ -205001,15 +205001,15 @@ static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
*/
static void rbuMoveOalFile(sqlite3rbu *p){
const char *zBase = sqlite3_db_filename(p->dbMain, "main");
- const char *zMove = zBase;
- char *zOal;
- char *zWal;
+ const char *zMove = zBase;
+ char *zOal;
+ char *zWal;
- if( rbuIsVacuum(p) ){
- zMove = sqlite3_db_filename(p->dbRbu, "main");
- }
- zOal = sqlite3_mprintf("%s-oal", zMove);
- zWal = sqlite3_mprintf("%s-wal", zMove);
+ if( rbuIsVacuum(p) ){
+ zMove = sqlite3_db_filename(p->dbRbu, "main");
+ }
+ zOal = sqlite3_mprintf("%s-oal", zMove);
+ zWal = sqlite3_mprintf("%s-wal", zMove);
assert( p->eStage==RBU_STAGE_MOVE );
assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
@@ -205033,7 +205033,7 @@ static void rbuMoveOalFile(sqlite3rbu *p){
sqlite3_close(p->dbMain);
p->dbMain = 0;
p->dbRbu = 0;
-
+
dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
if( dbMain ){
assert( p->rc==SQLITE_OK );
@@ -205041,34 +205041,34 @@ static void rbuMoveOalFile(sqlite3rbu *p){
}
if( p->rc==SQLITE_OK ){
-#if defined(_WIN32_WCE)
- {
- LPWSTR zWideOal;
- LPWSTR zWideWal;
-
- zWideOal = rbuWinUtf8ToUnicode(zOal);
- if( zWideOal ){
- zWideWal = rbuWinUtf8ToUnicode(zWal);
- if( zWideWal ){
- if( MoveFileW(zWideOal, zWideWal) ){
- p->rc = SQLITE_OK;
- }else{
- p->rc = SQLITE_IOERR;
- }
- sqlite3_free(zWideWal);
- }else{
- p->rc = SQLITE_IOERR_NOMEM;
- }
- sqlite3_free(zWideOal);
- }else{
- p->rc = SQLITE_IOERR_NOMEM;
- }
- }
-#else
+#if defined(_WIN32_WCE)
+ {
+ LPWSTR zWideOal;
+ LPWSTR zWideWal;
+
+ zWideOal = rbuWinUtf8ToUnicode(zOal);
+ if( zWideOal ){
+ zWideWal = rbuWinUtf8ToUnicode(zWal);
+ if( zWideWal ){
+ if( MoveFileW(zWideOal, zWideWal) ){
+ p->rc = SQLITE_OK;
+ }else{
+ p->rc = SQLITE_IOERR;
+ }
+ sqlite3_free(zWideWal);
+ }else{
+ p->rc = SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_free(zWideOal);
+ }else{
+ p->rc = SQLITE_IOERR_NOMEM;
+ }
+ }
+#else
p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
-#endif
+#endif
}
-
+
if( p->rc!=SQLITE_OK
|| rbuIsVacuum(p)
|| rbuExclusiveCheckpoint(dbMain)==0
@@ -205111,12 +205111,12 @@ static int rbuStepType(sqlite3rbu *p, const char **pzMask){
switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){
case SQLITE_INTEGER: {
int iVal = sqlite3_column_int(p->objiter.pSelect, iCol);
- switch( iVal ){
- case 0: res = RBU_INSERT; break;
- case 1: res = RBU_DELETE; break;
- case 2: res = RBU_REPLACE; break;
- case 3: res = RBU_IDX_DELETE; break;
- case 4: res = RBU_IDX_INSERT; break;
+ switch( iVal ){
+ case 0: res = RBU_INSERT; break;
+ case 1: res = RBU_DELETE; break;
+ case 2: res = RBU_REPLACE; break;
+ case 3: res = RBU_IDX_DELETE; break;
+ case 4: res = RBU_IDX_INSERT; break;
}
break;
}
@@ -205156,83 +205156,83 @@ static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){
#endif
/*
-** Argument eType must be one of RBU_INSERT, RBU_DELETE, RBU_IDX_INSERT or
-** RBU_IDX_DELETE. This function performs the work of a single
-** sqlite3rbu_step() call for the type of operation specified by eType.
-*/
-static void rbuStepOneOp(sqlite3rbu *p, int eType){
- RbuObjIter *pIter = &p->objiter;
- sqlite3_value *pVal;
- sqlite3_stmt *pWriter;
- int i;
-
- assert( p->rc==SQLITE_OK );
- assert( eType!=RBU_DELETE || pIter->zIdx==0 );
- assert( eType==RBU_DELETE || eType==RBU_IDX_DELETE
- || eType==RBU_INSERT || eType==RBU_IDX_INSERT
- );
-
- /* If this is a delete, decrement nPhaseOneStep by nIndex. If the DELETE
- ** statement below does actually delete a row, nPhaseOneStep will be
- ** incremented by the same amount when SQL function rbu_tmp_insert()
- ** is invoked by the trigger. */
- if( eType==RBU_DELETE ){
- p->nPhaseOneStep -= p->objiter.nIndex;
- }
-
- if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){
- pWriter = pIter->pDelete;
- }else{
- pWriter = pIter->pInsert;
- }
-
- for(i=0; i<pIter->nCol; i++){
- /* If this is an INSERT into a table b-tree and the table has an
- ** explicit INTEGER PRIMARY KEY, check that this is not an attempt
- ** to write a NULL into the IPK column. That is not permitted. */
+** Argument eType must be one of RBU_INSERT, RBU_DELETE, RBU_IDX_INSERT or
+** RBU_IDX_DELETE. This function performs the work of a single
+** sqlite3rbu_step() call for the type of operation specified by eType.
+*/
+static void rbuStepOneOp(sqlite3rbu *p, int eType){
+ RbuObjIter *pIter = &p->objiter;
+ sqlite3_value *pVal;
+ sqlite3_stmt *pWriter;
+ int i;
+
+ assert( p->rc==SQLITE_OK );
+ assert( eType!=RBU_DELETE || pIter->zIdx==0 );
+ assert( eType==RBU_DELETE || eType==RBU_IDX_DELETE
+ || eType==RBU_INSERT || eType==RBU_IDX_INSERT
+ );
+
+ /* If this is a delete, decrement nPhaseOneStep by nIndex. If the DELETE
+ ** statement below does actually delete a row, nPhaseOneStep will be
+ ** incremented by the same amount when SQL function rbu_tmp_insert()
+ ** is invoked by the trigger. */
+ if( eType==RBU_DELETE ){
+ p->nPhaseOneStep -= p->objiter.nIndex;
+ }
+
+ if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){
+ pWriter = pIter->pDelete;
+ }else{
+ pWriter = pIter->pInsert;
+ }
+
+ for(i=0; i<pIter->nCol; i++){
+ /* If this is an INSERT into a table b-tree and the table has an
+ ** explicit INTEGER PRIMARY KEY, check that this is not an attempt
+ ** to write a NULL into the IPK column. That is not permitted. */
if( eType==RBU_INSERT
&& pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i]
- && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
- ){
- p->rc = SQLITE_MISMATCH;
- p->zErrmsg = sqlite3_mprintf("datatype mismatch");
- return;
- }
-
- if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){
- continue;
- }
-
- pVal = sqlite3_column_value(pIter->pSelect, i);
- p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
- if( p->rc ) return;
- }
- if( pIter->zIdx==0 ){
+ && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
+ ){
+ p->rc = SQLITE_MISMATCH;
+ p->zErrmsg = sqlite3_mprintf("datatype mismatch");
+ return;
+ }
+
+ if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){
+ continue;
+ }
+
+ pVal = sqlite3_column_value(pIter->pSelect, i);
+ p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
+ if( p->rc ) return;
+ }
+ if( pIter->zIdx==0 ){
if( pIter->eType==RBU_PK_VTAB
|| pIter->eType==RBU_PK_NONE
|| (pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p))
- ){
+ ){
/* For a virtual table, or a table with no primary key, the
- ** SELECT statement is:
- **
- ** SELECT <cols>, rbu_control, rbu_rowid FROM ....
- **
- ** Hence column_value(pIter->nCol+1).
- */
+ ** SELECT statement is:
+ **
+ ** SELECT <cols>, rbu_control, rbu_rowid FROM ....
+ **
+ ** Hence column_value(pIter->nCol+1).
+ */
assertColumnName(pIter->pSelect, pIter->nCol+1,
- rbuIsVacuum(p) ? "rowid" : "rbu_rowid"
- );
- pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
- p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
- }
- }
- if( p->rc==SQLITE_OK ){
- sqlite3_step(pWriter);
- p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
- }
-}
-
-/*
+ rbuIsVacuum(p) ? "rowid" : "rbu_rowid"
+ );
+ pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
+ p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
+ }
+ }
+ if( p->rc==SQLITE_OK ){
+ sqlite3_step(pWriter);
+ p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
+ }
+}
+
+/*
** This function does the work for an sqlite3rbu_step() call.
**
** The object-iterator (p->objiter) currently points to a valid object,
@@ -205249,37 +205249,37 @@ static int rbuStep(sqlite3rbu *p){
int eType = rbuStepType(p, &zMask);
if( eType ){
- assert( eType==RBU_INSERT || eType==RBU_DELETE
- || eType==RBU_REPLACE || eType==RBU_IDX_DELETE
- || eType==RBU_IDX_INSERT || eType==RBU_UPDATE
- );
+ assert( eType==RBU_INSERT || eType==RBU_DELETE
+ || eType==RBU_REPLACE || eType==RBU_IDX_DELETE
+ || eType==RBU_IDX_INSERT || eType==RBU_UPDATE
+ );
assert( eType!=RBU_UPDATE || pIter->zIdx==0 );
- if( pIter->zIdx==0 && (eType==RBU_IDX_DELETE || eType==RBU_IDX_INSERT) ){
+ if( pIter->zIdx==0 && (eType==RBU_IDX_DELETE || eType==RBU_IDX_INSERT) ){
rbuBadControlError(p);
}
- else if( eType==RBU_REPLACE ){
- if( pIter->zIdx==0 ){
- p->nPhaseOneStep += p->objiter.nIndex;
- rbuStepOneOp(p, RBU_DELETE);
- }
- if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT);
- }
- else if( eType!=RBU_UPDATE ){
- rbuStepOneOp(p, eType);
- }
- else{
+ else if( eType==RBU_REPLACE ){
+ if( pIter->zIdx==0 ){
+ p->nPhaseOneStep += p->objiter.nIndex;
+ rbuStepOneOp(p, RBU_DELETE);
+ }
+ if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT);
+ }
+ else if( eType!=RBU_UPDATE ){
+ rbuStepOneOp(p, eType);
+ }
+ else{
sqlite3_value *pVal;
sqlite3_stmt *pUpdate = 0;
assert( eType==RBU_UPDATE );
- p->nPhaseOneStep -= p->objiter.nIndex;
+ p->nPhaseOneStep -= p->objiter.nIndex;
rbuGetUpdateStmt(p, pIter, zMask, &pUpdate);
if( pUpdate ){
- int i;
+ int i;
for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){
char c = zMask[pIter->aiSrcOrder[i]];
pVal = sqlite3_column_value(pIter->pSelect, i);
- if( pIter->abTblPk[i] || c!='.' ){
+ if( pIter->abTblPk[i] || c!='.' ){
p->rc = sqlite3_bind_value(pUpdate, i+1, pVal);
}
}
@@ -205303,14 +205303,14 @@ static int rbuStep(sqlite3rbu *p){
/*
** Increment the schema cookie of the main database opened by p->dbMain.
-**
-** Or, if this is an RBU vacuum, set the schema cookie of the main db
-** opened by p->dbMain to one more than the schema cookie of the main
-** db opened by p->dbRbu.
+**
+** Or, if this is an RBU vacuum, set the schema cookie of the main db
+** opened by p->dbMain to one more than the schema cookie of the main
+** db opened by p->dbRbu.
*/
static void rbuIncrSchemaCookie(sqlite3rbu *p){
if( p->rc==SQLITE_OK ){
- sqlite3 *dbread = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
+ sqlite3 *dbread = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
int iCookie = 1000000;
sqlite3_stmt *pStmt;
@@ -205342,7 +205342,7 @@ static void rbuIncrSchemaCookie(sqlite3rbu *p){
static void rbuSaveState(sqlite3rbu *p, int eStage){
if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){
sqlite3_stmt *pInsert = 0;
- rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
+ rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
int rc;
assert( p->zErrmsg==0 );
@@ -205356,7 +205356,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
"(%d, %d), "
"(%d, %lld), "
"(%d, %lld), "
- "(%d, %lld), "
+ "(%d, %lld), "
"(%d, %lld), "
"(%d, %Q) ",
p->zStateDb,
@@ -205366,8 +205366,8 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
RBU_STATE_ROW, p->nStep,
RBU_STATE_PROGRESS, p->nProgress,
RBU_STATE_CKPT, p->iWalCksum,
- RBU_STATE_COOKIE, (i64)pFd->iCookie,
- RBU_STATE_OALSZ, p->iOalSz,
+ RBU_STATE_COOKIE, (i64)pFd->iCookie,
+ RBU_STATE_OALSZ, p->iOalSz,
RBU_STATE_PHASEONESTEP, p->nPhaseOneStep,
RBU_STATE_DATATBL, p->objiter.zDataTbl
)
@@ -205385,116 +205385,116 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
/*
** The second argument passed to this function is the name of a PRAGMA
-** setting - "page_size", "auto_vacuum", "user_version" or "application_id".
-** This function executes the following on sqlite3rbu.dbRbu:
-**
-** "PRAGMA main.$zPragma"
-**
-** where $zPragma is the string passed as the second argument, then
-** on sqlite3rbu.dbMain:
-**
-** "PRAGMA main.$zPragma = $val"
-**
-** where $val is the value returned by the first PRAGMA invocation.
-**
-** In short, it copies the value of the specified PRAGMA setting from
-** dbRbu to dbMain.
-*/
-static void rbuCopyPragma(sqlite3rbu *p, const char *zPragma){
- if( p->rc==SQLITE_OK ){
- sqlite3_stmt *pPragma = 0;
+** setting - "page_size", "auto_vacuum", "user_version" or "application_id".
+** This function executes the following on sqlite3rbu.dbRbu:
+**
+** "PRAGMA main.$zPragma"
+**
+** where $zPragma is the string passed as the second argument, then
+** on sqlite3rbu.dbMain:
+**
+** "PRAGMA main.$zPragma = $val"
+**
+** where $val is the value returned by the first PRAGMA invocation.
+**
+** In short, it copies the value of the specified PRAGMA setting from
+** dbRbu to dbMain.
+*/
+static void rbuCopyPragma(sqlite3rbu *p, const char *zPragma){
+ if( p->rc==SQLITE_OK ){
+ sqlite3_stmt *pPragma = 0;
p->rc = prepareFreeAndCollectError(p->dbRbu, &pPragma, &p->zErrmsg,
- sqlite3_mprintf("PRAGMA main.%s", zPragma)
- );
- if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPragma) ){
- p->rc = rbuMPrintfExec(p, p->dbMain, "PRAGMA main.%s = %d",
- zPragma, sqlite3_column_int(pPragma, 0)
- );
- }
- rbuFinalize(p, pPragma);
- }
-}
-
-/*
+ sqlite3_mprintf("PRAGMA main.%s", zPragma)
+ );
+ if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPragma) ){
+ p->rc = rbuMPrintfExec(p, p->dbMain, "PRAGMA main.%s = %d",
+ zPragma, sqlite3_column_int(pPragma, 0)
+ );
+ }
+ rbuFinalize(p, pPragma);
+ }
+}
+
+/*
** The RBU handle passed as the only argument has just been opened and
-** the state database is empty. If this RBU handle was opened for an
-** RBU vacuum operation, create the schema in the target db.
-*/
-static void rbuCreateTargetSchema(sqlite3rbu *p){
- sqlite3_stmt *pSql = 0;
- sqlite3_stmt *pInsert = 0;
-
- assert( rbuIsVacuum(p) );
- p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg);
- if( p->rc==SQLITE_OK ){
+** the state database is empty. If this RBU handle was opened for an
+** RBU vacuum operation, create the schema in the target db.
+*/
+static void rbuCreateTargetSchema(sqlite3rbu *p){
+ sqlite3_stmt *pSql = 0;
+ sqlite3_stmt *pInsert = 0;
+
+ assert( rbuIsVacuum(p) );
+ p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg);
+ if( p->rc==SQLITE_OK ){
p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg,
"SELECT sql FROM sqlite_schema WHERE sql!='' AND rootpage!=0"
- " AND name!='sqlite_sequence' "
- " ORDER BY type DESC"
- );
- }
-
- while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
- const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
- p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg);
- }
- rbuFinalize(p, pSql);
- if( p->rc!=SQLITE_OK ) return;
-
- if( p->rc==SQLITE_OK ){
+ " AND name!='sqlite_sequence' "
+ " ORDER BY type DESC"
+ );
+ }
+
+ while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
+ const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
+ p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg);
+ }
+ rbuFinalize(p, pSql);
+ if( p->rc!=SQLITE_OK ) return;
+
+ if( p->rc==SQLITE_OK ){
p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg,
"SELECT * FROM sqlite_schema WHERE rootpage=0 OR rootpage IS NULL"
- );
- }
-
- if( p->rc==SQLITE_OK ){
+ );
+ }
+
+ if( p->rc==SQLITE_OK ){
p->rc = prepareAndCollectError(p->dbMain, &pInsert, &p->zErrmsg,
"INSERT INTO sqlite_schema VALUES(?,?,?,?,?)"
- );
- }
-
- while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
- int i;
- for(i=0; i<5; i++){
- sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i));
- }
- sqlite3_step(pInsert);
- p->rc = sqlite3_reset(pInsert);
- }
- if( p->rc==SQLITE_OK ){
- p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg);
- }
-
- rbuFinalize(p, pSql);
- rbuFinalize(p, pInsert);
-}
-
-/*
+ );
+ }
+
+ while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
+ int i;
+ for(i=0; i<5; i++){
+ sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i));
+ }
+ sqlite3_step(pInsert);
+ p->rc = sqlite3_reset(pInsert);
+ }
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg);
+ }
+
+ rbuFinalize(p, pSql);
+ rbuFinalize(p, pInsert);
+}
+
+/*
** Step the RBU object.
*/
-SQLITE_API int sqlite3rbu_step(sqlite3rbu *p){
+SQLITE_API int sqlite3rbu_step(sqlite3rbu *p){
if( p ){
switch( p->eStage ){
case RBU_STAGE_OAL: {
RbuObjIter *pIter = &p->objiter;
-
- /* If this is an RBU vacuum operation and the state table was empty
- ** when this handle was opened, create the target database schema. */
- if( rbuIsVacuum(p) && p->nProgress==0 && p->rc==SQLITE_OK ){
- rbuCreateTargetSchema(p);
- rbuCopyPragma(p, "user_version");
- rbuCopyPragma(p, "application_id");
- }
-
+
+ /* If this is an RBU vacuum operation and the state table was empty
+ ** when this handle was opened, create the target database schema. */
+ if( rbuIsVacuum(p) && p->nProgress==0 && p->rc==SQLITE_OK ){
+ rbuCreateTargetSchema(p);
+ rbuCopyPragma(p, "user_version");
+ rbuCopyPragma(p, "application_id");
+ }
+
while( p->rc==SQLITE_OK && pIter->zTbl ){
if( pIter->bCleanup ){
/* Clean up the rbu_tmp_xxx table for the previous table. It
** cannot be dropped as there are currently active SQL statements.
** But the contents can be deleted. */
- if( rbuIsVacuum(p)==0 && pIter->abIndexed ){
+ if( rbuIsVacuum(p)==0 && pIter->abIndexed ){
rbuMPrintfExec(p, p->dbRbu,
- "DELETE FROM %s.'rbu_tmp_%q'", p->zStateDb, pIter->zDataTbl
+ "DELETE FROM %s.'rbu_tmp_%q'", p->zStateDb, pIter->zDataTbl
);
}
}else{
@@ -205561,26 +205561,26 @@ SQLITE_API int sqlite3rbu_step(sqlite3rbu *p){
p->rc = SQLITE_DONE;
}
}else{
- /* At one point the following block copied a single frame from the
- ** wal file to the database file. So that one call to sqlite3rbu_step()
+ /* At one point the following block copied a single frame from the
+ ** wal file to the database file. So that one call to sqlite3rbu_step()
** checkpointed a single frame.
- **
- ** However, if the sector-size is larger than the page-size, and the
- ** application calls sqlite3rbu_savestate() or close() immediately
- ** after this step, then rbu_step() again, then a power failure occurs,
- ** then the database page written here may be damaged. Work around
- ** this by checkpointing frames until the next page in the aFrame[]
- ** lies on a different disk sector to the current one. */
- u32 iSector;
- do{
- RbuFrame *pFrame = &p->aFrame[p->nStep];
- iSector = (pFrame->iDbPage-1) / p->nPagePerSector;
- rbuCheckpointFrame(p, pFrame);
- p->nStep++;
+ **
+ ** However, if the sector-size is larger than the page-size, and the
+ ** application calls sqlite3rbu_savestate() or close() immediately
+ ** after this step, then rbu_step() again, then a power failure occurs,
+ ** then the database page written here may be damaged. Work around
+ ** this by checkpointing frames until the next page in the aFrame[]
+ ** lies on a different disk sector to the current one. */
+ u32 iSector;
+ do{
+ RbuFrame *pFrame = &p->aFrame[p->nStep];
+ iSector = (pFrame->iDbPage-1) / p->nPagePerSector;
+ rbuCheckpointFrame(p, pFrame);
+ p->nStep++;
}while( p->nStep<p->nFrame
- && iSector==((p->aFrame[p->nStep].iDbPage-1) / p->nPagePerSector)
- && p->rc==SQLITE_OK
- );
+ && iSector==((p->aFrame[p->nStep].iDbPage-1) / p->nPagePerSector)
+ && p->rc==SQLITE_OK
+ );
}
p->nProgress++;
}
@@ -205651,13 +205651,13 @@ static void rbuSetupOal(sqlite3rbu *p, RbuState *pState){
** leave an error code and error message in the rbu handle.
*/
static void rbuDeleteOalFile(sqlite3rbu *p){
- char *zOal = rbuMPrintf(p, "%s-oal", p->zTarget);
- if( zOal ){
- sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
- assert( pVfs && p->rc==SQLITE_OK && p->zErrmsg==0 );
- pVfs->xDelete(pVfs, zOal, 0);
- sqlite3_free(zOal);
- }
+ char *zOal = rbuMPrintf(p, "%s-oal", p->zTarget);
+ if( zOal ){
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
+ assert( pVfs && p->rc==SQLITE_OK && p->zErrmsg==0 );
+ pVfs->xDelete(pVfs, zOal, 0);
+ sqlite3_free(zOal);
+ }
}
/*
@@ -205678,7 +205678,7 @@ static void rbuCreateVfs(sqlite3rbu *p){
sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd);
assert( pVfs );
p->zVfsName = pVfs->zName;
- ((rbu_vfs*)pVfs)->pRbu = p;
+ ((rbu_vfs*)pVfs)->pRbu = p;
}
}
@@ -205694,112 +205694,112 @@ static void rbuDeleteVfs(sqlite3rbu *p){
}
/*
-** This user-defined SQL function is invoked with a single argument - the
-** name of a table expected to appear in the target database. It returns
-** the number of auxilliary indexes on the table.
+** This user-defined SQL function is invoked with a single argument - the
+** name of a table expected to appear in the target database. It returns
+** the number of auxilliary indexes on the table.
*/
-static void rbuIndexCntFunc(
+static void rbuIndexCntFunc(
sqlite3_context *pCtx,
- int nVal,
- sqlite3_value **apVal
-){
- sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx);
- sqlite3_stmt *pStmt = 0;
- char *zErrmsg = 0;
- int rc;
+ int nVal,
+ sqlite3_value **apVal
+){
+ sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx);
+ sqlite3_stmt *pStmt = 0;
+ char *zErrmsg = 0;
+ int rc;
sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
-
- assert( nVal==1 );
+
+ assert( nVal==1 );
rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg,
sqlite3_mprintf("SELECT count(*) FROM sqlite_schema "
- "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
- );
- if( rc!=SQLITE_OK ){
- sqlite3_result_error(pCtx, zErrmsg, -1);
- }else{
- int nIndex = 0;
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- nIndex = sqlite3_column_int(pStmt, 0);
- }
- rc = sqlite3_finalize(pStmt);
- if( rc==SQLITE_OK ){
- sqlite3_result_int(pCtx, nIndex);
- }else{
+ "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
+ );
+ if( rc!=SQLITE_OK ){
+ sqlite3_result_error(pCtx, zErrmsg, -1);
+ }else{
+ int nIndex = 0;
+ if( SQLITE_ROW==sqlite3_step(pStmt) ){
+ nIndex = sqlite3_column_int(pStmt, 0);
+ }
+ rc = sqlite3_finalize(pStmt);
+ if( rc==SQLITE_OK ){
+ sqlite3_result_int(pCtx, nIndex);
+ }else{
sqlite3_result_error(pCtx, sqlite3_errmsg(db), -1);
- }
- }
-
- sqlite3_free(zErrmsg);
-}
-
-/*
-** If the RBU database contains the rbu_count table, use it to initialize
-** the sqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table
-** is assumed to contain the same columns as:
-**
-** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
-**
-** There should be one row in the table for each data_xxx table in the
-** database. The 'tbl' column should contain the name of a data_xxx table,
-** and the cnt column the number of rows it contains.
-**
-** sqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt
+ }
+ }
+
+ sqlite3_free(zErrmsg);
+}
+
+/*
+** If the RBU database contains the rbu_count table, use it to initialize
+** the sqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table
+** is assumed to contain the same columns as:
+**
+** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
+**
+** There should be one row in the table for each data_xxx table in the
+** database. The 'tbl' column should contain the name of a data_xxx table,
+** and the cnt column the number of rows it contains.
+**
+** sqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt
** for all rows in the rbu_count table, where nIndex is the number of
-** indexes on the corresponding target database table.
-*/
-static void rbuInitPhaseOneSteps(sqlite3rbu *p){
- if( p->rc==SQLITE_OK ){
- sqlite3_stmt *pStmt = 0;
- int bExists = 0; /* True if rbu_count exists */
-
- p->nPhaseOneStep = -1;
-
+** indexes on the corresponding target database table.
+*/
+static void rbuInitPhaseOneSteps(sqlite3rbu *p){
+ if( p->rc==SQLITE_OK ){
+ sqlite3_stmt *pStmt = 0;
+ int bExists = 0; /* True if rbu_count exists */
+
+ p->nPhaseOneStep = -1;
+
p->rc = sqlite3_create_function(p->dbRbu,
- "rbu_index_cnt", 1, SQLITE_UTF8, (void*)p, rbuIndexCntFunc, 0, 0
- );
+ "rbu_index_cnt", 1, SQLITE_UTF8, (void*)p, rbuIndexCntFunc, 0, 0
+ );
- /* Check for the rbu_count table. If it does not exist, or if an error
- ** occurs, nPhaseOneStep will be left set to -1. */
- if( p->rc==SQLITE_OK ){
- p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
+ /* Check for the rbu_count table. If it does not exist, or if an error
+ ** occurs, nPhaseOneStep will be left set to -1. */
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
"SELECT 1 FROM sqlite_schema WHERE tbl_name = 'rbu_count'"
- );
- }
- if( p->rc==SQLITE_OK ){
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- bExists = 1;
- }
- p->rc = sqlite3_finalize(pStmt);
- }
-
- if( p->rc==SQLITE_OK && bExists ){
- p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
- "SELECT sum(cnt * (1 + rbu_index_cnt(rbu_target_name(tbl))))"
- "FROM rbu_count"
- );
- if( p->rc==SQLITE_OK ){
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- p->nPhaseOneStep = sqlite3_column_int64(pStmt, 0);
- }
- p->rc = sqlite3_finalize(pStmt);
- }
- }
- }
-}
-
-
-static sqlite3rbu *openRbuHandle(
+ );
+ }
+ if( p->rc==SQLITE_OK ){
+ if( SQLITE_ROW==sqlite3_step(pStmt) ){
+ bExists = 1;
+ }
+ p->rc = sqlite3_finalize(pStmt);
+ }
+
+ if( p->rc==SQLITE_OK && bExists ){
+ p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
+ "SELECT sum(cnt * (1 + rbu_index_cnt(rbu_target_name(tbl))))"
+ "FROM rbu_count"
+ );
+ if( p->rc==SQLITE_OK ){
+ if( SQLITE_ROW==sqlite3_step(pStmt) ){
+ p->nPhaseOneStep = sqlite3_column_int64(pStmt, 0);
+ }
+ p->rc = sqlite3_finalize(pStmt);
+ }
+ }
+ }
+}
+
+
+static sqlite3rbu *openRbuHandle(
const char *zTarget,
const char *zRbu,
const char *zState
){
sqlite3rbu *p;
- size_t nTarget = zTarget ? strlen(zTarget) : 0;
- size_t nRbu = strlen(zRbu);
- size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1;
+ size_t nTarget = zTarget ? strlen(zTarget) : 0;
+ size_t nRbu = strlen(zRbu);
+ size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1;
- p = (sqlite3rbu*)sqlite3_malloc64(nByte);
+ p = (sqlite3rbu*)sqlite3_malloc64(nByte);
if( p ){
RbuState *pState = 0;
@@ -205807,33 +205807,33 @@ static sqlite3rbu *openRbuHandle(
memset(p, 0, sizeof(sqlite3rbu));
rbuCreateVfs(p);
- /* Open the target, RBU and state databases */
+ /* Open the target, RBU and state databases */
if( p->rc==SQLITE_OK ){
- char *pCsr = (char*)&p[1];
- int bRetry = 0;
- if( zTarget ){
- p->zTarget = pCsr;
- memcpy(p->zTarget, zTarget, nTarget+1);
- pCsr += nTarget+1;
- }
- p->zRbu = pCsr;
+ char *pCsr = (char*)&p[1];
+ int bRetry = 0;
+ if( zTarget ){
+ p->zTarget = pCsr;
+ memcpy(p->zTarget, zTarget, nTarget+1);
+ pCsr += nTarget+1;
+ }
+ p->zRbu = pCsr;
memcpy(p->zRbu, zRbu, nRbu+1);
- pCsr += nRbu+1;
+ pCsr += nRbu+1;
if( zState ){
- p->zState = rbuMPrintf(p, "%s", zState);
- }
-
- /* If the first attempt to open the database file fails and the bRetry
- ** flag it set, this means that the db was not opened because it seemed
- ** to be a wal-mode db. But, this may have happened due to an earlier
- ** RBU vacuum operation leaving an old wal file in the directory.
- ** If this is the case, it will have been checkpointed and deleted
+ p->zState = rbuMPrintf(p, "%s", zState);
+ }
+
+ /* If the first attempt to open the database file fails and the bRetry
+ ** flag it set, this means that the db was not opened because it seemed
+ ** to be a wal-mode db. But, this may have happened due to an earlier
+ ** RBU vacuum operation leaving an old wal file in the directory.
+ ** If this is the case, it will have been checkpointed and deleted
** when the handle was closed and a second attempt to open the
- ** database may succeed. */
+ ** database may succeed. */
rbuOpenDatabase(p, 0, &bRetry);
- if( bRetry ){
+ if( bRetry ){
rbuOpenDatabase(p, 0, 0);
- }
+ }
}
if( p->rc==SQLITE_OK ){
@@ -205843,11 +205843,11 @@ static sqlite3rbu *openRbuHandle(
if( pState->eStage==0 ){
rbuDeleteOalFile(p);
- rbuInitPhaseOneSteps(p);
+ rbuInitPhaseOneSteps(p);
p->eStage = RBU_STAGE_OAL;
}else{
p->eStage = pState->eStage;
- p->nPhaseOneStep = pState->nPhaseOneStep;
+ p->nPhaseOneStep = pState->nPhaseOneStep;
}
p->nProgress = pState->nProgress;
p->iOalSz = pState->iOalSz;
@@ -205867,25 +205867,25 @@ static sqlite3rbu *openRbuHandle(
if( p->rc==SQLITE_OK
&& (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE)
- && pState->eStage!=0
- ){
- rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
+ && pState->eStage!=0
+ ){
+ rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
if( pFd->iCookie!=pState->iCookie ){
- /* At this point (pTargetFd->iCookie) contains the value of the
+ /* At this point (pTargetFd->iCookie) contains the value of the
** change-counter cookie (the thing that gets incremented when a
** transaction is committed in rollback mode) currently stored on
- ** page 1 of the database file. */
- p->rc = SQLITE_BUSY;
- p->zErrmsg = sqlite3_mprintf("database modified during rbu %s",
- (rbuIsVacuum(p) ? "vacuum" : "update")
- );
- }
+ ** page 1 of the database file. */
+ p->rc = SQLITE_BUSY;
+ p->zErrmsg = sqlite3_mprintf("database modified during rbu %s",
+ (rbuIsVacuum(p) ? "vacuum" : "update")
+ );
+ }
}
if( p->rc==SQLITE_OK ){
if( p->eStage==RBU_STAGE_OAL ){
- sqlite3 *db = p->dbMain;
- p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg);
+ sqlite3 *db = p->dbMain;
+ p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg);
/* Point the object iterator at the first object */
if( p->rc==SQLITE_OK ){
@@ -205896,33 +205896,33 @@ static sqlite3rbu *openRbuHandle(
** update finished. */
if( p->rc==SQLITE_OK && p->objiter.zTbl==0 ){
p->rc = SQLITE_DONE;
- p->eStage = RBU_STAGE_DONE;
- }else{
- if( p->rc==SQLITE_OK && pState->eStage==0 && rbuIsVacuum(p) ){
- rbuCopyPragma(p, "page_size");
- rbuCopyPragma(p, "auto_vacuum");
- }
-
- /* Open transactions both databases. The *-oal file is opened or
- ** created at this point. */
- if( p->rc==SQLITE_OK ){
- p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
- }
-
- /* Check if the main database is a zipvfs db. If it is, set the upper
+ p->eStage = RBU_STAGE_DONE;
+ }else{
+ if( p->rc==SQLITE_OK && pState->eStage==0 && rbuIsVacuum(p) ){
+ rbuCopyPragma(p, "page_size");
+ rbuCopyPragma(p, "auto_vacuum");
+ }
+
+ /* Open transactions both databases. The *-oal file is opened or
+ ** created at this point. */
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
+ }
+
+ /* Check if the main database is a zipvfs db. If it is, set the upper
** level pager to use "journal_mode=off". This prevents it from
- ** generating a large journal using a temp file. */
- if( p->rc==SQLITE_OK ){
- int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0);
- if( frc==SQLITE_OK ){
- p->rc = sqlite3_exec(
- db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg);
- }
- }
-
- if( p->rc==SQLITE_OK ){
- rbuSetupOal(p, pState);
- }
+ ** generating a large journal using a temp file. */
+ if( p->rc==SQLITE_OK ){
+ int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0);
+ if( frc==SQLITE_OK ){
+ p->rc = sqlite3_exec(
+ db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg);
+ }
+ }
+
+ if( p->rc==SQLITE_OK ){
+ rbuSetupOal(p, pState);
+ }
}
}else if( p->eStage==RBU_STAGE_MOVE ){
/* no-op */
@@ -205949,54 +205949,54 @@ static sqlite3rbu *openRbuHandle(
return p;
}
-/*
-** Allocate and return an RBU handle with all fields zeroed except for the
-** error code, which is set to SQLITE_MISUSE.
-*/
-static sqlite3rbu *rbuMisuseError(void){
- sqlite3rbu *pRet;
- pRet = sqlite3_malloc64(sizeof(sqlite3rbu));
- if( pRet ){
- memset(pRet, 0, sizeof(sqlite3rbu));
- pRet->rc = SQLITE_MISUSE;
- }
- return pRet;
-}
+/*
+** Allocate and return an RBU handle with all fields zeroed except for the
+** error code, which is set to SQLITE_MISUSE.
+*/
+static sqlite3rbu *rbuMisuseError(void){
+ sqlite3rbu *pRet;
+ pRet = sqlite3_malloc64(sizeof(sqlite3rbu));
+ if( pRet ){
+ memset(pRet, 0, sizeof(sqlite3rbu));
+ pRet->rc = SQLITE_MISUSE;
+ }
+ return pRet;
+}
/*
** Open and return a new RBU handle.
-*/
-SQLITE_API sqlite3rbu *sqlite3rbu_open(
+*/
+SQLITE_API sqlite3rbu *sqlite3rbu_open(
const char *zTarget,
- const char *zRbu,
- const char *zState
-){
- if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
- return openRbuHandle(zTarget, zRbu, zState);
-}
-
-/*
-** Open a handle to begin or resume an RBU VACUUM operation.
-*/
-SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
+ const char *zRbu,
+ const char *zState
+){
+ if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
+ return openRbuHandle(zTarget, zRbu, zState);
+}
+
+/*
+** Open a handle to begin or resume an RBU VACUUM operation.
+*/
+SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
const char *zTarget,
- const char *zState
-){
- if( zTarget==0 ){ return rbuMisuseError(); }
+ const char *zState
+){
+ if( zTarget==0 ){ return rbuMisuseError(); }
if( zState ){
int n = strlen(zState);
if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){
return rbuMisuseError();
}
}
- /* TODO: Check that both arguments are non-NULL */
- return openRbuHandle(0, zTarget, zState);
-}
-
-/*
+ /* TODO: Check that both arguments are non-NULL */
+ return openRbuHandle(0, zTarget, zState);
+}
+
+/*
** Return the database handle used by pRbu.
*/
-SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){
+SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){
sqlite3 *db = 0;
if( pRbu ){
db = (bRbu ? pRbu->dbRbu : pRbu->dbMain);
@@ -206012,8 +206012,8 @@ SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){
*/
static void rbuEditErrmsg(sqlite3rbu *p){
if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){
- unsigned int i;
- size_t nErrmsg = strlen(p->zErrmsg);
+ unsigned int i;
+ size_t nErrmsg = strlen(p->zErrmsg);
for(i=0; i<(nErrmsg-8); i++){
if( memcmp(&p->zErrmsg[i], "rbu_imp_", 8)==0 ){
int nDel = 8;
@@ -206028,7 +206028,7 @@ static void rbuEditErrmsg(sqlite3rbu *p){
/*
** Close the RBU handle.
*/
-SQLITE_API int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
+SQLITE_API int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
int rc;
if( p ){
@@ -206037,12 +206037,12 @@ SQLITE_API int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
}
- /* Sync the db file if currently doing an incremental checkpoint */
- if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
- sqlite3_file *pDb = p->pTargetFd->pReal;
- p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
- }
-
+ /* Sync the db file if currently doing an incremental checkpoint */
+ if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+ p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
+ }
+
rbuSaveState(p, p->eStage);
if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){
@@ -206052,32 +206052,32 @@ SQLITE_API int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
/* Close any open statement handles. */
rbuObjIterFinalize(&p->objiter);
- /* If this is an RBU vacuum handle and the vacuum has either finished
+ /* If this is an RBU vacuum handle and the vacuum has either finished
** successfully or encountered an error, delete the contents of the
** state table. This causes the next call to sqlite3rbu_vacuum()
- ** specifying the current target and state databases to start a new
- ** vacuum from scratch. */
- if( rbuIsVacuum(p) && p->rc!=SQLITE_OK && p->dbRbu ){
- int rc2 = sqlite3_exec(p->dbRbu, "DELETE FROM stat.rbu_state", 0, 0, 0);
- if( p->rc==SQLITE_DONE && rc2!=SQLITE_OK ) p->rc = rc2;
- }
-
+ ** specifying the current target and state databases to start a new
+ ** vacuum from scratch. */
+ if( rbuIsVacuum(p) && p->rc!=SQLITE_OK && p->dbRbu ){
+ int rc2 = sqlite3_exec(p->dbRbu, "DELETE FROM stat.rbu_state", 0, 0, 0);
+ if( p->rc==SQLITE_DONE && rc2!=SQLITE_OK ) p->rc = rc2;
+ }
+
/* Close the open database handle and VFS object. */
- sqlite3_close(p->dbRbu);
+ sqlite3_close(p->dbRbu);
sqlite3_close(p->dbMain);
- assert( p->szTemp==0 );
+ assert( p->szTemp==0 );
rbuDeleteVfs(p);
sqlite3_free(p->aBuf);
sqlite3_free(p->aFrame);
rbuEditErrmsg(p);
rc = p->rc;
- if( pzErrmsg ){
- *pzErrmsg = p->zErrmsg;
- }else{
- sqlite3_free(p->zErrmsg);
- }
- sqlite3_free(p->zState);
+ if( pzErrmsg ){
+ *pzErrmsg = p->zErrmsg;
+ }else{
+ sqlite3_free(p->zErrmsg);
+ }
+ sqlite3_free(p->zState);
sqlite3_free(p);
}else{
rc = SQLITE_NOMEM;
@@ -206091,111 +206091,111 @@ SQLITE_API int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
** updates) that have been performed on the target database since the
** current RBU update was started.
*/
-SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu){
+SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu){
return pRbu->nProgress;
}
-/*
-** Return permyriadage progress indications for the two main stages of
-** an RBU update.
-*/
-SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){
- const int MAX_PROGRESS = 10000;
- switch( p->eStage ){
- case RBU_STAGE_OAL:
- if( p->nPhaseOneStep>0 ){
- *pnOne = (int)(MAX_PROGRESS * (i64)p->nProgress/(i64)p->nPhaseOneStep);
- }else{
- *pnOne = -1;
- }
- *pnTwo = 0;
- break;
-
- case RBU_STAGE_MOVE:
- *pnOne = MAX_PROGRESS;
- *pnTwo = 0;
- break;
-
- case RBU_STAGE_CKPT:
- *pnOne = MAX_PROGRESS;
- *pnTwo = (int)(MAX_PROGRESS * (i64)p->nStep / (i64)p->nFrame);
- break;
-
- case RBU_STAGE_DONE:
- *pnOne = MAX_PROGRESS;
- *pnTwo = MAX_PROGRESS;
- break;
-
- default:
- assert( 0 );
- }
-}
-
-/*
-** Return the current state of the RBU vacuum or update operation.
-*/
-SQLITE_API int sqlite3rbu_state(sqlite3rbu *p){
- int aRes[] = {
- 0, SQLITE_RBU_STATE_OAL, SQLITE_RBU_STATE_MOVE,
- 0, SQLITE_RBU_STATE_CHECKPOINT, SQLITE_RBU_STATE_DONE
- };
-
- assert( RBU_STAGE_OAL==1 );
- assert( RBU_STAGE_MOVE==2 );
- assert( RBU_STAGE_CKPT==4 );
- assert( RBU_STAGE_DONE==5 );
- assert( aRes[RBU_STAGE_OAL]==SQLITE_RBU_STATE_OAL );
- assert( aRes[RBU_STAGE_MOVE]==SQLITE_RBU_STATE_MOVE );
- assert( aRes[RBU_STAGE_CKPT]==SQLITE_RBU_STATE_CHECKPOINT );
- assert( aRes[RBU_STAGE_DONE]==SQLITE_RBU_STATE_DONE );
-
- if( p->rc!=SQLITE_OK && p->rc!=SQLITE_DONE ){
- return SQLITE_RBU_STATE_ERROR;
- }else{
- assert( p->rc!=SQLITE_DONE || p->eStage==RBU_STAGE_DONE );
- assert( p->eStage==RBU_STAGE_OAL
- || p->eStage==RBU_STAGE_MOVE
- || p->eStage==RBU_STAGE_CKPT
- || p->eStage==RBU_STAGE_DONE
- );
- return aRes[p->eStage];
- }
-}
-
-SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){
- int rc = p->rc;
- if( rc==SQLITE_DONE ) return SQLITE_OK;
-
- assert( p->eStage>=RBU_STAGE_OAL && p->eStage<=RBU_STAGE_DONE );
- if( p->eStage==RBU_STAGE_OAL ){
- assert( rc!=SQLITE_DONE );
- if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0);
- }
-
- /* Sync the db file */
- if( rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
- sqlite3_file *pDb = p->pTargetFd->pReal;
- rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
- }
-
- p->rc = rc;
- rbuSaveState(p, p->eStage);
- rc = p->rc;
-
- if( p->eStage==RBU_STAGE_OAL ){
- assert( rc!=SQLITE_DONE );
- if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
+/*
+** Return permyriadage progress indications for the two main stages of
+** an RBU update.
+*/
+SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){
+ const int MAX_PROGRESS = 10000;
+ switch( p->eStage ){
+ case RBU_STAGE_OAL:
+ if( p->nPhaseOneStep>0 ){
+ *pnOne = (int)(MAX_PROGRESS * (i64)p->nProgress/(i64)p->nPhaseOneStep);
+ }else{
+ *pnOne = -1;
+ }
+ *pnTwo = 0;
+ break;
+
+ case RBU_STAGE_MOVE:
+ *pnOne = MAX_PROGRESS;
+ *pnTwo = 0;
+ break;
+
+ case RBU_STAGE_CKPT:
+ *pnOne = MAX_PROGRESS;
+ *pnTwo = (int)(MAX_PROGRESS * (i64)p->nStep / (i64)p->nFrame);
+ break;
+
+ case RBU_STAGE_DONE:
+ *pnOne = MAX_PROGRESS;
+ *pnTwo = MAX_PROGRESS;
+ break;
+
+ default:
+ assert( 0 );
+ }
+}
+
+/*
+** Return the current state of the RBU vacuum or update operation.
+*/
+SQLITE_API int sqlite3rbu_state(sqlite3rbu *p){
+ int aRes[] = {
+ 0, SQLITE_RBU_STATE_OAL, SQLITE_RBU_STATE_MOVE,
+ 0, SQLITE_RBU_STATE_CHECKPOINT, SQLITE_RBU_STATE_DONE
+ };
+
+ assert( RBU_STAGE_OAL==1 );
+ assert( RBU_STAGE_MOVE==2 );
+ assert( RBU_STAGE_CKPT==4 );
+ assert( RBU_STAGE_DONE==5 );
+ assert( aRes[RBU_STAGE_OAL]==SQLITE_RBU_STATE_OAL );
+ assert( aRes[RBU_STAGE_MOVE]==SQLITE_RBU_STATE_MOVE );
+ assert( aRes[RBU_STAGE_CKPT]==SQLITE_RBU_STATE_CHECKPOINT );
+ assert( aRes[RBU_STAGE_DONE]==SQLITE_RBU_STATE_DONE );
+
+ if( p->rc!=SQLITE_OK && p->rc!=SQLITE_DONE ){
+ return SQLITE_RBU_STATE_ERROR;
+ }else{
+ assert( p->rc!=SQLITE_DONE || p->eStage==RBU_STAGE_DONE );
+ assert( p->eStage==RBU_STAGE_OAL
+ || p->eStage==RBU_STAGE_MOVE
+ || p->eStage==RBU_STAGE_CKPT
+ || p->eStage==RBU_STAGE_DONE
+ );
+ return aRes[p->eStage];
+ }
+}
+
+SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){
+ int rc = p->rc;
+ if( rc==SQLITE_DONE ) return SQLITE_OK;
+
+ assert( p->eStage>=RBU_STAGE_OAL && p->eStage<=RBU_STAGE_DONE );
+ if( p->eStage==RBU_STAGE_OAL ){
+ assert( rc!=SQLITE_DONE );
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0);
+ }
+
+ /* Sync the db file */
+ if( rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+ rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
+ }
+
+ p->rc = rc;
+ rbuSaveState(p, p->eStage);
+ rc = p->rc;
+
+ if( p->eStage==RBU_STAGE_OAL ){
+ assert( rc!=SQLITE_DONE );
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
if( rc==SQLITE_OK ){
const char *zBegin = rbuIsVacuum(p) ? "BEGIN" : "BEGIN IMMEDIATE";
rc = sqlite3_exec(p->dbRbu, zBegin, 0, 0, 0);
}
- if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0,0);
- }
-
- p->rc = rc;
- return rc;
-}
-
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0,0);
+ }
+
+ p->rc = rc;
+ return rc;
+}
+
/**************************************************************************
** Beginning of RBU VFS shim methods. The VFS shim modifies the behaviour
** of a standard VFS in the following ways:
@@ -206256,7 +206256,7 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){
*/
static void rbuUnlockShm(rbu_file *p){
- assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
+ assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
if( p->pRbu ){
int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock;
int i;
@@ -206270,18 +206270,18 @@ static void rbuUnlockShm(rbu_file *p){
}
/*
-*/
-static int rbuUpdateTempSize(rbu_file *pFd, sqlite3_int64 nNew){
- sqlite3rbu *pRbu = pFd->pRbu;
- i64 nDiff = nNew - pFd->sz;
- pRbu->szTemp += nDiff;
- pFd->sz = nNew;
- assert( pRbu->szTemp>=0 );
- if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL;
- return SQLITE_OK;
-}
-
-/*
+*/
+static int rbuUpdateTempSize(rbu_file *pFd, sqlite3_int64 nNew){
+ sqlite3rbu *pRbu = pFd->pRbu;
+ i64 nDiff = nNew - pFd->sz;
+ pRbu->szTemp += nDiff;
+ pFd->sz = nNew;
+ assert( pRbu->szTemp>=0 );
+ if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL;
+ return SQLITE_OK;
+}
+
+/*
** Add an item to the main-db lists, if it is not already present.
**
** There are two main-db lists. One for all file descriptors, and one
@@ -206365,9 +206365,9 @@ static int rbuVfsClose(sqlite3_file *pFile){
rbuUnlockShm(p);
p->pReal->pMethods->xShmUnmap(p->pReal, 0);
}
- else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
- rbuUpdateTempSize(p, 0);
- }
+ else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
+ rbuUpdateTempSize(p, 0);
+ }
assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p );
/* Close the underlying file handle */
@@ -206388,22 +206388,22 @@ static u32 rbuGetU32(u8 *aBuf){
}
/*
-** Write an unsigned 32-bit value in big-endian format to the supplied
-** buffer.
-*/
-static void rbuPutU32(u8 *aBuf, u32 iVal){
- aBuf[0] = (iVal >> 24) & 0xFF;
- aBuf[1] = (iVal >> 16) & 0xFF;
- aBuf[2] = (iVal >> 8) & 0xFF;
- aBuf[3] = (iVal >> 0) & 0xFF;
-}
-
-static void rbuPutU16(u8 *aBuf, u16 iVal){
- aBuf[0] = (iVal >> 8) & 0xFF;
- aBuf[1] = (iVal >> 0) & 0xFF;
-}
-
-/*
+** Write an unsigned 32-bit value in big-endian format to the supplied
+** buffer.
+*/
+static void rbuPutU32(u8 *aBuf, u32 iVal){
+ aBuf[0] = (iVal >> 24) & 0xFF;
+ aBuf[1] = (iVal >> 16) & 0xFF;
+ aBuf[2] = (iVal >> 8) & 0xFF;
+ aBuf[3] = (iVal >> 0) & 0xFF;
+}
+
+static void rbuPutU16(u8 *aBuf, u16 iVal){
+ aBuf[0] = (iVal >> 8) & 0xFF;
+ aBuf[1] = (iVal >> 0) & 0xFF;
+}
+
+/*
** Read data from an rbuVfs-file.
*/
static int rbuVfsRead(
@@ -206428,35 +206428,35 @@ static int rbuVfsRead(
memset(zBuf, 0, iAmt);
}else{
rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
-#if 1
+#if 1
/* If this is being called to read the first page of the target
** database as part of an rbu vacuum operation, synthesize the
- ** contents of the first page if it does not yet exist. Otherwise,
- ** SQLite will not check for a *-wal file. */
+ ** contents of the first page if it does not yet exist. Otherwise,
+ ** SQLite will not check for a *-wal file. */
if( pRbu && rbuIsVacuum(pRbu)
- && rc==SQLITE_IOERR_SHORT_READ && iOfst==0
- && (p->openFlags & SQLITE_OPEN_MAIN_DB)
- && pRbu->rc==SQLITE_OK
- ){
- sqlite3_file *pFd = (sqlite3_file*)pRbu->pRbuFd;
- rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst);
- if( rc==SQLITE_OK ){
- u8 *aBuf = (u8*)zBuf;
- u32 iRoot = rbuGetU32(&aBuf[52]) ? 1 : 0;
- rbuPutU32(&aBuf[52], iRoot); /* largest root page number */
- rbuPutU32(&aBuf[36], 0); /* number of free pages */
- rbuPutU32(&aBuf[32], 0); /* first page on free list trunk */
- rbuPutU32(&aBuf[28], 1); /* size of db file in pages */
- rbuPutU32(&aBuf[24], pRbu->pRbuFd->iCookie+1); /* Change counter */
-
- if( iAmt>100 ){
- memset(&aBuf[100], 0, iAmt-100);
- rbuPutU16(&aBuf[105], iAmt & 0xFFFF);
- aBuf[100] = 0x0D;
- }
- }
- }
-#endif
+ && rc==SQLITE_IOERR_SHORT_READ && iOfst==0
+ && (p->openFlags & SQLITE_OPEN_MAIN_DB)
+ && pRbu->rc==SQLITE_OK
+ ){
+ sqlite3_file *pFd = (sqlite3_file*)pRbu->pRbuFd;
+ rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst);
+ if( rc==SQLITE_OK ){
+ u8 *aBuf = (u8*)zBuf;
+ u32 iRoot = rbuGetU32(&aBuf[52]) ? 1 : 0;
+ rbuPutU32(&aBuf[52], iRoot); /* largest root page number */
+ rbuPutU32(&aBuf[36], 0); /* number of free pages */
+ rbuPutU32(&aBuf[32], 0); /* first page on free list trunk */
+ rbuPutU32(&aBuf[28], 1); /* size of db file in pages */
+ rbuPutU32(&aBuf[24], pRbu->pRbuFd->iCookie+1); /* Change counter */
+
+ if( iAmt>100 ){
+ memset(&aBuf[100], 0, iAmt-100);
+ rbuPutU16(&aBuf[105], iAmt & 0xFFFF);
+ aBuf[100] = 0x0D;
+ }
+ }
+ }
+#endif
}
if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
/* These look like magic numbers. But they are stable, as they are part
@@ -206486,19 +206486,19 @@ static int rbuVfsWrite(
assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
rc = rbuCaptureDbWrite(p->pRbu, iOfst);
}else{
- if( pRbu ){
+ if( pRbu ){
if( pRbu->eStage==RBU_STAGE_OAL
&& (p->openFlags & SQLITE_OPEN_WAL)
- && iOfst>=pRbu->iOalSz
- ){
- pRbu->iOalSz = iAmt + iOfst;
- }else if( p->openFlags & SQLITE_OPEN_DELETEONCLOSE ){
- i64 szNew = iAmt+iOfst;
- if( szNew>p->sz ){
- rc = rbuUpdateTempSize(p, szNew);
- if( rc!=SQLITE_OK ) return rc;
- }
- }
+ && iOfst>=pRbu->iOalSz
+ ){
+ pRbu->iOalSz = iAmt + iOfst;
+ }else if( p->openFlags & SQLITE_OPEN_DELETEONCLOSE ){
+ i64 szNew = iAmt+iOfst;
+ if( szNew>p->sz ){
+ rc = rbuUpdateTempSize(p, szNew);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ }
}
rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
@@ -206517,10 +206517,10 @@ static int rbuVfsWrite(
*/
static int rbuVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
rbu_file *p = (rbu_file*)pFile;
- if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
- int rc = rbuUpdateTempSize(p, size);
- if( rc!=SQLITE_OK ) return rc;
- }
+ if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
+ int rc = rbuUpdateTempSize(p, size);
+ if( rc!=SQLITE_OK ) return rc;
+ }
return p->pReal->pMethods->xTruncate(p->pReal, size);
}
@@ -206543,20 +206543,20 @@ static int rbuVfsSync(sqlite3_file *pFile, int flags){
*/
static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
rbu_file *p = (rbu_file *)pFile;
- int rc;
- rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
-
- /* If this is an RBU vacuum operation and this is the target database,
- ** pretend that it has at least one page. Otherwise, SQLite will not
+ int rc;
+ rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
+
+ /* If this is an RBU vacuum operation and this is the target database,
+ ** pretend that it has at least one page. Otherwise, SQLite will not
** check for the existance of a *-wal file. rbuVfsRead() contains
- ** similar logic. */
+ ** similar logic. */
if( rc==SQLITE_OK && *pSize==0
&& p->pRbu && rbuIsVacuum(p->pRbu)
- && (p->openFlags & SQLITE_OPEN_MAIN_DB)
- ){
- *pSize = 1024;
- }
- return rc;
+ && (p->openFlags & SQLITE_OPEN_MAIN_DB)
+ ){
+ *pSize = 1024;
+ }
+ return rc;
}
/*
@@ -206569,8 +206569,8 @@ static int rbuVfsLock(sqlite3_file *pFile, int eLock){
assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
if( eLock==SQLITE_LOCK_EXCLUSIVE
- && (p->bNolock || (pRbu && pRbu->eStage!=RBU_STAGE_DONE))
- ){
+ && (p->bNolock || (pRbu && pRbu->eStage!=RBU_STAGE_DONE))
+ ){
/* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this
** prevents it from checkpointing the database from sqlite3_close(). */
rc = SQLITE_BUSY;
@@ -206634,12 +206634,12 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
}
return rc;
}
- else if( op==SQLITE_FCNTL_RBUCNT ){
- sqlite3rbu *pRbu = (sqlite3rbu*)pArg;
- pRbu->nRbu++;
- pRbu->pRbuFd = p;
- p->bNolock = 1;
- }
+ else if( op==SQLITE_FCNTL_RBUCNT ){
+ sqlite3rbu *pRbu = (sqlite3rbu*)pArg;
+ pRbu->nRbu++;
+ pRbu->pRbuFd = p;
+ p->bNolock = 1;
+ }
rc = xControl(p->pReal, op, pArg);
if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
@@ -206743,7 +206743,7 @@ static int rbuVfsShmMap(
}
if( rc==SQLITE_OK ){
- char *pNew = (char*)sqlite3_malloc64(szRegion);
+ char *pNew = (char*)sqlite3_malloc64(szRegion);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -206819,15 +206819,15 @@ static int rbuVfsOpen(
rbuVfsShmMap, /* xShmMap */
rbuVfsShmLock, /* xShmLock */
rbuVfsShmBarrier, /* xShmBarrier */
- rbuVfsShmUnmap, /* xShmUnmap */
- 0, 0 /* xFetch, xUnfetch */
+ rbuVfsShmUnmap, /* xShmUnmap */
+ 0, 0 /* xFetch, xUnfetch */
};
rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs;
sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs;
rbu_file *pFd = (rbu_file *)pFile;
int rc = SQLITE_OK;
const char *zOpen = zName;
- int oflags = flags;
+ int oflags = flags;
memset(pFd, 0, sizeof(rbu_file));
pFd->pReal = (sqlite3_file*)&pFd[1];
@@ -206848,10 +206848,10 @@ static int rbuVfsOpen(
if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
/* This call is to open a *-wal file. Intead, open the *-oal. */
size_t nOpen;
- if( rbuIsVacuum(pDb->pRbu) ){
+ if( rbuIsVacuum(pDb->pRbu) ){
zOpen = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
zOpen = sqlite3_filename_wal(zOpen);
- }
+ }
nOpen = strlen(zOpen);
((char*)zOpen)[nOpen-3] = 'o';
pFd->pRbu = pDb->pRbu;
@@ -206859,21 +206859,21 @@ static int rbuVfsOpen(
pDb->pWalFd = pFd;
}
}
- }else{
- pFd->pRbu = pRbuVfs->pRbu;
+ }else{
+ pFd->pRbu = pRbuVfs->pRbu;
}
if( oflags & SQLITE_OPEN_MAIN_DB
&& sqlite3_uri_boolean(zName, "rbu_memory", 0)
- ){
- assert( oflags & SQLITE_OPEN_MAIN_DB );
- oflags = SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
- SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
- zOpen = 0;
- }
-
+ ){
+ assert( oflags & SQLITE_OPEN_MAIN_DB );
+ oflags = SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
+ SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
+ zOpen = 0;
+ }
+
if( rc==SQLITE_OK ){
- rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags);
+ rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags);
}
if( pFd->pReal->pMethods ){
/* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
@@ -206935,9 +206935,9 @@ static int rbuVfsAccess(
if( *pResOut ){
rc = SQLITE_CANTOPEN;
}else{
- sqlite3_int64 sz = 0;
- rc = rbuVfsFileSize(&pDb->base, &sz);
- *pResOut = (sz>0);
+ sqlite3_int64 sz = 0;
+ rc = rbuVfsFileSize(&pDb->base, &sz);
+ *pResOut = (sz>0);
}
}
}
@@ -207037,7 +207037,7 @@ static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
** Deregister and destroy an RBU vfs created by an earlier call to
** sqlite3rbu_create_vfs().
*/
-SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName){
+SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName){
sqlite3_vfs *pVfs = sqlite3_vfs_find(zName);
if( pVfs && pVfs->xOpen==rbuVfsOpen ){
sqlite3_mutex_free(((rbu_vfs*)pVfs)->mutex);
@@ -207051,7 +207051,7 @@ SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName){
** via existing VFS zParent. The new object is registered as a non-default
** VFS with SQLite before returning.
*/
-SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent){
+SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent){
/* Template for VFS */
static sqlite3_vfs vfs_template = {
@@ -207085,12 +207085,12 @@ SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent){
rbu_vfs *pNew = 0; /* Newly allocated VFS */
int rc = SQLITE_OK;
- size_t nName;
- size_t nByte;
+ size_t nName;
+ size_t nByte;
nName = strlen(zName);
nByte = sizeof(rbu_vfs) + nName + 1;
- pNew = (rbu_vfs*)sqlite3_malloc64(nByte);
+ pNew = (rbu_vfs*)sqlite3_malloc64(nByte);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -207126,21 +207126,21 @@ SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent){
return rc;
}
-/*
-** Configure the aggregate temp file size limit for this RBU handle.
-*/
-SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu *pRbu, sqlite3_int64 n){
- if( n>=0 ){
- pRbu->szTempLimit = n;
- }
- return pRbu->szTempLimit;
-}
+/*
+** Configure the aggregate temp file size limit for this RBU handle.
+*/
+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu *pRbu, sqlite3_int64 n){
+ if( n>=0 ){
+ pRbu->szTempLimit = n;
+ }
+ return pRbu->szTempLimit;
+}
+
+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu *pRbu){
+ return pRbu->szTemp;
+}
+
-SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu *pRbu){
- return pRbu->szTemp;
-}
-
-
/**************************************************************************/
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */
@@ -207165,9 +207165,9 @@ SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu *pRbu){
** information from an SQLite database in order to implement the
** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script
** for an example implementation.
-**
-** Additional information is available on the "dbstat.html" page of the
-** official SQLite documentation.
+**
+** Additional information is available on the "dbstat.html" page of the
+** official SQLite documentation.
*/
/* #include "sqliteInt.h" ** Requires access to internal data structures ** */
@@ -207269,7 +207269,7 @@ struct StatCursor {
sqlite3_stmt *pStmt; /* Iterates through set of root pages */
u8 isEof; /* After pStmt has returned SQLITE_DONE */
u8 isAgg; /* Aggregate results for each table */
- int iDb; /* Schema used for this query */
+ int iDb; /* Schema used for this query */
StatPage aPage[32]; /* Pages in path to current page */
int iPage; /* Current entry in aPage[] */
@@ -207314,9 +207314,9 @@ static int statConnect(
int iDb;
if( argc>=4 ){
- Token nm;
- sqlite3TokenInit(&nm, (char*)argv[3]);
- iDb = sqlite3FindDb(db, &nm);
+ Token nm;
+ sqlite3TokenInit(&nm, (char*)argv[3]);
+ iDb = sqlite3FindDb(db, &nm);
if( iDb<0 ){
*pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
return SQLITE_ERROR;
@@ -207328,7 +207328,7 @@ static int statConnect(
rc = sqlite3_declare_vtab(db, zDbstatSchema);
if( rc==SQLITE_OK ){
pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
- if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
+ if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
}
assert( rc==SQLITE_OK || pTab==0 );
@@ -207352,7 +207352,7 @@ static int statDisconnect(sqlite3_vtab *pVtab){
/*
** Compute the best query strategy and return the result in idxNum.
-**
+**
** idxNum-Bit Meaning
** ---------- ----------------------------------------------
** 0x01 There is a schema=? term in the WHERE clause
@@ -207361,18 +207361,18 @@ static int statDisconnect(sqlite3_vtab *pVtab){
** 0x08 Output should be ordered by name and path
*/
static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
- int i;
+ int i;
int iSchema = -1;
int iName = -1;
int iAgg = -1;
- /* Look for a valid schema=? constraint. If found, change the idxNum to
- ** 1 and request the value of that constraint be sent to xFilter. And
- ** lower the cost estimate to encourage the constrained version to be
- ** used.
- */
- for(i=0; i<pIdxInfo->nConstraint; i++){
- if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ /* Look for a valid schema=? constraint. If found, change the idxNum to
+ ** 1 and request the value of that constraint be sent to xFilter. And
+ ** lower the cost estimate to encourage the constrained version to be
+ ** used.
+ */
+ for(i=0; i<pIdxInfo->nConstraint; i++){
+ if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
if( pIdxInfo->aConstraint[i].usable==0 ){
/* Force DBSTAT table should always be the right-most table in a join */
return SQLITE_CONSTRAINT;
@@ -207391,7 +207391,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
break;
}
}
- }
+ }
i = 0;
if( iSchema>=0 ){
pIdxInfo->aConstraintUsage[iSchema].argvIndex = ++i;
@@ -207407,7 +207407,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
pIdxInfo->idxNum |= 0x04;
}
pIdxInfo->estimatedCost = 1.0;
-
+
/* Records are always returned in ascending order of (name, path).
** If this will satisfy the client, set the orderByConsumed flag so that
** SQLite does not do an external sort.
@@ -207439,15 +207439,15 @@ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
if( pCsr==0 ){
- return SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}else{
memset(pCsr, 0, sizeof(StatCursor));
pCsr->base.pVtab = pVTab;
- pCsr->iDb = pTab->iDb;
+ pCsr->iDb = pTab->iDb;
}
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
- return SQLITE_OK;
+ return SQLITE_OK;
}
static void statClearCells(StatPage *p){
@@ -207485,7 +207485,7 @@ static void statResetCsr(StatCursor *pCsr){
pCsr->iPage = 0;
sqlite3_free(pCsr->zPath);
pCsr->zPath = 0;
- pCsr->isEof = 0;
+ pCsr->isEof = 0;
}
/* Resize the space-used counters inside of the cursor */
@@ -207586,7 +207586,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
sqlite3BtreeLeave(pBt);
p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
- if( p->aCell==0 ) return SQLITE_NOMEM_BKPT;
+ if( p->aCell==0 ) return SQLITE_NOMEM_BKPT;
memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
for(i=0; i<p->nCell; i++){
@@ -207623,13 +207623,13 @@ static int statDecodePage(Btree *pBt, StatPage *p){
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
pCell->nOvfl = nOvfl;
pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
- if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
+ if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
for(j=1; j<nOvfl; j++){
int rc;
u32 iPrev = pCell->aOvfl[j-1];
DbPage *pPg = 0;
- rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg, 0);
+ rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg, 0);
if( rc!=SQLITE_OK ){
assert( pPg==0 );
return rc;
@@ -207719,7 +207719,7 @@ static int statNext(sqlite3_vtab_cursor *pCursor){
char *z;
StatCursor *pCsr = (StatCursor *)pCursor;
StatTable *pTab = (StatTable *)pCursor->pVtab;
- Btree *pBt = pTab->db->aDb[pCsr->iDb].pBt;
+ Btree *pBt = pTab->db->aDb[pCsr->iDb].pBt;
Pager *pPager = sqlite3BtreePager(pBt);
sqlite3_free(pCsr->zPath);
@@ -207884,7 +207884,7 @@ static int statFilter(
int argc, sqlite3_value **argv
){
StatCursor *pCsr = (StatCursor *)pCursor;
- StatTable *pTab = (StatTable*)(pCursor->pVtab);
+ StatTable *pTab = (StatTable*)(pCursor->pVtab);
sqlite3_str *pSql; /* Query of btrees to analyze */
char *zSql; /* String value of pSql */
int iArg = 0; /* Count of argv[] parameters used so far */
@@ -207897,15 +207897,15 @@ static int statFilter(
if( idxNum & 0x01 ){
/* schema=? constraint is present. Get its value */
const char *zDbase = (const char*)sqlite3_value_text(argv[iArg++]);
- pCsr->iDb = sqlite3FindDbName(pTab->db, zDbase);
- if( pCsr->iDb<0 ){
+ pCsr->iDb = sqlite3FindDbName(pTab->db, zDbase);
+ if( pCsr->iDb<0 ){
pCsr->iDb = 0;
pCsr->isEof = 1;
return SQLITE_OK;
- }
- }else{
- pCsr->iDb = pTab->iDb;
- }
+ }
+ }else{
+ pCsr->iDb = pTab->iDb;
+ }
if( idxNum & 0x02 ){
/* name=? constraint is present */
zName = (const char*)sqlite3_value_text(argv[iArg++]);
@@ -207931,18 +207931,18 @@ static int statFilter(
sqlite3_str_appendf(pSql, " ORDER BY name");
}
zSql = sqlite3_str_finish(pSql);
- if( zSql==0 ){
- return SQLITE_NOMEM_BKPT;
- }else{
- rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
- sqlite3_free(zSql);
- }
-
- if( rc==SQLITE_OK ){
+ if( zSql==0 ){
+ return SQLITE_NOMEM_BKPT;
+ }else{
+ rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
+ sqlite3_free(zSql);
+ }
+
+ if( rc==SQLITE_OK ){
pCsr->iPage = -1;
- rc = statNext(pCursor);
- }
- return rc;
+ rc = statNext(pCursor);
+ }
+ return rc;
}
static int statColumn(
@@ -207989,15 +207989,15 @@ static int statColumn(
sqlite3_result_int64(ctx, pCsr->iOffset);
}
break;
- case 9: /* pgsize */
+ case 9: /* pgsize */
sqlite3_result_int(ctx, pCsr->szPage);
break;
case 10: { /* schema */
- sqlite3 *db = sqlite3_context_db_handle(ctx);
- int iDb = pCsr->iDb;
- sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC);
- break;
- }
+ sqlite3 *db = sqlite3_context_db_handle(ctx);
+ int iDb = pCsr->iDb;
+ sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC);
+ break;
+ }
default: { /* aggregate */
sqlite3_result_int(ctx, pCsr->isAgg);
break;
@@ -208037,9 +208037,9 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
- 0, /* xSavepoint */
- 0, /* xRelease */
- 0, /* xRollbackTo */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0, /* xRollbackTo */
0 /* xShadowName */
};
return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
@@ -208049,678 +208049,678 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
/************** End of dbstat.c **********************************************/
-/************** Begin file dbpage.c ******************************************/
-/*
-** 2017-10-11
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains an implementation of the "sqlite_dbpage" virtual table.
-**
-** The sqlite_dbpage virtual table is used to read or write whole raw
+/************** Begin file dbpage.c ******************************************/
+/*
+** 2017-10-11
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file contains an implementation of the "sqlite_dbpage" virtual table.
+**
+** The sqlite_dbpage virtual table is used to read or write whole raw
** pages of the database file. The pager interface is used so that
-** uncommitted changes and changes recorded in the WAL file are correctly
-** retrieved.
-**
-** Usage example:
-**
-** SELECT data FROM sqlite_dbpage('aux1') WHERE pgno=123;
-**
-** This is an eponymous virtual table so it does not need to be created before
-** use. The optional argument to the sqlite_dbpage() table name is the
-** schema for the database file that is to be read. The default schema is
-** "main".
-**
-** The data field of sqlite_dbpage table can be updated. The new
-** value must be a BLOB which is the correct page size, otherwise the
-** update fails. Rows may not be deleted or inserted.
-*/
-
-/* #include "sqliteInt.h" ** Requires access to internal data structures ** */
-#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
- && !defined(SQLITE_OMIT_VIRTUALTABLE)
-
-typedef struct DbpageTable DbpageTable;
-typedef struct DbpageCursor DbpageCursor;
-
-struct DbpageCursor {
- sqlite3_vtab_cursor base; /* Base class. Must be first */
- int pgno; /* Current page number */
- int mxPgno; /* Last page to visit on this scan */
- Pager *pPager; /* Pager being read/written */
- DbPage *pPage1; /* Page 1 of the database */
- int iDb; /* Index of database to analyze */
- int szPage; /* Size of each page in bytes */
-};
-
-struct DbpageTable {
- sqlite3_vtab base; /* Base class. Must be first */
- sqlite3 *db; /* The database */
-};
-
-/* Columns */
-#define DBPAGE_COLUMN_PGNO 0
-#define DBPAGE_COLUMN_DATA 1
-#define DBPAGE_COLUMN_SCHEMA 2
-
-
-
-/*
-** Connect to or create a dbpagevfs virtual table.
-*/
-static int dbpageConnect(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- DbpageTable *pTab = 0;
- int rc = SQLITE_OK;
-
+** uncommitted changes and changes recorded in the WAL file are correctly
+** retrieved.
+**
+** Usage example:
+**
+** SELECT data FROM sqlite_dbpage('aux1') WHERE pgno=123;
+**
+** This is an eponymous virtual table so it does not need to be created before
+** use. The optional argument to the sqlite_dbpage() table name is the
+** schema for the database file that is to be read. The default schema is
+** "main".
+**
+** The data field of sqlite_dbpage table can be updated. The new
+** value must be a BLOB which is the correct page size, otherwise the
+** update fails. Rows may not be deleted or inserted.
+*/
+
+/* #include "sqliteInt.h" ** Requires access to internal data structures ** */
+#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
+ && !defined(SQLITE_OMIT_VIRTUALTABLE)
+
+typedef struct DbpageTable DbpageTable;
+typedef struct DbpageCursor DbpageCursor;
+
+struct DbpageCursor {
+ sqlite3_vtab_cursor base; /* Base class. Must be first */
+ int pgno; /* Current page number */
+ int mxPgno; /* Last page to visit on this scan */
+ Pager *pPager; /* Pager being read/written */
+ DbPage *pPage1; /* Page 1 of the database */
+ int iDb; /* Index of database to analyze */
+ int szPage; /* Size of each page in bytes */
+};
+
+struct DbpageTable {
+ sqlite3_vtab base; /* Base class. Must be first */
+ sqlite3 *db; /* The database */
+};
+
+/* Columns */
+#define DBPAGE_COLUMN_PGNO 0
+#define DBPAGE_COLUMN_DATA 1
+#define DBPAGE_COLUMN_SCHEMA 2
+
+
+
+/*
+** Connect to or create a dbpagevfs virtual table.
+*/
+static int dbpageConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ DbpageTable *pTab = 0;
+ int rc = SQLITE_OK;
+
sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
rc = sqlite3_declare_vtab(db,
- "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)");
- if( rc==SQLITE_OK ){
- pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable));
- if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
- }
-
- assert( rc==SQLITE_OK || pTab==0 );
- if( rc==SQLITE_OK ){
- memset(pTab, 0, sizeof(DbpageTable));
- pTab->db = db;
- }
-
- *ppVtab = (sqlite3_vtab*)pTab;
- return rc;
-}
-
-/*
-** Disconnect from or destroy a dbpagevfs virtual table.
-*/
-static int dbpageDisconnect(sqlite3_vtab *pVtab){
- sqlite3_free(pVtab);
- return SQLITE_OK;
-}
-
-/*
-** idxNum:
-**
-** 0 schema=main, full table scan
-** 1 schema=main, pgno=?1
-** 2 schema=?1, full table scan
-** 3 schema=?1, pgno=?2
-*/
-static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
- int i;
- int iPlan = 0;
-
- /* If there is a schema= constraint, it must be honored. Report a
- ** ridiculously large estimated cost if the schema= constraint is
- ** unavailable
- */
- for(i=0; i<pIdxInfo->nConstraint; i++){
- struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
- if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue;
- if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
- if( !p->usable ){
+ "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)");
+ if( rc==SQLITE_OK ){
+ pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable));
+ if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
+ }
+
+ assert( rc==SQLITE_OK || pTab==0 );
+ if( rc==SQLITE_OK ){
+ memset(pTab, 0, sizeof(DbpageTable));
+ pTab->db = db;
+ }
+
+ *ppVtab = (sqlite3_vtab*)pTab;
+ return rc;
+}
+
+/*
+** Disconnect from or destroy a dbpagevfs virtual table.
+*/
+static int dbpageDisconnect(sqlite3_vtab *pVtab){
+ sqlite3_free(pVtab);
+ return SQLITE_OK;
+}
+
+/*
+** idxNum:
+**
+** 0 schema=main, full table scan
+** 1 schema=main, pgno=?1
+** 2 schema=?1, full table scan
+** 3 schema=?1, pgno=?2
+*/
+static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+ int i;
+ int iPlan = 0;
+
+ /* If there is a schema= constraint, it must be honored. Report a
+ ** ridiculously large estimated cost if the schema= constraint is
+ ** unavailable
+ */
+ for(i=0; i<pIdxInfo->nConstraint; i++){
+ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
+ if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue;
+ if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ if( !p->usable ){
/* No solution. */
return SQLITE_CONSTRAINT;
- }
- iPlan = 2;
- pIdxInfo->aConstraintUsage[i].argvIndex = 1;
- pIdxInfo->aConstraintUsage[i].omit = 1;
- break;
- }
-
- /* If we reach this point, it means that either there is no schema=
- ** constraint (in which case we use the "main" schema) or else the
- ** schema constraint was accepted. Lower the estimated cost accordingly
- */
- pIdxInfo->estimatedCost = 1.0e6;
-
- /* Check for constraints against pgno */
- for(i=0; i<pIdxInfo->nConstraint; i++){
- struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
- if( p->usable && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
- pIdxInfo->estimatedRows = 1;
- pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
- pIdxInfo->estimatedCost = 1.0;
- pIdxInfo->aConstraintUsage[i].argvIndex = iPlan ? 2 : 1;
- pIdxInfo->aConstraintUsage[i].omit = 1;
- iPlan |= 1;
- break;
- }
- }
- pIdxInfo->idxNum = iPlan;
-
- if( pIdxInfo->nOrderBy>=1
- && pIdxInfo->aOrderBy[0].iColumn<=0
- && pIdxInfo->aOrderBy[0].desc==0
- ){
- pIdxInfo->orderByConsumed = 1;
- }
- return SQLITE_OK;
-}
-
-/*
-** Open a new dbpagevfs cursor.
-*/
-static int dbpageOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
- DbpageCursor *pCsr;
-
- pCsr = (DbpageCursor *)sqlite3_malloc64(sizeof(DbpageCursor));
- if( pCsr==0 ){
- return SQLITE_NOMEM_BKPT;
- }else{
- memset(pCsr, 0, sizeof(DbpageCursor));
- pCsr->base.pVtab = pVTab;
- pCsr->pgno = -1;
- }
-
- *ppCursor = (sqlite3_vtab_cursor *)pCsr;
- return SQLITE_OK;
-}
-
-/*
-** Close a dbpagevfs cursor.
-*/
-static int dbpageClose(sqlite3_vtab_cursor *pCursor){
- DbpageCursor *pCsr = (DbpageCursor *)pCursor;
- if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1);
- sqlite3_free(pCsr);
- return SQLITE_OK;
-}
-
-/*
-** Move a dbpagevfs cursor to the next entry in the file.
-*/
-static int dbpageNext(sqlite3_vtab_cursor *pCursor){
- int rc = SQLITE_OK;
- DbpageCursor *pCsr = (DbpageCursor *)pCursor;
- pCsr->pgno++;
- return rc;
-}
-
-static int dbpageEof(sqlite3_vtab_cursor *pCursor){
- DbpageCursor *pCsr = (DbpageCursor *)pCursor;
- return pCsr->pgno > pCsr->mxPgno;
-}
-
-/*
-** idxNum:
-**
-** 0 schema=main, full table scan
-** 1 schema=main, pgno=?1
-** 2 schema=?1, full table scan
-** 3 schema=?1, pgno=?2
-**
-** idxStr is not used
-*/
-static int dbpageFilter(
+ }
+ iPlan = 2;
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ break;
+ }
+
+ /* If we reach this point, it means that either there is no schema=
+ ** constraint (in which case we use the "main" schema) or else the
+ ** schema constraint was accepted. Lower the estimated cost accordingly
+ */
+ pIdxInfo->estimatedCost = 1.0e6;
+
+ /* Check for constraints against pgno */
+ for(i=0; i<pIdxInfo->nConstraint; i++){
+ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
+ if( p->usable && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+ pIdxInfo->estimatedRows = 1;
+ pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
+ pIdxInfo->estimatedCost = 1.0;
+ pIdxInfo->aConstraintUsage[i].argvIndex = iPlan ? 2 : 1;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ iPlan |= 1;
+ break;
+ }
+ }
+ pIdxInfo->idxNum = iPlan;
+
+ if( pIdxInfo->nOrderBy>=1
+ && pIdxInfo->aOrderBy[0].iColumn<=0
+ && pIdxInfo->aOrderBy[0].desc==0
+ ){
+ pIdxInfo->orderByConsumed = 1;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Open a new dbpagevfs cursor.
+*/
+static int dbpageOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
+ DbpageCursor *pCsr;
+
+ pCsr = (DbpageCursor *)sqlite3_malloc64(sizeof(DbpageCursor));
+ if( pCsr==0 ){
+ return SQLITE_NOMEM_BKPT;
+ }else{
+ memset(pCsr, 0, sizeof(DbpageCursor));
+ pCsr->base.pVtab = pVTab;
+ pCsr->pgno = -1;
+ }
+
+ *ppCursor = (sqlite3_vtab_cursor *)pCsr;
+ return SQLITE_OK;
+}
+
+/*
+** Close a dbpagevfs cursor.
+*/
+static int dbpageClose(sqlite3_vtab_cursor *pCursor){
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1);
+ sqlite3_free(pCsr);
+ return SQLITE_OK;
+}
+
+/*
+** Move a dbpagevfs cursor to the next entry in the file.
+*/
+static int dbpageNext(sqlite3_vtab_cursor *pCursor){
+ int rc = SQLITE_OK;
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ pCsr->pgno++;
+ return rc;
+}
+
+static int dbpageEof(sqlite3_vtab_cursor *pCursor){
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ return pCsr->pgno > pCsr->mxPgno;
+}
+
+/*
+** idxNum:
+**
+** 0 schema=main, full table scan
+** 1 schema=main, pgno=?1
+** 2 schema=?1, full table scan
+** 3 schema=?1, pgno=?2
+**
+** idxStr is not used
+*/
+static int dbpageFilter(
sqlite3_vtab_cursor *pCursor,
- int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv
-){
- DbpageCursor *pCsr = (DbpageCursor *)pCursor;
- DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
- int rc;
- sqlite3 *db = pTab->db;
- Btree *pBt;
-
- /* Default setting is no rows of result */
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
+ int rc;
+ sqlite3 *db = pTab->db;
+ Btree *pBt;
+
+ /* Default setting is no rows of result */
pCsr->pgno = 1;
- pCsr->mxPgno = 0;
-
- if( idxNum & 2 ){
- const char *zSchema;
- assert( argc>=1 );
- zSchema = (const char*)sqlite3_value_text(argv[0]);
- pCsr->iDb = sqlite3FindDbName(db, zSchema);
- if( pCsr->iDb<0 ) return SQLITE_OK;
- }else{
- pCsr->iDb = 0;
- }
- pBt = db->aDb[pCsr->iDb].pBt;
- if( pBt==0 ) return SQLITE_OK;
- pCsr->pPager = sqlite3BtreePager(pBt);
- pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
- pCsr->mxPgno = sqlite3BtreeLastPage(pBt);
- if( idxNum & 1 ){
- assert( argc>(idxNum>>1) );
- pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]);
- if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){
- pCsr->pgno = 1;
- pCsr->mxPgno = 0;
- }else{
- pCsr->mxPgno = pCsr->pgno;
- }
- }else{
- assert( pCsr->pgno==1 );
- }
- if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1);
- rc = sqlite3PagerGet(pCsr->pPager, 1, &pCsr->pPage1, 0);
- return rc;
-}
-
-static int dbpageColumn(
+ pCsr->mxPgno = 0;
+
+ if( idxNum & 2 ){
+ const char *zSchema;
+ assert( argc>=1 );
+ zSchema = (const char*)sqlite3_value_text(argv[0]);
+ pCsr->iDb = sqlite3FindDbName(db, zSchema);
+ if( pCsr->iDb<0 ) return SQLITE_OK;
+ }else{
+ pCsr->iDb = 0;
+ }
+ pBt = db->aDb[pCsr->iDb].pBt;
+ if( pBt==0 ) return SQLITE_OK;
+ pCsr->pPager = sqlite3BtreePager(pBt);
+ pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
+ pCsr->mxPgno = sqlite3BtreeLastPage(pBt);
+ if( idxNum & 1 ){
+ assert( argc>(idxNum>>1) );
+ pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]);
+ if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){
+ pCsr->pgno = 1;
+ pCsr->mxPgno = 0;
+ }else{
+ pCsr->mxPgno = pCsr->pgno;
+ }
+ }else{
+ assert( pCsr->pgno==1 );
+ }
+ if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1);
+ rc = sqlite3PagerGet(pCsr->pPager, 1, &pCsr->pPage1, 0);
+ return rc;
+}
+
+static int dbpageColumn(
sqlite3_vtab_cursor *pCursor,
sqlite3_context *ctx,
- int i
-){
- DbpageCursor *pCsr = (DbpageCursor *)pCursor;
- int rc = SQLITE_OK;
- switch( i ){
- case 0: { /* pgno */
- sqlite3_result_int(ctx, pCsr->pgno);
- break;
- }
- case 1: { /* data */
- DbPage *pDbPage = 0;
- rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
- if( rc==SQLITE_OK ){
- sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage,
- SQLITE_TRANSIENT);
- }
- sqlite3PagerUnref(pDbPage);
- break;
- }
- default: { /* schema */
- sqlite3 *db = sqlite3_context_db_handle(ctx);
- sqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC);
- break;
- }
- }
- return SQLITE_OK;
-}
-
-static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
- DbpageCursor *pCsr = (DbpageCursor *)pCursor;
- *pRowid = pCsr->pgno;
- return SQLITE_OK;
-}
-
-static int dbpageUpdate(
- sqlite3_vtab *pVtab,
- int argc,
- sqlite3_value **argv,
- sqlite_int64 *pRowid
-){
- DbpageTable *pTab = (DbpageTable *)pVtab;
- Pgno pgno;
- DbPage *pDbPage = 0;
- int rc = SQLITE_OK;
- char *zErr = 0;
- const char *zSchema;
- int iDb;
- Btree *pBt;
- Pager *pPager;
- int szPage;
-
+ int i
+){
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ int rc = SQLITE_OK;
+ switch( i ){
+ case 0: { /* pgno */
+ sqlite3_result_int(ctx, pCsr->pgno);
+ break;
+ }
+ case 1: { /* data */
+ DbPage *pDbPage = 0;
+ rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage,
+ SQLITE_TRANSIENT);
+ }
+ sqlite3PagerUnref(pDbPage);
+ break;
+ }
+ default: { /* schema */
+ sqlite3 *db = sqlite3_context_db_handle(ctx);
+ sqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC);
+ break;
+ }
+ }
+ return SQLITE_OK;
+}
+
+static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ *pRowid = pCsr->pgno;
+ return SQLITE_OK;
+}
+
+static int dbpageUpdate(
+ sqlite3_vtab *pVtab,
+ int argc,
+ sqlite3_value **argv,
+ sqlite_int64 *pRowid
+){
+ DbpageTable *pTab = (DbpageTable *)pVtab;
+ Pgno pgno;
+ DbPage *pDbPage = 0;
+ int rc = SQLITE_OK;
+ char *zErr = 0;
+ const char *zSchema;
+ int iDb;
+ Btree *pBt;
+ Pager *pPager;
+ int szPage;
+
if( pTab->db->flags & SQLITE_Defensive ){
zErr = "read-only";
goto update_fail;
}
- if( argc==1 ){
- zErr = "cannot delete";
- goto update_fail;
- }
- pgno = sqlite3_value_int(argv[0]);
- if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
- zErr = "cannot insert";
- goto update_fail;
- }
- zSchema = (const char*)sqlite3_value_text(argv[4]);
- iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1;
- if( iDb<0 ){
- zErr = "no such schema";
- goto update_fail;
- }
- pBt = pTab->db->aDb[iDb].pBt;
- if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){
- zErr = "bad page number";
- goto update_fail;
- }
- szPage = sqlite3BtreeGetPageSize(pBt);
+ if( argc==1 ){
+ zErr = "cannot delete";
+ goto update_fail;
+ }
+ pgno = sqlite3_value_int(argv[0]);
+ if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
+ zErr = "cannot insert";
+ goto update_fail;
+ }
+ zSchema = (const char*)sqlite3_value_text(argv[4]);
+ iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1;
+ if( iDb<0 ){
+ zErr = "no such schema";
+ goto update_fail;
+ }
+ pBt = pTab->db->aDb[iDb].pBt;
+ if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){
+ zErr = "bad page number";
+ goto update_fail;
+ }
+ szPage = sqlite3BtreeGetPageSize(pBt);
if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
- || sqlite3_value_bytes(argv[3])!=szPage
- ){
- zErr = "bad page value";
- goto update_fail;
- }
- pPager = sqlite3BtreePager(pBt);
- rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerWrite(pDbPage);
- if( rc==SQLITE_OK ){
- memcpy(sqlite3PagerGetData(pDbPage),
- sqlite3_value_blob(argv[3]),
- szPage);
- }
- }
- sqlite3PagerUnref(pDbPage);
- return rc;
-
-update_fail:
- sqlite3_free(pVtab->zErrMsg);
- pVtab->zErrMsg = sqlite3_mprintf("%s", zErr);
- return SQLITE_ERROR;
-}
-
-/* Since we do not know in advance which database files will be
-** written by the sqlite_dbpage virtual table, start a write transaction
-** on them all.
-*/
-static int dbpageBegin(sqlite3_vtab *pVtab){
- DbpageTable *pTab = (DbpageTable *)pVtab;
- sqlite3 *db = pTab->db;
- int i;
- for(i=0; i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
+ || sqlite3_value_bytes(argv[3])!=szPage
+ ){
+ zErr = "bad page value";
+ goto update_fail;
+ }
+ pPager = sqlite3BtreePager(pBt);
+ rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerWrite(pDbPage);
+ if( rc==SQLITE_OK ){
+ memcpy(sqlite3PagerGetData(pDbPage),
+ sqlite3_value_blob(argv[3]),
+ szPage);
+ }
+ }
+ sqlite3PagerUnref(pDbPage);
+ return rc;
+
+update_fail:
+ sqlite3_free(pVtab->zErrMsg);
+ pVtab->zErrMsg = sqlite3_mprintf("%s", zErr);
+ return SQLITE_ERROR;
+}
+
+/* Since we do not know in advance which database files will be
+** written by the sqlite_dbpage virtual table, start a write transaction
+** on them all.
+*/
+static int dbpageBegin(sqlite3_vtab *pVtab){
+ DbpageTable *pTab = (DbpageTable *)pVtab;
+ sqlite3 *db = pTab->db;
+ int i;
+ for(i=0; i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0);
- }
- return SQLITE_OK;
-}
-
-
-/*
-** Invoke this routine to register the "dbpage" virtual table module
-*/
-SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){
- static sqlite3_module dbpage_module = {
- 0, /* iVersion */
- dbpageConnect, /* xCreate */
- dbpageConnect, /* xConnect */
- dbpageBestIndex, /* xBestIndex */
- dbpageDisconnect, /* xDisconnect */
- dbpageDisconnect, /* xDestroy */
- dbpageOpen, /* xOpen - open a cursor */
- dbpageClose, /* xClose - close a cursor */
- dbpageFilter, /* xFilter - configure scan constraints */
- dbpageNext, /* xNext - advance a cursor */
- dbpageEof, /* xEof - check for end of scan */
- dbpageColumn, /* xColumn - read data */
- dbpageRowid, /* xRowid - read data */
- dbpageUpdate, /* xUpdate */
- dbpageBegin, /* xBegin */
- 0, /* xSync */
- 0, /* xCommit */
- 0, /* xRollback */
- 0, /* xFindMethod */
- 0, /* xRename */
- 0, /* xSavepoint */
- 0, /* xRelease */
- 0, /* xRollbackTo */
+ }
+ return SQLITE_OK;
+}
+
+
+/*
+** Invoke this routine to register the "dbpage" virtual table module
+*/
+SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){
+ static sqlite3_module dbpage_module = {
+ 0, /* iVersion */
+ dbpageConnect, /* xCreate */
+ dbpageConnect, /* xConnect */
+ dbpageBestIndex, /* xBestIndex */
+ dbpageDisconnect, /* xDisconnect */
+ dbpageDisconnect, /* xDestroy */
+ dbpageOpen, /* xOpen - open a cursor */
+ dbpageClose, /* xClose - close a cursor */
+ dbpageFilter, /* xFilter - configure scan constraints */
+ dbpageNext, /* xNext - advance a cursor */
+ dbpageEof, /* xEof - check for end of scan */
+ dbpageColumn, /* xColumn - read data */
+ dbpageRowid, /* xRowid - read data */
+ dbpageUpdate, /* xUpdate */
+ dbpageBegin, /* xBegin */
+ 0, /* xSync */
+ 0, /* xCommit */
+ 0, /* xRollback */
+ 0, /* xFindMethod */
+ 0, /* xRename */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0, /* xRollbackTo */
0 /* xShadowName */
- };
- return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
-}
-#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
-SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
-#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
-
-/************** End of dbpage.c **********************************************/
-/************** Begin file sqlite3session.c **********************************/
-
-#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
-/* #include "sqlite3session.h" */
-/* #include <assert.h> */
-/* #include <string.h> */
-
-#ifndef SQLITE_AMALGAMATION
-/* # include "sqliteInt.h" */
-/* # include "vdbeInt.h" */
-#endif
-
-typedef struct SessionTable SessionTable;
-typedef struct SessionChange SessionChange;
-typedef struct SessionBuffer SessionBuffer;
-typedef struct SessionInput SessionInput;
-
-/*
-** Minimum chunk size used by streaming versions of functions.
-*/
-#ifndef SESSIONS_STRM_CHUNK_SIZE
-# ifdef SQLITE_TEST
-# define SESSIONS_STRM_CHUNK_SIZE 64
-# else
-# define SESSIONS_STRM_CHUNK_SIZE 1024
-# endif
-#endif
-
+ };
+ return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
+}
+#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
+SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
+#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
+
+/************** End of dbpage.c **********************************************/
+/************** Begin file sqlite3session.c **********************************/
+
+#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+/* #include "sqlite3session.h" */
+/* #include <assert.h> */
+/* #include <string.h> */
+
+#ifndef SQLITE_AMALGAMATION
+/* # include "sqliteInt.h" */
+/* # include "vdbeInt.h" */
+#endif
+
+typedef struct SessionTable SessionTable;
+typedef struct SessionChange SessionChange;
+typedef struct SessionBuffer SessionBuffer;
+typedef struct SessionInput SessionInput;
+
+/*
+** Minimum chunk size used by streaming versions of functions.
+*/
+#ifndef SESSIONS_STRM_CHUNK_SIZE
+# ifdef SQLITE_TEST
+# define SESSIONS_STRM_CHUNK_SIZE 64
+# else
+# define SESSIONS_STRM_CHUNK_SIZE 1024
+# endif
+#endif
+
static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE;
-typedef struct SessionHook SessionHook;
-struct SessionHook {
- void *pCtx;
- int (*xOld)(void*,int,sqlite3_value**);
- int (*xNew)(void*,int,sqlite3_value**);
- int (*xCount)(void*);
- int (*xDepth)(void*);
-};
-
-/*
-** Session handle structure.
-*/
-struct sqlite3_session {
- sqlite3 *db; /* Database handle session is attached to */
- char *zDb; /* Name of database session is attached to */
+typedef struct SessionHook SessionHook;
+struct SessionHook {
+ void *pCtx;
+ int (*xOld)(void*,int,sqlite3_value**);
+ int (*xNew)(void*,int,sqlite3_value**);
+ int (*xCount)(void*);
+ int (*xDepth)(void*);
+};
+
+/*
+** Session handle structure.
+*/
+struct sqlite3_session {
+ sqlite3 *db; /* Database handle session is attached to */
+ char *zDb; /* Name of database session is attached to */
int bEnableSize; /* True if changeset_size() enabled */
- int bEnable; /* True if currently recording */
- int bIndirect; /* True if all changes are indirect */
- int bAutoAttach; /* True to auto-attach tables */
- int rc; /* Non-zero if an error has occurred */
- void *pFilterCtx; /* First argument to pass to xTableFilter */
- int (*xTableFilter)(void *pCtx, const char *zTab);
+ int bEnable; /* True if currently recording */
+ int bIndirect; /* True if all changes are indirect */
+ int bAutoAttach; /* True to auto-attach tables */
+ int rc; /* Non-zero if an error has occurred */
+ void *pFilterCtx; /* First argument to pass to xTableFilter */
+ int (*xTableFilter)(void *pCtx, const char *zTab);
i64 nMalloc; /* Number of bytes of data allocated */
i64 nMaxChangesetSize;
- sqlite3_value *pZeroBlob; /* Value containing X'' */
- sqlite3_session *pNext; /* Next session object on same db. */
- SessionTable *pTable; /* List of attached tables */
- SessionHook hook; /* APIs to grab new and old data with */
-};
-
-/*
-** Instances of this structure are used to build strings or binary records.
-*/
-struct SessionBuffer {
- u8 *aBuf; /* Pointer to changeset buffer */
- int nBuf; /* Size of buffer aBuf */
- int nAlloc; /* Size of allocation containing aBuf */
-};
-
-/*
+ sqlite3_value *pZeroBlob; /* Value containing X'' */
+ sqlite3_session *pNext; /* Next session object on same db. */
+ SessionTable *pTable; /* List of attached tables */
+ SessionHook hook; /* APIs to grab new and old data with */
+};
+
+/*
+** Instances of this structure are used to build strings or binary records.
+*/
+struct SessionBuffer {
+ u8 *aBuf; /* Pointer to changeset buffer */
+ int nBuf; /* Size of buffer aBuf */
+ int nAlloc; /* Size of allocation containing aBuf */
+};
+
+/*
** An object of this type is used internally as an abstraction for
-** input data. Input data may be supplied either as a single large buffer
-** (e.g. sqlite3changeset_start()) or using a stream function (e.g.
-** sqlite3changeset_start_strm()).
-*/
-struct SessionInput {
+** input data. Input data may be supplied either as a single large buffer
+** (e.g. sqlite3changeset_start()) or using a stream function (e.g.
+** sqlite3changeset_start_strm()).
+*/
+struct SessionInput {
int bNoDiscard; /* If true, do not discard in InputBuffer() */
- int iCurrent; /* Offset in aData[] of current change */
- int iNext; /* Offset in aData[] of next change */
- u8 *aData; /* Pointer to buffer containing changeset */
- int nData; /* Number of bytes in aData */
-
- SessionBuffer buf; /* Current read buffer */
- int (*xInput)(void*, void*, int*); /* Input stream call (or NULL) */
- void *pIn; /* First argument to xInput */
- int bEof; /* Set to true after xInput finished */
-};
-
-/*
-** Structure for changeset iterators.
-*/
-struct sqlite3_changeset_iter {
- SessionInput in; /* Input buffer or stream */
- SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */
- int bPatchset; /* True if this is a patchset */
+ int iCurrent; /* Offset in aData[] of current change */
+ int iNext; /* Offset in aData[] of next change */
+ u8 *aData; /* Pointer to buffer containing changeset */
+ int nData; /* Number of bytes in aData */
+
+ SessionBuffer buf; /* Current read buffer */
+ int (*xInput)(void*, void*, int*); /* Input stream call (or NULL) */
+ void *pIn; /* First argument to xInput */
+ int bEof; /* Set to true after xInput finished */
+};
+
+/*
+** Structure for changeset iterators.
+*/
+struct sqlite3_changeset_iter {
+ SessionInput in; /* Input buffer or stream */
+ SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */
+ int bPatchset; /* True if this is a patchset */
int bInvert; /* True to invert changeset */
int bSkipEmpty; /* Skip noop UPDATE changes */
- int rc; /* Iterator error code */
- sqlite3_stmt *pConflict; /* Points to conflicting row, if any */
- char *zTab; /* Current table */
- int nCol; /* Number of columns in zTab */
- int op; /* Current operation */
- int bIndirect; /* True if current change was indirect */
- u8 *abPK; /* Primary key array */
- sqlite3_value **apValue; /* old.* and new.* values */
-};
-
-/*
-** Each session object maintains a set of the following structures, one
-** for each table the session object is monitoring. The structures are
-** stored in a linked list starting at sqlite3_session.pTable.
-**
-** The keys of the SessionTable.aChange[] hash table are all rows that have
-** been modified in any way since the session object was attached to the
-** table.
-**
-** The data associated with each hash-table entry is a structure containing
-** a subset of the initial values that the modified row contained at the
-** start of the session. Or no initial values if the row was inserted.
-*/
-struct SessionTable {
- SessionTable *pNext;
- char *zName; /* Local name of table */
- int nCol; /* Number of columns in table zName */
- int bStat1; /* True if this is sqlite_stat1 */
- const char **azCol; /* Column names */
- u8 *abPK; /* Array of primary key flags */
- int nEntry; /* Total number of entries in hash table */
- int nChange; /* Size of apChange[] array */
- SessionChange **apChange; /* Hash table buckets */
-};
-
-/*
-** RECORD FORMAT:
-**
+ int rc; /* Iterator error code */
+ sqlite3_stmt *pConflict; /* Points to conflicting row, if any */
+ char *zTab; /* Current table */
+ int nCol; /* Number of columns in zTab */
+ int op; /* Current operation */
+ int bIndirect; /* True if current change was indirect */
+ u8 *abPK; /* Primary key array */
+ sqlite3_value **apValue; /* old.* and new.* values */
+};
+
+/*
+** Each session object maintains a set of the following structures, one
+** for each table the session object is monitoring. The structures are
+** stored in a linked list starting at sqlite3_session.pTable.
+**
+** The keys of the SessionTable.aChange[] hash table are all rows that have
+** been modified in any way since the session object was attached to the
+** table.
+**
+** The data associated with each hash-table entry is a structure containing
+** a subset of the initial values that the modified row contained at the
+** start of the session. Or no initial values if the row was inserted.
+*/
+struct SessionTable {
+ SessionTable *pNext;
+ char *zName; /* Local name of table */
+ int nCol; /* Number of columns in table zName */
+ int bStat1; /* True if this is sqlite_stat1 */
+ const char **azCol; /* Column names */
+ u8 *abPK; /* Array of primary key flags */
+ int nEntry; /* Total number of entries in hash table */
+ int nChange; /* Size of apChange[] array */
+ SessionChange **apChange; /* Hash table buckets */
+};
+
+/*
+** RECORD FORMAT:
+**
** The following record format is similar to (but not compatible with) that
** used in SQLite database files. This format is used as part of the
-** change-set binary format, and so must be architecture independent.
-**
-** Unlike the SQLite database record format, each field is self-contained -
-** there is no separation of header and data. Each field begins with a
-** single byte describing its type, as follows:
-**
-** 0x00: Undefined value.
-** 0x01: Integer value.
-** 0x02: Real value.
-** 0x03: Text value.
-** 0x04: Blob value.
-** 0x05: SQL NULL value.
-**
-** Note that the above match the definitions of SQLITE_INTEGER, SQLITE_TEXT
-** and so on in sqlite3.h. For undefined and NULL values, the field consists
-** only of the single type byte. For other types of values, the type byte
-** is followed by:
-**
-** Text values:
-** A varint containing the number of bytes in the value (encoded using
-** UTF-8). Followed by a buffer containing the UTF-8 representation
-** of the text value. There is no nul terminator.
-**
-** Blob values:
-** A varint containing the number of bytes in the value, followed by
-** a buffer containing the value itself.
-**
-** Integer values:
-** An 8-byte big-endian integer value.
-**
-** Real values:
-** An 8-byte big-endian IEEE 754-2008 real value.
-**
+** change-set binary format, and so must be architecture independent.
+**
+** Unlike the SQLite database record format, each field is self-contained -
+** there is no separation of header and data. Each field begins with a
+** single byte describing its type, as follows:
+**
+** 0x00: Undefined value.
+** 0x01: Integer value.
+** 0x02: Real value.
+** 0x03: Text value.
+** 0x04: Blob value.
+** 0x05: SQL NULL value.
+**
+** Note that the above match the definitions of SQLITE_INTEGER, SQLITE_TEXT
+** and so on in sqlite3.h. For undefined and NULL values, the field consists
+** only of the single type byte. For other types of values, the type byte
+** is followed by:
+**
+** Text values:
+** A varint containing the number of bytes in the value (encoded using
+** UTF-8). Followed by a buffer containing the UTF-8 representation
+** of the text value. There is no nul terminator.
+**
+** Blob values:
+** A varint containing the number of bytes in the value, followed by
+** a buffer containing the value itself.
+**
+** Integer values:
+** An 8-byte big-endian integer value.
+**
+** Real values:
+** An 8-byte big-endian IEEE 754-2008 real value.
+**
** Varint values are encoded in the same way as varints in the SQLite
-** record format.
-**
-** CHANGESET FORMAT:
-**
-** A changeset is a collection of DELETE, UPDATE and INSERT operations on
-** one or more tables. Operations on a single table are grouped together,
-** but may occur in any order (i.e. deletes, updates and inserts are all
-** mixed together).
-**
-** Each group of changes begins with a table header:
-**
-** 1 byte: Constant 0x54 (capital 'T')
-** Varint: Number of columns in the table.
-** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
-** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
-**
-** Followed by one or more changes to the table.
-**
-** 1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
-** 1 byte: The "indirect-change" flag.
-** old.* record: (delete and update only)
-** new.* record: (insert and update only)
-**
-** The "old.*" and "new.*" records, if present, are N field records in the
-** format described above under "RECORD FORMAT", where N is the number of
-** columns in the table. The i'th field of each record is associated with
-** the i'th column of the table, counting from left to right in the order
-** in which columns were declared in the CREATE TABLE statement.
-**
-** The new.* record that is part of each INSERT change contains the values
-** that make up the new row. Similarly, the old.* record that is part of each
+** record format.
+**
+** CHANGESET FORMAT:
+**
+** A changeset is a collection of DELETE, UPDATE and INSERT operations on
+** one or more tables. Operations on a single table are grouped together,
+** but may occur in any order (i.e. deletes, updates and inserts are all
+** mixed together).
+**
+** Each group of changes begins with a table header:
+**
+** 1 byte: Constant 0x54 (capital 'T')
+** Varint: Number of columns in the table.
+** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
+** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
+**
+** Followed by one or more changes to the table.
+**
+** 1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
+** 1 byte: The "indirect-change" flag.
+** old.* record: (delete and update only)
+** new.* record: (insert and update only)
+**
+** The "old.*" and "new.*" records, if present, are N field records in the
+** format described above under "RECORD FORMAT", where N is the number of
+** columns in the table. The i'th field of each record is associated with
+** the i'th column of the table, counting from left to right in the order
+** in which columns were declared in the CREATE TABLE statement.
+**
+** The new.* record that is part of each INSERT change contains the values
+** that make up the new row. Similarly, the old.* record that is part of each
** DELETE change contains the values that made up the row that was deleted
-** from the database. In the changeset format, the records that are part
-** of INSERT or DELETE changes never contain any undefined (type byte 0x00)
-** fields.
-**
-** Within the old.* record associated with an UPDATE change, all fields
-** associated with table columns that are not PRIMARY KEY columns and are
-** not modified by the UPDATE change are set to "undefined". Other fields
-** are set to the values that made up the row before the UPDATE that the
+** from the database. In the changeset format, the records that are part
+** of INSERT or DELETE changes never contain any undefined (type byte 0x00)
+** fields.
+**
+** Within the old.* record associated with an UPDATE change, all fields
+** associated with table columns that are not PRIMARY KEY columns and are
+** not modified by the UPDATE change are set to "undefined". Other fields
+** are set to the values that made up the row before the UPDATE that the
** change records took place. Within the new.* record, fields associated
** with table columns modified by the UPDATE change contain the new
-** values. Fields associated with table columns that are not modified
-** are set to "undefined".
-**
-** PATCHSET FORMAT:
-**
-** A patchset is also a collection of changes. It is similar to a changeset,
-** but leaves undefined those fields that are not useful if no conflict
-** resolution is required when applying the changeset.
-**
-** Each group of changes begins with a table header:
-**
-** 1 byte: Constant 0x50 (capital 'P')
-** Varint: Number of columns in the table.
-** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
-** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
-**
-** Followed by one or more changes to the table.
-**
-** 1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
-** 1 byte: The "indirect-change" flag.
-** single record: (PK fields for DELETE, PK and modified fields for UPDATE,
-** full record for INSERT).
-**
-** As in the changeset format, each field of the single record that is part
-** of a patchset change is associated with the correspondingly positioned
+** values. Fields associated with table columns that are not modified
+** are set to "undefined".
+**
+** PATCHSET FORMAT:
+**
+** A patchset is also a collection of changes. It is similar to a changeset,
+** but leaves undefined those fields that are not useful if no conflict
+** resolution is required when applying the changeset.
+**
+** Each group of changes begins with a table header:
+**
+** 1 byte: Constant 0x50 (capital 'P')
+** Varint: Number of columns in the table.
+** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
+** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
+**
+** Followed by one or more changes to the table.
+**
+** 1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
+** 1 byte: The "indirect-change" flag.
+** single record: (PK fields for DELETE, PK and modified fields for UPDATE,
+** full record for INSERT).
+**
+** As in the changeset format, each field of the single record that is part
+** of a patchset change is associated with the correspondingly positioned
** table column, counting from left to right within the CREATE TABLE
-** statement.
-**
-** For a DELETE change, all fields within the record except those associated
+** statement.
+**
+** For a DELETE change, all fields within the record except those associated
** with PRIMARY KEY columns are omitted. The PRIMARY KEY fields contain the
** values identifying the row to delete.
-**
-** For an UPDATE change, all fields except those associated with PRIMARY KEY
-** columns and columns that are modified by the UPDATE are set to "undefined".
-** PRIMARY KEY fields contain the values identifying the table row to update,
-** and fields associated with modified columns contain the new column values.
-**
-** The records associated with INSERT changes are in the same format as for
-** changesets. It is not possible for a record associated with an INSERT
-** change to contain a field set to "undefined".
+**
+** For an UPDATE change, all fields except those associated with PRIMARY KEY
+** columns and columns that are modified by the UPDATE are set to "undefined".
+** PRIMARY KEY fields contain the values identifying the table row to update,
+** and fields associated with modified columns contain the new column values.
+**
+** The records associated with INSERT changes are in the same format as for
+** changesets. It is not possible for a record associated with an INSERT
+** change to contain a field set to "undefined".
**
** REBASE BLOB FORMAT:
**
@@ -208757,156 +208757,156 @@ struct SessionTable {
** the conflicting change was an UPDATE, then the single record is a copy
** of the new.* record with the PK fields filled in based on the original
** old.* record.
-*/
-
-/*
-** For each row modified during a session, there exists a single instance of
-** this structure stored in a SessionTable.aChange[] hash table.
-*/
-struct SessionChange {
+*/
+
+/*
+** For each row modified during a session, there exists a single instance of
+** this structure stored in a SessionTable.aChange[] hash table.
+*/
+struct SessionChange {
u8 op; /* One of UPDATE, DELETE, INSERT */
u8 bIndirect; /* True if this change is "indirect" */
int nMaxSize; /* Max size of eventual changeset record */
- int nRecord; /* Number of bytes in buffer aRecord[] */
- u8 *aRecord; /* Buffer containing old.* record */
- SessionChange *pNext; /* For hash-table collisions */
-};
-
-/*
+ int nRecord; /* Number of bytes in buffer aRecord[] */
+ u8 *aRecord; /* Buffer containing old.* record */
+ SessionChange *pNext; /* For hash-table collisions */
+};
+
+/*
** Write a varint with value iVal into the buffer at aBuf. Return the
-** number of bytes written.
-*/
-static int sessionVarintPut(u8 *aBuf, int iVal){
- return putVarint32(aBuf, iVal);
-}
-
-/*
-** Return the number of bytes required to store value iVal as a varint.
-*/
-static int sessionVarintLen(int iVal){
- return sqlite3VarintLen(iVal);
-}
-
-/*
+** number of bytes written.
+*/
+static int sessionVarintPut(u8 *aBuf, int iVal){
+ return putVarint32(aBuf, iVal);
+}
+
+/*
+** Return the number of bytes required to store value iVal as a varint.
+*/
+static int sessionVarintLen(int iVal){
+ return sqlite3VarintLen(iVal);
+}
+
+/*
** Read a varint value from aBuf[] into *piVal. Return the number of
-** bytes read.
-*/
-static int sessionVarintGet(u8 *aBuf, int *piVal){
- return getVarint32(aBuf, *piVal);
-}
-
-/* Load an unaligned and unsigned 32-bit integer */
-#define SESSION_UINT32(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
-
-/*
-** Read a 64-bit big-endian integer value from buffer aRec[]. Return
-** the value read.
-*/
-static sqlite3_int64 sessionGetI64(u8 *aRec){
- u64 x = SESSION_UINT32(aRec);
- u32 y = SESSION_UINT32(aRec+4);
- x = (x<<32) + y;
- return (sqlite3_int64)x;
-}
-
-/*
-** Write a 64-bit big-endian integer value to the buffer aBuf[].
-*/
-static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){
- aBuf[0] = (i>>56) & 0xFF;
- aBuf[1] = (i>>48) & 0xFF;
- aBuf[2] = (i>>40) & 0xFF;
- aBuf[3] = (i>>32) & 0xFF;
- aBuf[4] = (i>>24) & 0xFF;
- aBuf[5] = (i>>16) & 0xFF;
- aBuf[6] = (i>> 8) & 0xFF;
- aBuf[7] = (i>> 0) & 0xFF;
-}
-
-/*
-** This function is used to serialize the contents of value pValue (see
-** comment titled "RECORD FORMAT" above).
-**
+** bytes read.
+*/
+static int sessionVarintGet(u8 *aBuf, int *piVal){
+ return getVarint32(aBuf, *piVal);
+}
+
+/* Load an unaligned and unsigned 32-bit integer */
+#define SESSION_UINT32(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
+
+/*
+** Read a 64-bit big-endian integer value from buffer aRec[]. Return
+** the value read.
+*/
+static sqlite3_int64 sessionGetI64(u8 *aRec){
+ u64 x = SESSION_UINT32(aRec);
+ u32 y = SESSION_UINT32(aRec+4);
+ x = (x<<32) + y;
+ return (sqlite3_int64)x;
+}
+
+/*
+** Write a 64-bit big-endian integer value to the buffer aBuf[].
+*/
+static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){
+ aBuf[0] = (i>>56) & 0xFF;
+ aBuf[1] = (i>>48) & 0xFF;
+ aBuf[2] = (i>>40) & 0xFF;
+ aBuf[3] = (i>>32) & 0xFF;
+ aBuf[4] = (i>>24) & 0xFF;
+ aBuf[5] = (i>>16) & 0xFF;
+ aBuf[6] = (i>> 8) & 0xFF;
+ aBuf[7] = (i>> 0) & 0xFF;
+}
+
+/*
+** This function is used to serialize the contents of value pValue (see
+** comment titled "RECORD FORMAT" above).
+**
** If it is non-NULL, the serialized form of the value is written to
-** buffer aBuf. *pnWrite is set to the number of bytes written before
-** returning. Or, if aBuf is NULL, the only thing this function does is
-** set *pnWrite.
-**
-** If no error occurs, SQLITE_OK is returned. Or, if an OOM error occurs
+** buffer aBuf. *pnWrite is set to the number of bytes written before
+** returning. Or, if aBuf is NULL, the only thing this function does is
+** set *pnWrite.
+**
+** If no error occurs, SQLITE_OK is returned. Or, if an OOM error occurs
** within a call to sqlite3_value_text() (may fail if the db is utf-16))
-** SQLITE_NOMEM is returned.
-*/
-static int sessionSerializeValue(
- u8 *aBuf, /* If non-NULL, write serialized value here */
- sqlite3_value *pValue, /* Value to serialize */
+** SQLITE_NOMEM is returned.
+*/
+static int sessionSerializeValue(
+ u8 *aBuf, /* If non-NULL, write serialized value here */
+ sqlite3_value *pValue, /* Value to serialize */
sqlite3_int64 *pnWrite /* IN/OUT: Increment by bytes written */
-){
- int nByte; /* Size of serialized value in bytes */
-
- if( pValue ){
- int eType; /* Value type (SQLITE_NULL, TEXT etc.) */
+){
+ int nByte; /* Size of serialized value in bytes */
+
+ if( pValue ){
+ int eType; /* Value type (SQLITE_NULL, TEXT etc.) */
- eType = sqlite3_value_type(pValue);
- if( aBuf ) aBuf[0] = eType;
+ eType = sqlite3_value_type(pValue);
+ if( aBuf ) aBuf[0] = eType;
- switch( eType ){
+ switch( eType ){
case SQLITE_NULL:
- nByte = 1;
- break;
+ nByte = 1;
+ break;
case SQLITE_INTEGER:
- case SQLITE_FLOAT:
- if( aBuf ){
- /* TODO: SQLite does something special to deal with mixed-endian
- ** floating point values (e.g. ARM7). This code probably should
- ** too. */
- u64 i;
- if( eType==SQLITE_INTEGER ){
- i = (u64)sqlite3_value_int64(pValue);
- }else{
- double r;
- assert( sizeof(double)==8 && sizeof(u64)==8 );
- r = sqlite3_value_double(pValue);
- memcpy(&i, &r, 8);
- }
- sessionPutI64(&aBuf[1], i);
- }
+ case SQLITE_FLOAT:
+ if( aBuf ){
+ /* TODO: SQLite does something special to deal with mixed-endian
+ ** floating point values (e.g. ARM7). This code probably should
+ ** too. */
+ u64 i;
+ if( eType==SQLITE_INTEGER ){
+ i = (u64)sqlite3_value_int64(pValue);
+ }else{
+ double r;
+ assert( sizeof(double)==8 && sizeof(u64)==8 );
+ r = sqlite3_value_double(pValue);
+ memcpy(&i, &r, 8);
+ }
+ sessionPutI64(&aBuf[1], i);
+ }
nByte = 9;
- break;
-
- default: {
- u8 *z;
- int n;
- int nVarint;
-
- assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
- if( eType==SQLITE_TEXT ){
- z = (u8 *)sqlite3_value_text(pValue);
- }else{
- z = (u8 *)sqlite3_value_blob(pValue);
- }
- n = sqlite3_value_bytes(pValue);
- if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
- nVarint = sessionVarintLen(n);
-
- if( aBuf ){
- sessionVarintPut(&aBuf[1], n);
+ break;
+
+ default: {
+ u8 *z;
+ int n;
+ int nVarint;
+
+ assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
+ if( eType==SQLITE_TEXT ){
+ z = (u8 *)sqlite3_value_text(pValue);
+ }else{
+ z = (u8 *)sqlite3_value_blob(pValue);
+ }
+ n = sqlite3_value_bytes(pValue);
+ if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
+ nVarint = sessionVarintLen(n);
+
+ if( aBuf ){
+ sessionVarintPut(&aBuf[1], n);
if( n>0 ) memcpy(&aBuf[nVarint + 1], z, n);
- }
-
- nByte = 1 + nVarint + n;
- break;
- }
- }
- }else{
- nByte = 1;
- if( aBuf ) aBuf[0] = '\0';
- }
-
- if( pnWrite ) *pnWrite += nByte;
- return SQLITE_OK;
-}
-
+ }
+
+ nByte = 1 + nVarint + n;
+ break;
+ }
+ }
+ }else{
+ nByte = 1;
+ if( aBuf ) aBuf[0] = '\0';
+ }
+
+ if( pnWrite ) *pnWrite += nByte;
+ return SQLITE_OK;
+}
+
/*
** Allocate and return a pointer to a buffer nByte bytes in size. If
** pSession is not NULL, increase the sqlite3_session.nMalloc variable
@@ -208917,8 +208917,8 @@ static void *sessionMalloc64(sqlite3_session *pSession, i64 nByte){
if( pSession ) pSession->nMalloc += sqlite3_msize(pRet);
return pRet;
}
-
-/*
+
+/*
** Free buffer pFree, which must have been allocated by an earlier
** call to sessionMalloc64(). If pSession is not NULL, decrease the
** sqlite3_session.nMalloc counter by the number of bytes freed.
@@ -208929,582 +208929,582 @@ static void sessionFree(sqlite3_session *pSession, void *pFree){
}
/*
-** This macro is used to calculate hash key values for data structures. In
-** order to use this macro, the entire data structure must be represented
-** as a series of unsigned integers. In order to calculate a hash-key value
-** for a data structure represented as three such integers, the macro may
-** then be used as follows:
-**
-** int hash_key_value;
-** hash_key_value = HASH_APPEND(0, <value 1>);
-** hash_key_value = HASH_APPEND(hash_key_value, <value 2>);
-** hash_key_value = HASH_APPEND(hash_key_value, <value 3>);
-**
-** In practice, the data structures this macro is used for are the primary
-** key values of modified rows.
-*/
-#define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (unsigned int)(add)
-
-/*
-** Append the hash of the 64-bit integer passed as the second argument to the
-** hash-key value passed as the first. Return the new hash-key value.
-*/
-static unsigned int sessionHashAppendI64(unsigned int h, i64 i){
- h = HASH_APPEND(h, i & 0xFFFFFFFF);
- return HASH_APPEND(h, (i>>32)&0xFFFFFFFF);
-}
-
-/*
+** This macro is used to calculate hash key values for data structures. In
+** order to use this macro, the entire data structure must be represented
+** as a series of unsigned integers. In order to calculate a hash-key value
+** for a data structure represented as three such integers, the macro may
+** then be used as follows:
+**
+** int hash_key_value;
+** hash_key_value = HASH_APPEND(0, <value 1>);
+** hash_key_value = HASH_APPEND(hash_key_value, <value 2>);
+** hash_key_value = HASH_APPEND(hash_key_value, <value 3>);
+**
+** In practice, the data structures this macro is used for are the primary
+** key values of modified rows.
+*/
+#define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (unsigned int)(add)
+
+/*
+** Append the hash of the 64-bit integer passed as the second argument to the
+** hash-key value passed as the first. Return the new hash-key value.
+*/
+static unsigned int sessionHashAppendI64(unsigned int h, i64 i){
+ h = HASH_APPEND(h, i & 0xFFFFFFFF);
+ return HASH_APPEND(h, (i>>32)&0xFFFFFFFF);
+}
+
+/*
** Append the hash of the blob passed via the second and third arguments to
-** the hash-key value passed as the first. Return the new hash-key value.
-*/
-static unsigned int sessionHashAppendBlob(unsigned int h, int n, const u8 *z){
- int i;
- for(i=0; i<n; i++) h = HASH_APPEND(h, z[i]);
- return h;
-}
-
-/*
-** Append the hash of the data type passed as the second argument to the
-** hash-key value passed as the first. Return the new hash-key value.
-*/
-static unsigned int sessionHashAppendType(unsigned int h, int eType){
- return HASH_APPEND(h, eType);
-}
-
-/*
-** This function may only be called from within a pre-update callback.
+** the hash-key value passed as the first. Return the new hash-key value.
+*/
+static unsigned int sessionHashAppendBlob(unsigned int h, int n, const u8 *z){
+ int i;
+ for(i=0; i<n; i++) h = HASH_APPEND(h, z[i]);
+ return h;
+}
+
+/*
+** Append the hash of the data type passed as the second argument to the
+** hash-key value passed as the first. Return the new hash-key value.
+*/
+static unsigned int sessionHashAppendType(unsigned int h, int eType){
+ return HASH_APPEND(h, eType);
+}
+
+/*
+** This function may only be called from within a pre-update callback.
** It calculates a hash based on the primary key values of the old.* or
-** new.* row currently available and, assuming no error occurs, writes it to
-** *piHash before returning. If the primary key contains one or more NULL
-** values, *pbNullPK is set to true before returning.
-**
-** If an error occurs, an SQLite error code is returned and the final values
-** of *piHash asn *pbNullPK are undefined. Otherwise, SQLITE_OK is returned
-** and the output variables are set as described above.
-*/
-static int sessionPreupdateHash(
- sqlite3_session *pSession, /* Session object that owns pTab */
- SessionTable *pTab, /* Session table handle */
- int bNew, /* True to hash the new.* PK */
- int *piHash, /* OUT: Hash value */
- int *pbNullPK /* OUT: True if there are NULL values in PK */
-){
- unsigned int h = 0; /* Hash value to return */
- int i; /* Used to iterate through columns */
-
- assert( *pbNullPK==0 );
- assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) );
- for(i=0; i<pTab->nCol; i++){
- if( pTab->abPK[i] ){
- int rc;
- int eType;
- sqlite3_value *pVal;
-
- if( bNew ){
- rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal);
- }else{
- rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal);
- }
- if( rc!=SQLITE_OK ) return rc;
-
- eType = sqlite3_value_type(pVal);
- h = sessionHashAppendType(h, eType);
- if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
- i64 iVal;
- if( eType==SQLITE_INTEGER ){
- iVal = sqlite3_value_int64(pVal);
- }else{
- double rVal = sqlite3_value_double(pVal);
- assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
- memcpy(&iVal, &rVal, 8);
- }
- h = sessionHashAppendI64(h, iVal);
- }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
- const u8 *z;
- int n;
- if( eType==SQLITE_TEXT ){
- z = (const u8 *)sqlite3_value_text(pVal);
- }else{
- z = (const u8 *)sqlite3_value_blob(pVal);
- }
- n = sqlite3_value_bytes(pVal);
- if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
- h = sessionHashAppendBlob(h, n, z);
- }else{
- assert( eType==SQLITE_NULL );
- assert( pTab->bStat1==0 || i!=1 );
- *pbNullPK = 1;
- }
- }
- }
-
- *piHash = (h % pTab->nChange);
- return SQLITE_OK;
-}
-
-/*
-** The buffer that the argument points to contains a serialized SQL value.
-** Return the number of bytes of space occupied by the value (including
-** the type byte).
-*/
-static int sessionSerialLen(u8 *a){
- int e = *a;
- int n;
+** new.* row currently available and, assuming no error occurs, writes it to
+** *piHash before returning. If the primary key contains one or more NULL
+** values, *pbNullPK is set to true before returning.
+**
+** If an error occurs, an SQLite error code is returned and the final values
+** of *piHash asn *pbNullPK are undefined. Otherwise, SQLITE_OK is returned
+** and the output variables are set as described above.
+*/
+static int sessionPreupdateHash(
+ sqlite3_session *pSession, /* Session object that owns pTab */
+ SessionTable *pTab, /* Session table handle */
+ int bNew, /* True to hash the new.* PK */
+ int *piHash, /* OUT: Hash value */
+ int *pbNullPK /* OUT: True if there are NULL values in PK */
+){
+ unsigned int h = 0; /* Hash value to return */
+ int i; /* Used to iterate through columns */
+
+ assert( *pbNullPK==0 );
+ assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) );
+ for(i=0; i<pTab->nCol; i++){
+ if( pTab->abPK[i] ){
+ int rc;
+ int eType;
+ sqlite3_value *pVal;
+
+ if( bNew ){
+ rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal);
+ }else{
+ rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal);
+ }
+ if( rc!=SQLITE_OK ) return rc;
+
+ eType = sqlite3_value_type(pVal);
+ h = sessionHashAppendType(h, eType);
+ if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+ i64 iVal;
+ if( eType==SQLITE_INTEGER ){
+ iVal = sqlite3_value_int64(pVal);
+ }else{
+ double rVal = sqlite3_value_double(pVal);
+ assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
+ memcpy(&iVal, &rVal, 8);
+ }
+ h = sessionHashAppendI64(h, iVal);
+ }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
+ const u8 *z;
+ int n;
+ if( eType==SQLITE_TEXT ){
+ z = (const u8 *)sqlite3_value_text(pVal);
+ }else{
+ z = (const u8 *)sqlite3_value_blob(pVal);
+ }
+ n = sqlite3_value_bytes(pVal);
+ if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
+ h = sessionHashAppendBlob(h, n, z);
+ }else{
+ assert( eType==SQLITE_NULL );
+ assert( pTab->bStat1==0 || i!=1 );
+ *pbNullPK = 1;
+ }
+ }
+ }
+
+ *piHash = (h % pTab->nChange);
+ return SQLITE_OK;
+}
+
+/*
+** The buffer that the argument points to contains a serialized SQL value.
+** Return the number of bytes of space occupied by the value (including
+** the type byte).
+*/
+static int sessionSerialLen(u8 *a){
+ int e = *a;
+ int n;
if( e==0 || e==0xFF ) return 1;
- if( e==SQLITE_NULL ) return 1;
- if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9;
- return sessionVarintGet(&a[1], &n) + 1 + n;
-}
-
-/*
-** Based on the primary key values stored in change aRecord, calculate a
-** hash key. Assume the has table has nBucket buckets. The hash keys
-** calculated by this function are compatible with those calculated by
-** sessionPreupdateHash().
-**
-** The bPkOnly argument is non-zero if the record at aRecord[] is from
-** a patchset DELETE. In this case the non-PK fields are omitted entirely.
-*/
-static unsigned int sessionChangeHash(
- SessionTable *pTab, /* Table handle */
- int bPkOnly, /* Record consists of PK fields only */
- u8 *aRecord, /* Change record */
- int nBucket /* Assume this many buckets in hash table */
-){
- unsigned int h = 0; /* Value to return */
- int i; /* Used to iterate through columns */
- u8 *a = aRecord; /* Used to iterate through change record */
-
- for(i=0; i<pTab->nCol; i++){
- int eType = *a;
- int isPK = pTab->abPK[i];
- if( bPkOnly && isPK==0 ) continue;
-
+ if( e==SQLITE_NULL ) return 1;
+ if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9;
+ return sessionVarintGet(&a[1], &n) + 1 + n;
+}
+
+/*
+** Based on the primary key values stored in change aRecord, calculate a
+** hash key. Assume the has table has nBucket buckets. The hash keys
+** calculated by this function are compatible with those calculated by
+** sessionPreupdateHash().
+**
+** The bPkOnly argument is non-zero if the record at aRecord[] is from
+** a patchset DELETE. In this case the non-PK fields are omitted entirely.
+*/
+static unsigned int sessionChangeHash(
+ SessionTable *pTab, /* Table handle */
+ int bPkOnly, /* Record consists of PK fields only */
+ u8 *aRecord, /* Change record */
+ int nBucket /* Assume this many buckets in hash table */
+){
+ unsigned int h = 0; /* Value to return */
+ int i; /* Used to iterate through columns */
+ u8 *a = aRecord; /* Used to iterate through change record */
+
+ for(i=0; i<pTab->nCol; i++){
+ int eType = *a;
+ int isPK = pTab->abPK[i];
+ if( bPkOnly && isPK==0 ) continue;
+
/* It is not possible for eType to be SQLITE_NULL here. The session
- ** module does not record changes for rows with NULL values stored in
- ** primary key columns. */
+ ** module does not record changes for rows with NULL values stored in
+ ** primary key columns. */
assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
|| eType==SQLITE_TEXT || eType==SQLITE_BLOB
|| eType==SQLITE_NULL || eType==0
- );
- assert( !isPK || (eType!=0 && eType!=SQLITE_NULL) );
-
- if( isPK ){
- a++;
- h = sessionHashAppendType(h, eType);
- if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
- h = sessionHashAppendI64(h, sessionGetI64(a));
- a += 8;
- }else{
+ );
+ assert( !isPK || (eType!=0 && eType!=SQLITE_NULL) );
+
+ if( isPK ){
+ a++;
+ h = sessionHashAppendType(h, eType);
+ if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+ h = sessionHashAppendI64(h, sessionGetI64(a));
+ a += 8;
+ }else{
int n;
- a += sessionVarintGet(a, &n);
- h = sessionHashAppendBlob(h, n, a);
- a += n;
- }
- }else{
- a += sessionSerialLen(a);
- }
- }
- return (h % nBucket);
-}
-
-/*
-** Arguments aLeft and aRight are pointers to change records for table pTab.
-** This function returns true if the two records apply to the same row (i.e.
+ a += sessionVarintGet(a, &n);
+ h = sessionHashAppendBlob(h, n, a);
+ a += n;
+ }
+ }else{
+ a += sessionSerialLen(a);
+ }
+ }
+ return (h % nBucket);
+}
+
+/*
+** Arguments aLeft and aRight are pointers to change records for table pTab.
+** This function returns true if the two records apply to the same row (i.e.
** have the same values stored in the primary key columns), or false
-** otherwise.
-*/
-static int sessionChangeEqual(
- SessionTable *pTab, /* Table used for PK definition */
- int bLeftPkOnly, /* True if aLeft[] contains PK fields only */
- u8 *aLeft, /* Change record */
- int bRightPkOnly, /* True if aRight[] contains PK fields only */
- u8 *aRight /* Change record */
-){
- u8 *a1 = aLeft; /* Cursor to iterate through aLeft */
- u8 *a2 = aRight; /* Cursor to iterate through aRight */
- int iCol; /* Used to iterate through table columns */
-
- for(iCol=0; iCol<pTab->nCol; iCol++){
- if( pTab->abPK[iCol] ){
- int n1 = sessionSerialLen(a1);
- int n2 = sessionSerialLen(a2);
-
+** otherwise.
+*/
+static int sessionChangeEqual(
+ SessionTable *pTab, /* Table used for PK definition */
+ int bLeftPkOnly, /* True if aLeft[] contains PK fields only */
+ u8 *aLeft, /* Change record */
+ int bRightPkOnly, /* True if aRight[] contains PK fields only */
+ u8 *aRight /* Change record */
+){
+ u8 *a1 = aLeft; /* Cursor to iterate through aLeft */
+ u8 *a2 = aRight; /* Cursor to iterate through aRight */
+ int iCol; /* Used to iterate through table columns */
+
+ for(iCol=0; iCol<pTab->nCol; iCol++){
+ if( pTab->abPK[iCol] ){
+ int n1 = sessionSerialLen(a1);
+ int n2 = sessionSerialLen(a2);
+
if( n1!=n2 || memcmp(a1, a2, n1) ){
- return 0;
- }
- a1 += n1;
- a2 += n2;
- }else{
- if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1);
- if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2);
- }
- }
-
- return 1;
-}
-
-/*
-** Arguments aLeft and aRight both point to buffers containing change
-** records with nCol columns. This function "merges" the two records into
-** a single records which is written to the buffer at *paOut. *paOut is
+ return 0;
+ }
+ a1 += n1;
+ a2 += n2;
+ }else{
+ if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1);
+ if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2);
+ }
+ }
+
+ return 1;
+}
+
+/*
+** Arguments aLeft and aRight both point to buffers containing change
+** records with nCol columns. This function "merges" the two records into
+** a single records which is written to the buffer at *paOut. *paOut is
** then set to point to one byte after the last byte written before
-** returning.
-**
+** returning.
+**
** The merging of records is done as follows: For each column, if the
-** aRight record contains a value for the column, copy the value from
-** their. Otherwise, if aLeft contains a value, copy it. If neither
-** record contains a value for a given column, then neither does the
-** output record.
-*/
-static void sessionMergeRecord(
+** aRight record contains a value for the column, copy the value from
+** their. Otherwise, if aLeft contains a value, copy it. If neither
+** record contains a value for a given column, then neither does the
+** output record.
+*/
+static void sessionMergeRecord(
u8 **paOut,
- int nCol,
- u8 *aLeft,
- u8 *aRight
-){
- u8 *a1 = aLeft; /* Cursor used to iterate through aLeft */
- u8 *a2 = aRight; /* Cursor used to iterate through aRight */
- u8 *aOut = *paOut; /* Output cursor */
- int iCol; /* Used to iterate from 0 to nCol */
-
- for(iCol=0; iCol<nCol; iCol++){
- int n1 = sessionSerialLen(a1);
- int n2 = sessionSerialLen(a2);
- if( *a2 ){
- memcpy(aOut, a2, n2);
- aOut += n2;
- }else{
- memcpy(aOut, a1, n1);
- aOut += n1;
- }
- a1 += n1;
- a2 += n2;
- }
-
- *paOut = aOut;
-}
-
-/*
-** This is a helper function used by sessionMergeUpdate().
-**
+ int nCol,
+ u8 *aLeft,
+ u8 *aRight
+){
+ u8 *a1 = aLeft; /* Cursor used to iterate through aLeft */
+ u8 *a2 = aRight; /* Cursor used to iterate through aRight */
+ u8 *aOut = *paOut; /* Output cursor */
+ int iCol; /* Used to iterate from 0 to nCol */
+
+ for(iCol=0; iCol<nCol; iCol++){
+ int n1 = sessionSerialLen(a1);
+ int n2 = sessionSerialLen(a2);
+ if( *a2 ){
+ memcpy(aOut, a2, n2);
+ aOut += n2;
+ }else{
+ memcpy(aOut, a1, n1);
+ aOut += n1;
+ }
+ a1 += n1;
+ a2 += n2;
+ }
+
+ *paOut = aOut;
+}
+
+/*
+** This is a helper function used by sessionMergeUpdate().
+**
** When this function is called, both *paOne and *paTwo point to a value
** within a change record. Before it returns, both have been advanced so
-** as to point to the next value in the record.
-**
-** If, when this function is called, *paTwo points to a valid value (i.e.
-** *paTwo[0] is not 0x00 - the "no value" placeholder), a copy of the *paTwo
+** as to point to the next value in the record.
+**
+** If, when this function is called, *paTwo points to a valid value (i.e.
+** *paTwo[0] is not 0x00 - the "no value" placeholder), a copy of the *paTwo
** pointer is returned and *pnVal is set to the number of bytes in the
-** serialized value. Otherwise, a copy of *paOne is returned and *pnVal
-** set to the number of bytes in the value at *paOne. If *paOne points
-** to the "no value" placeholder, *pnVal is set to 1. In other words:
-**
-** if( *paTwo is valid ) return *paTwo;
-** return *paOne;
-**
-*/
-static u8 *sessionMergeValue(
- u8 **paOne, /* IN/OUT: Left-hand buffer pointer */
- u8 **paTwo, /* IN/OUT: Right-hand buffer pointer */
- int *pnVal /* OUT: Bytes in returned value */
-){
- u8 *a1 = *paOne;
- u8 *a2 = *paTwo;
- u8 *pRet = 0;
- int n1;
-
- assert( a1 );
- if( a2 ){
- int n2 = sessionSerialLen(a2);
- if( *a2 ){
- *pnVal = n2;
- pRet = a2;
- }
- *paTwo = &a2[n2];
- }
-
- n1 = sessionSerialLen(a1);
- if( pRet==0 ){
- *pnVal = n1;
- pRet = a1;
- }
- *paOne = &a1[n1];
-
- return pRet;
-}
-
-/*
-** This function is used by changeset_concat() to merge two UPDATE changes
-** on the same row.
-*/
-static int sessionMergeUpdate(
- u8 **paOut, /* IN/OUT: Pointer to output buffer */
- SessionTable *pTab, /* Table change pertains to */
- int bPatchset, /* True if records are patchset records */
- u8 *aOldRecord1, /* old.* record for first change */
- u8 *aOldRecord2, /* old.* record for second change */
- u8 *aNewRecord1, /* new.* record for first change */
- u8 *aNewRecord2 /* new.* record for second change */
-){
- u8 *aOld1 = aOldRecord1;
- u8 *aOld2 = aOldRecord2;
- u8 *aNew1 = aNewRecord1;
- u8 *aNew2 = aNewRecord2;
-
- u8 *aOut = *paOut;
- int i;
-
- if( bPatchset==0 ){
- int bRequired = 0;
-
- assert( aOldRecord1 && aNewRecord1 );
-
- /* Write the old.* vector first. */
- for(i=0; i<pTab->nCol; i++){
- int nOld;
- u8 *aOld;
- int nNew;
- u8 *aNew;
-
- aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
- aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
- if( pTab->abPK[i] || nOld!=nNew || memcmp(aOld, aNew, nNew) ){
- if( pTab->abPK[i]==0 ) bRequired = 1;
- memcpy(aOut, aOld, nOld);
- aOut += nOld;
- }else{
- *(aOut++) = '\0';
- }
- }
-
- if( !bRequired ) return 0;
- }
-
- /* Write the new.* vector */
- aOld1 = aOldRecord1;
- aOld2 = aOldRecord2;
- aNew1 = aNewRecord1;
- aNew2 = aNewRecord2;
- for(i=0; i<pTab->nCol; i++){
- int nOld;
- u8 *aOld;
- int nNew;
- u8 *aNew;
-
- aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
- aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
+** serialized value. Otherwise, a copy of *paOne is returned and *pnVal
+** set to the number of bytes in the value at *paOne. If *paOne points
+** to the "no value" placeholder, *pnVal is set to 1. In other words:
+**
+** if( *paTwo is valid ) return *paTwo;
+** return *paOne;
+**
+*/
+static u8 *sessionMergeValue(
+ u8 **paOne, /* IN/OUT: Left-hand buffer pointer */
+ u8 **paTwo, /* IN/OUT: Right-hand buffer pointer */
+ int *pnVal /* OUT: Bytes in returned value */
+){
+ u8 *a1 = *paOne;
+ u8 *a2 = *paTwo;
+ u8 *pRet = 0;
+ int n1;
+
+ assert( a1 );
+ if( a2 ){
+ int n2 = sessionSerialLen(a2);
+ if( *a2 ){
+ *pnVal = n2;
+ pRet = a2;
+ }
+ *paTwo = &a2[n2];
+ }
+
+ n1 = sessionSerialLen(a1);
+ if( pRet==0 ){
+ *pnVal = n1;
+ pRet = a1;
+ }
+ *paOne = &a1[n1];
+
+ return pRet;
+}
+
+/*
+** This function is used by changeset_concat() to merge two UPDATE changes
+** on the same row.
+*/
+static int sessionMergeUpdate(
+ u8 **paOut, /* IN/OUT: Pointer to output buffer */
+ SessionTable *pTab, /* Table change pertains to */
+ int bPatchset, /* True if records are patchset records */
+ u8 *aOldRecord1, /* old.* record for first change */
+ u8 *aOldRecord2, /* old.* record for second change */
+ u8 *aNewRecord1, /* new.* record for first change */
+ u8 *aNewRecord2 /* new.* record for second change */
+){
+ u8 *aOld1 = aOldRecord1;
+ u8 *aOld2 = aOldRecord2;
+ u8 *aNew1 = aNewRecord1;
+ u8 *aNew2 = aNewRecord2;
+
+ u8 *aOut = *paOut;
+ int i;
+
+ if( bPatchset==0 ){
+ int bRequired = 0;
+
+ assert( aOldRecord1 && aNewRecord1 );
+
+ /* Write the old.* vector first. */
+ for(i=0; i<pTab->nCol; i++){
+ int nOld;
+ u8 *aOld;
+ int nNew;
+ u8 *aNew;
+
+ aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
+ aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
+ if( pTab->abPK[i] || nOld!=nNew || memcmp(aOld, aNew, nNew) ){
+ if( pTab->abPK[i]==0 ) bRequired = 1;
+ memcpy(aOut, aOld, nOld);
+ aOut += nOld;
+ }else{
+ *(aOut++) = '\0';
+ }
+ }
+
+ if( !bRequired ) return 0;
+ }
+
+ /* Write the new.* vector */
+ aOld1 = aOldRecord1;
+ aOld2 = aOldRecord2;
+ aNew1 = aNewRecord1;
+ aNew2 = aNewRecord2;
+ for(i=0; i<pTab->nCol; i++){
+ int nOld;
+ u8 *aOld;
+ int nNew;
+ u8 *aNew;
+
+ aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
+ aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
if( bPatchset==0
&& (pTab->abPK[i] || (nOld==nNew && 0==memcmp(aOld, aNew, nNew)))
- ){
- *(aOut++) = '\0';
- }else{
- memcpy(aOut, aNew, nNew);
- aOut += nNew;
- }
- }
-
- *paOut = aOut;
- return 1;
-}
-
-/*
-** This function is only called from within a pre-update-hook callback.
-** It determines if the current pre-update-hook change affects the same row
-** as the change stored in argument pChange. If so, it returns true. Otherwise
-** if the pre-update-hook does not affect the same row as pChange, it returns
-** false.
-*/
-static int sessionPreupdateEqual(
- sqlite3_session *pSession, /* Session object that owns SessionTable */
- SessionTable *pTab, /* Table associated with change */
- SessionChange *pChange, /* Change to compare to */
- int op /* Current pre-update operation */
-){
- int iCol; /* Used to iterate through columns */
- u8 *a = pChange->aRecord; /* Cursor used to scan change record */
-
- assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
- for(iCol=0; iCol<pTab->nCol; iCol++){
- if( !pTab->abPK[iCol] ){
- a += sessionSerialLen(a);
- }else{
- sqlite3_value *pVal; /* Value returned by preupdate_new/old */
- int rc; /* Error code from preupdate_new/old */
- int eType = *a++; /* Type of value from change record */
-
- /* The following calls to preupdate_new() and preupdate_old() can not
- ** fail. This is because they cache their return values, and by the
- ** time control flows to here they have already been called once from
- ** within sessionPreupdateHash(). The first two asserts below verify
- ** this (that the method has already been called). */
- if( op==SQLITE_INSERT ){
- /* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */
- rc = pSession->hook.xNew(pSession->hook.pCtx, iCol, &pVal);
- }else{
- /* assert( db->pPreUpdate->pUnpacked ); */
- rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal);
- }
- assert( rc==SQLITE_OK );
- if( sqlite3_value_type(pVal)!=eType ) return 0;
-
- /* A SessionChange object never has a NULL value in a PK column */
- assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
- || eType==SQLITE_BLOB || eType==SQLITE_TEXT
- );
-
- if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
- i64 iVal = sessionGetI64(a);
- a += 8;
- if( eType==SQLITE_INTEGER ){
- if( sqlite3_value_int64(pVal)!=iVal ) return 0;
- }else{
- double rVal;
- assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
- memcpy(&rVal, &iVal, 8);
- if( sqlite3_value_double(pVal)!=rVal ) return 0;
- }
- }else{
- int n;
- const u8 *z;
- a += sessionVarintGet(a, &n);
- if( sqlite3_value_bytes(pVal)!=n ) return 0;
- if( eType==SQLITE_TEXT ){
- z = sqlite3_value_text(pVal);
- }else{
- z = sqlite3_value_blob(pVal);
- }
+ ){
+ *(aOut++) = '\0';
+ }else{
+ memcpy(aOut, aNew, nNew);
+ aOut += nNew;
+ }
+ }
+
+ *paOut = aOut;
+ return 1;
+}
+
+/*
+** This function is only called from within a pre-update-hook callback.
+** It determines if the current pre-update-hook change affects the same row
+** as the change stored in argument pChange. If so, it returns true. Otherwise
+** if the pre-update-hook does not affect the same row as pChange, it returns
+** false.
+*/
+static int sessionPreupdateEqual(
+ sqlite3_session *pSession, /* Session object that owns SessionTable */
+ SessionTable *pTab, /* Table associated with change */
+ SessionChange *pChange, /* Change to compare to */
+ int op /* Current pre-update operation */
+){
+ int iCol; /* Used to iterate through columns */
+ u8 *a = pChange->aRecord; /* Cursor used to scan change record */
+
+ assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
+ for(iCol=0; iCol<pTab->nCol; iCol++){
+ if( !pTab->abPK[iCol] ){
+ a += sessionSerialLen(a);
+ }else{
+ sqlite3_value *pVal; /* Value returned by preupdate_new/old */
+ int rc; /* Error code from preupdate_new/old */
+ int eType = *a++; /* Type of value from change record */
+
+ /* The following calls to preupdate_new() and preupdate_old() can not
+ ** fail. This is because they cache their return values, and by the
+ ** time control flows to here they have already been called once from
+ ** within sessionPreupdateHash(). The first two asserts below verify
+ ** this (that the method has already been called). */
+ if( op==SQLITE_INSERT ){
+ /* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */
+ rc = pSession->hook.xNew(pSession->hook.pCtx, iCol, &pVal);
+ }else{
+ /* assert( db->pPreUpdate->pUnpacked ); */
+ rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal);
+ }
+ assert( rc==SQLITE_OK );
+ if( sqlite3_value_type(pVal)!=eType ) return 0;
+
+ /* A SessionChange object never has a NULL value in a PK column */
+ assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
+ || eType==SQLITE_BLOB || eType==SQLITE_TEXT
+ );
+
+ if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+ i64 iVal = sessionGetI64(a);
+ a += 8;
+ if( eType==SQLITE_INTEGER ){
+ if( sqlite3_value_int64(pVal)!=iVal ) return 0;
+ }else{
+ double rVal;
+ assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
+ memcpy(&rVal, &iVal, 8);
+ if( sqlite3_value_double(pVal)!=rVal ) return 0;
+ }
+ }else{
+ int n;
+ const u8 *z;
+ a += sessionVarintGet(a, &n);
+ if( sqlite3_value_bytes(pVal)!=n ) return 0;
+ if( eType==SQLITE_TEXT ){
+ z = sqlite3_value_text(pVal);
+ }else{
+ z = sqlite3_value_blob(pVal);
+ }
if( n>0 && memcmp(a, z, n) ) return 0;
- a += n;
- }
- }
- }
-
- return 1;
-}
-
-/*
+ a += n;
+ }
+ }
+ }
+
+ return 1;
+}
+
+/*
** If required, grow the hash table used to store changes on table pTab
-** (part of the session pSession). If a fatal OOM error occurs, set the
-** session object to failed and return SQLITE_ERROR. Otherwise, return
-** SQLITE_OK.
-**
-** It is possible that a non-fatal OOM error occurs in this function. In
-** that case the hash-table does not grow, but SQLITE_OK is returned anyway.
-** Growing the hash table in this case is a performance optimization only,
-** it is not required for correct operation.
-*/
+** (part of the session pSession). If a fatal OOM error occurs, set the
+** session object to failed and return SQLITE_ERROR. Otherwise, return
+** SQLITE_OK.
+**
+** It is possible that a non-fatal OOM error occurs in this function. In
+** that case the hash-table does not grow, but SQLITE_OK is returned anyway.
+** Growing the hash table in this case is a performance optimization only,
+** it is not required for correct operation.
+*/
static int sessionGrowHash(
sqlite3_session *pSession, /* For memory accounting. May be NULL */
int bPatchset,
SessionTable *pTab
){
- if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){
- int i;
- SessionChange **apNew;
+ if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){
+ int i;
+ SessionChange **apNew;
sqlite3_int64 nNew = 2*(sqlite3_int64)(pTab->nChange ? pTab->nChange : 128);
-
+
apNew = (SessionChange**)sessionMalloc64(
pSession, sizeof(SessionChange*) * nNew
);
- if( apNew==0 ){
- if( pTab->nChange==0 ){
- return SQLITE_ERROR;
- }
- return SQLITE_OK;
- }
- memset(apNew, 0, sizeof(SessionChange *) * nNew);
-
- for(i=0; i<pTab->nChange; i++){
- SessionChange *p;
- SessionChange *pNext;
- for(p=pTab->apChange[i]; p; p=pNext){
- int bPkOnly = (p->op==SQLITE_DELETE && bPatchset);
- int iHash = sessionChangeHash(pTab, bPkOnly, p->aRecord, nNew);
- pNext = p->pNext;
- p->pNext = apNew[iHash];
- apNew[iHash] = p;
- }
- }
-
+ if( apNew==0 ){
+ if( pTab->nChange==0 ){
+ return SQLITE_ERROR;
+ }
+ return SQLITE_OK;
+ }
+ memset(apNew, 0, sizeof(SessionChange *) * nNew);
+
+ for(i=0; i<pTab->nChange; i++){
+ SessionChange *p;
+ SessionChange *pNext;
+ for(p=pTab->apChange[i]; p; p=pNext){
+ int bPkOnly = (p->op==SQLITE_DELETE && bPatchset);
+ int iHash = sessionChangeHash(pTab, bPkOnly, p->aRecord, nNew);
+ pNext = p->pNext;
+ p->pNext = apNew[iHash];
+ apNew[iHash] = p;
+ }
+ }
+
sessionFree(pSession, pTab->apChange);
- pTab->nChange = nNew;
- pTab->apChange = apNew;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** This function queries the database for the names of the columns of table
-** zThis, in schema zDb.
-**
-** Otherwise, if they are not NULL, variable *pnCol is set to the number
-** of columns in the database table and variable *pzTab is set to point to a
-** nul-terminated copy of the table name. *pazCol (if not NULL) is set to
-** point to an array of pointers to column names. And *pabPK (again, if not
-** NULL) is set to point to an array of booleans - true if the corresponding
-** column is part of the primary key.
-**
-** For example, if the table is declared as:
-**
-** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z));
-**
-** Then the four output variables are populated as follows:
-**
-** *pnCol = 4
-** *pzTab = "tbl1"
-** *pazCol = {"w", "x", "y", "z"}
-** *pabPK = {1, 0, 0, 1}
-**
-** All returned buffers are part of the same single allocation, which must
-** be freed using sqlite3_free() by the caller
-*/
-static int sessionTableInfo(
+ pTab->nChange = nNew;
+ pTab->apChange = apNew;
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** This function queries the database for the names of the columns of table
+** zThis, in schema zDb.
+**
+** Otherwise, if they are not NULL, variable *pnCol is set to the number
+** of columns in the database table and variable *pzTab is set to point to a
+** nul-terminated copy of the table name. *pazCol (if not NULL) is set to
+** point to an array of pointers to column names. And *pabPK (again, if not
+** NULL) is set to point to an array of booleans - true if the corresponding
+** column is part of the primary key.
+**
+** For example, if the table is declared as:
+**
+** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z));
+**
+** Then the four output variables are populated as follows:
+**
+** *pnCol = 4
+** *pzTab = "tbl1"
+** *pazCol = {"w", "x", "y", "z"}
+** *pabPK = {1, 0, 0, 1}
+**
+** All returned buffers are part of the same single allocation, which must
+** be freed using sqlite3_free() by the caller
+*/
+static int sessionTableInfo(
sqlite3_session *pSession, /* For memory accounting. May be NULL */
- sqlite3 *db, /* Database connection */
- const char *zDb, /* Name of attached database (e.g. "main") */
- const char *zThis, /* Table name */
- int *pnCol, /* OUT: number of columns */
- const char **pzTab, /* OUT: Copy of zThis */
- const char ***pazCol, /* OUT: Array of column names for table */
- u8 **pabPK /* OUT: Array of booleans - true for PK col */
-){
- char *zPragma;
- sqlite3_stmt *pStmt;
- int rc;
+ sqlite3 *db, /* Database connection */
+ const char *zDb, /* Name of attached database (e.g. "main") */
+ const char *zThis, /* Table name */
+ int *pnCol, /* OUT: number of columns */
+ const char **pzTab, /* OUT: Copy of zThis */
+ const char ***pazCol, /* OUT: Array of column names for table */
+ u8 **pabPK /* OUT: Array of booleans - true for PK col */
+){
+ char *zPragma;
+ sqlite3_stmt *pStmt;
+ int rc;
sqlite3_int64 nByte;
- int nDbCol = 0;
- int nThis;
- int i;
- u8 *pAlloc = 0;
- char **azCol = 0;
- u8 *abPK = 0;
-
- assert( pazCol && pabPK );
-
- nThis = sqlite3Strlen30(zThis);
- if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
- rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
- if( rc==SQLITE_OK ){
- /* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
- zPragma = sqlite3_mprintf(
- "SELECT 0, 'tbl', '', 0, '', 1 UNION ALL "
- "SELECT 1, 'idx', '', 0, '', 2 UNION ALL "
- "SELECT 2, 'stat', '', 0, '', 0"
- );
- }else if( rc==SQLITE_ERROR ){
- zPragma = sqlite3_mprintf("");
- }else{
+ int nDbCol = 0;
+ int nThis;
+ int i;
+ u8 *pAlloc = 0;
+ char **azCol = 0;
+ u8 *abPK = 0;
+
+ assert( pazCol && pabPK );
+
+ nThis = sqlite3Strlen30(zThis);
+ if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
+ rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
+ if( rc==SQLITE_OK ){
+ /* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
+ zPragma = sqlite3_mprintf(
+ "SELECT 0, 'tbl', '', 0, '', 1 UNION ALL "
+ "SELECT 1, 'idx', '', 0, '', 2 UNION ALL "
+ "SELECT 2, 'stat', '', 0, '', 0"
+ );
+ }else if( rc==SQLITE_ERROR ){
+ zPragma = sqlite3_mprintf("");
+ }else{
*pazCol = 0;
*pabPK = 0;
*pnCol = 0;
if( pzTab ) *pzTab = 0;
- return rc;
- }
- }else{
- zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
- }
+ return rc;
+ }
+ }else{
+ zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
+ }
if( !zPragma ){
*pazCol = 0;
*pabPK = 0;
@@ -209512,9 +209512,9 @@ static int sessionTableInfo(
if( pzTab ) *pzTab = 0;
return SQLITE_NOMEM;
}
-
- rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
- sqlite3_free(zPragma);
+
+ rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
+ sqlite3_free(zPragma);
if( rc!=SQLITE_OK ){
*pazCol = 0;
*pabPK = 0;
@@ -209522,146 +209522,146 @@ static int sessionTableInfo(
if( pzTab ) *pzTab = 0;
return rc;
}
-
- nByte = nThis + 1;
- while( SQLITE_ROW==sqlite3_step(pStmt) ){
- nByte += sqlite3_column_bytes(pStmt, 1);
- nDbCol++;
- }
- rc = sqlite3_reset(pStmt);
-
- if( rc==SQLITE_OK ){
- nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1);
+
+ nByte = nThis + 1;
+ while( SQLITE_ROW==sqlite3_step(pStmt) ){
+ nByte += sqlite3_column_bytes(pStmt, 1);
+ nDbCol++;
+ }
+ rc = sqlite3_reset(pStmt);
+
+ if( rc==SQLITE_OK ){
+ nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1);
pAlloc = sessionMalloc64(pSession, nByte);
- if( pAlloc==0 ){
- rc = SQLITE_NOMEM;
- }
- }
- if( rc==SQLITE_OK ){
- azCol = (char **)pAlloc;
- pAlloc = (u8 *)&azCol[nDbCol];
- abPK = (u8 *)pAlloc;
- pAlloc = &abPK[nDbCol];
- if( pzTab ){
- memcpy(pAlloc, zThis, nThis+1);
- *pzTab = (char *)pAlloc;
- pAlloc += nThis+1;
- }
-
- i = 0;
- while( SQLITE_ROW==sqlite3_step(pStmt) ){
- int nName = sqlite3_column_bytes(pStmt, 1);
- const unsigned char *zName = sqlite3_column_text(pStmt, 1);
- if( zName==0 ) break;
- memcpy(pAlloc, zName, nName+1);
- azCol[i] = (char *)pAlloc;
- pAlloc += nName+1;
- abPK[i] = sqlite3_column_int(pStmt, 5);
- i++;
- }
- rc = sqlite3_reset(pStmt);
-
- }
-
- /* If successful, populate the output variables. Otherwise, zero them and
- ** free any allocation made. An error code will be returned in this case.
- */
- if( rc==SQLITE_OK ){
- *pazCol = (const char **)azCol;
- *pabPK = abPK;
- *pnCol = nDbCol;
- }else{
- *pazCol = 0;
- *pabPK = 0;
- *pnCol = 0;
- if( pzTab ) *pzTab = 0;
+ if( pAlloc==0 ){
+ rc = SQLITE_NOMEM;
+ }
+ }
+ if( rc==SQLITE_OK ){
+ azCol = (char **)pAlloc;
+ pAlloc = (u8 *)&azCol[nDbCol];
+ abPK = (u8 *)pAlloc;
+ pAlloc = &abPK[nDbCol];
+ if( pzTab ){
+ memcpy(pAlloc, zThis, nThis+1);
+ *pzTab = (char *)pAlloc;
+ pAlloc += nThis+1;
+ }
+
+ i = 0;
+ while( SQLITE_ROW==sqlite3_step(pStmt) ){
+ int nName = sqlite3_column_bytes(pStmt, 1);
+ const unsigned char *zName = sqlite3_column_text(pStmt, 1);
+ if( zName==0 ) break;
+ memcpy(pAlloc, zName, nName+1);
+ azCol[i] = (char *)pAlloc;
+ pAlloc += nName+1;
+ abPK[i] = sqlite3_column_int(pStmt, 5);
+ i++;
+ }
+ rc = sqlite3_reset(pStmt);
+
+ }
+
+ /* If successful, populate the output variables. Otherwise, zero them and
+ ** free any allocation made. An error code will be returned in this case.
+ */
+ if( rc==SQLITE_OK ){
+ *pazCol = (const char **)azCol;
+ *pabPK = abPK;
+ *pnCol = nDbCol;
+ }else{
+ *pazCol = 0;
+ *pabPK = 0;
+ *pnCol = 0;
+ if( pzTab ) *pzTab = 0;
sessionFree(pSession, azCol);
- }
- sqlite3_finalize(pStmt);
- return rc;
-}
-
-/*
-** This function is only called from within a pre-update handler for a
-** write to table pTab, part of session pSession. If this is the first
-** write to this table, initalize the SessionTable.nCol, azCol[] and
-** abPK[] arrays accordingly.
-**
-** If an error occurs, an error code is stored in sqlite3_session.rc and
-** non-zero returned. Or, if no error occurs but the table has no primary
-** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to
+ }
+ sqlite3_finalize(pStmt);
+ return rc;
+}
+
+/*
+** This function is only called from within a pre-update handler for a
+** write to table pTab, part of session pSession. If this is the first
+** write to this table, initalize the SessionTable.nCol, azCol[] and
+** abPK[] arrays accordingly.
+**
+** If an error occurs, an error code is stored in sqlite3_session.rc and
+** non-zero returned. Or, if no error occurs but the table has no primary
+** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to
** indicate that updates on this table should be ignored. SessionTable.abPK
-** is set to NULL in this case.
-*/
-static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
- if( pTab->nCol==0 ){
- u8 *abPK;
- assert( pTab->azCol==0 || pTab->abPK==0 );
+** is set to NULL in this case.
+*/
+static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
+ if( pTab->nCol==0 ){
+ u8 *abPK;
+ assert( pTab->azCol==0 || pTab->abPK==0 );
pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb,
- pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK
- );
- if( pSession->rc==SQLITE_OK ){
- int i;
- for(i=0; i<pTab->nCol; i++){
- if( abPK[i] ){
- pTab->abPK = abPK;
- break;
- }
- }
- if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){
- pTab->bStat1 = 1;
- }
+ pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK
+ );
+ if( pSession->rc==SQLITE_OK ){
+ int i;
+ for(i=0; i<pTab->nCol; i++){
+ if( abPK[i] ){
+ pTab->abPK = abPK;
+ break;
+ }
+ }
+ if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){
+ pTab->bStat1 = 1;
+ }
if( pSession->bEnableSize ){
pSession->nMaxChangesetSize += (
1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName)+1
);
}
- }
- }
- return (pSession->rc || pTab->abPK==0);
-}
-
-/*
-** Versions of the four methods in object SessionHook for use with the
-** sqlite_stat1 table. The purpose of this is to substitute a zero-length
-** blob each time a NULL value is read from the "idx" column of the
-** sqlite_stat1 table.
-*/
-typedef struct SessionStat1Ctx SessionStat1Ctx;
-struct SessionStat1Ctx {
- SessionHook hook;
- sqlite3_session *pSession;
-};
-static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){
- SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
- sqlite3_value *pVal = 0;
- int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal);
- if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
- pVal = p->pSession->pZeroBlob;
- }
- *ppVal = pVal;
- return rc;
-}
-static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){
- SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
- sqlite3_value *pVal = 0;
- int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal);
- if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
- pVal = p->pSession->pZeroBlob;
- }
- *ppVal = pVal;
- return rc;
-}
-static int sessionStat1Count(void *pCtx){
- SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
- return p->hook.xCount(p->hook.pCtx);
-}
-static int sessionStat1Depth(void *pCtx){
- SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
- return p->hook.xDepth(p->hook.pCtx);
-}
-
+ }
+ }
+ return (pSession->rc || pTab->abPK==0);
+}
+
+/*
+** Versions of the four methods in object SessionHook for use with the
+** sqlite_stat1 table. The purpose of this is to substitute a zero-length
+** blob each time a NULL value is read from the "idx" column of the
+** sqlite_stat1 table.
+*/
+typedef struct SessionStat1Ctx SessionStat1Ctx;
+struct SessionStat1Ctx {
+ SessionHook hook;
+ sqlite3_session *pSession;
+};
+static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ sqlite3_value *pVal = 0;
+ int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal);
+ if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
+ pVal = p->pSession->pZeroBlob;
+ }
+ *ppVal = pVal;
+ return rc;
+}
+static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ sqlite3_value *pVal = 0;
+ int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal);
+ if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
+ pVal = p->pSession->pZeroBlob;
+ }
+ *ppVal = pVal;
+ return rc;
+}
+static int sessionStat1Count(void *pCtx){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ return p->hook.xCount(p->hook.pCtx);
+}
+static int sessionStat1Depth(void *pCtx){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ return p->hook.xDepth(p->hook.pCtx);
+}
+
static int sessionUpdateMaxSize(
int op,
sqlite3_session *pSession, /* Session object pTab is attached to */
@@ -209695,7 +209695,7 @@ static int sessionUpdateMaxSize(
if( p==0 ){
return SQLITE_NOMEM;
}
-
+
eType = *pCsr++;
switch( eType ){
case SQLITE_NULL:
@@ -209760,722 +209760,722 @@ static int sessionUpdateMaxSize(
return SQLITE_OK;
}
-/*
+/*
** This function is only called from with a pre-update-hook reporting a
-** change on table pTab (attached to session pSession). The type of change
-** (UPDATE, INSERT, DELETE) is specified by the first argument.
-**
-** Unless one is already present or an error occurs, an entry is added
-** to the changed-rows hash table associated with table pTab.
-*/
-static void sessionPreupdateOneChange(
- int op, /* One of SQLITE_UPDATE, INSERT, DELETE */
- sqlite3_session *pSession, /* Session object pTab is attached to */
- SessionTable *pTab /* Table that change applies to */
-){
+** change on table pTab (attached to session pSession). The type of change
+** (UPDATE, INSERT, DELETE) is specified by the first argument.
+**
+** Unless one is already present or an error occurs, an entry is added
+** to the changed-rows hash table associated with table pTab.
+*/
+static void sessionPreupdateOneChange(
+ int op, /* One of SQLITE_UPDATE, INSERT, DELETE */
+ sqlite3_session *pSession, /* Session object pTab is attached to */
+ SessionTable *pTab /* Table that change applies to */
+){
int iHash;
int bNull = 0;
- int rc = SQLITE_OK;
+ int rc = SQLITE_OK;
SessionStat1Ctx stat1 = {{0,0,0,0,0},0};
-
- if( pSession->rc ) return;
-
- /* Load table details if required */
- if( sessionInitTable(pSession, pTab) ) return;
-
+
+ if( pSession->rc ) return;
+
+ /* Load table details if required */
+ if( sessionInitTable(pSession, pTab) ) return;
+
/* Check the number of columns in this xPreUpdate call matches the
- ** number of columns in the table. */
- if( pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){
- pSession->rc = SQLITE_SCHEMA;
- return;
- }
-
- /* Grow the hash table if required */
+ ** number of columns in the table. */
+ if( pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){
+ pSession->rc = SQLITE_SCHEMA;
+ return;
+ }
+
+ /* Grow the hash table if required */
if( sessionGrowHash(pSession, 0, pTab) ){
- pSession->rc = SQLITE_NOMEM;
- return;
- }
-
- if( pTab->bStat1 ){
- stat1.hook = pSession->hook;
- stat1.pSession = pSession;
- pSession->hook.pCtx = (void*)&stat1;
- pSession->hook.xNew = sessionStat1New;
- pSession->hook.xOld = sessionStat1Old;
- pSession->hook.xCount = sessionStat1Count;
- pSession->hook.xDepth = sessionStat1Depth;
- if( pSession->pZeroBlob==0 ){
- sqlite3_value *p = sqlite3ValueNew(0);
- if( p==0 ){
- rc = SQLITE_NOMEM;
- goto error_out;
- }
- sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC);
- pSession->pZeroBlob = p;
- }
- }
-
- /* Calculate the hash-key for this change. If the primary key of the row
- ** includes a NULL value, exit early. Such changes are ignored by the
- ** session module. */
- rc = sessionPreupdateHash(pSession, pTab, op==SQLITE_INSERT, &iHash, &bNull);
- if( rc!=SQLITE_OK ) goto error_out;
-
- if( bNull==0 ){
- /* Search the hash table for an existing record for this row. */
- SessionChange *pC;
- for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){
- if( sessionPreupdateEqual(pSession, pTab, pC, op) ) break;
- }
-
- if( pC==0 ){
- /* Create a new change object containing all the old values (if
- ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK
- ** values (if this is an INSERT). */
+ pSession->rc = SQLITE_NOMEM;
+ return;
+ }
+
+ if( pTab->bStat1 ){
+ stat1.hook = pSession->hook;
+ stat1.pSession = pSession;
+ pSession->hook.pCtx = (void*)&stat1;
+ pSession->hook.xNew = sessionStat1New;
+ pSession->hook.xOld = sessionStat1Old;
+ pSession->hook.xCount = sessionStat1Count;
+ pSession->hook.xDepth = sessionStat1Depth;
+ if( pSession->pZeroBlob==0 ){
+ sqlite3_value *p = sqlite3ValueNew(0);
+ if( p==0 ){
+ rc = SQLITE_NOMEM;
+ goto error_out;
+ }
+ sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC);
+ pSession->pZeroBlob = p;
+ }
+ }
+
+ /* Calculate the hash-key for this change. If the primary key of the row
+ ** includes a NULL value, exit early. Such changes are ignored by the
+ ** session module. */
+ rc = sessionPreupdateHash(pSession, pTab, op==SQLITE_INSERT, &iHash, &bNull);
+ if( rc!=SQLITE_OK ) goto error_out;
+
+ if( bNull==0 ){
+ /* Search the hash table for an existing record for this row. */
+ SessionChange *pC;
+ for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){
+ if( sessionPreupdateEqual(pSession, pTab, pC, op) ) break;
+ }
+
+ if( pC==0 ){
+ /* Create a new change object containing all the old values (if
+ ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK
+ ** values (if this is an INSERT). */
sqlite3_int64 nByte; /* Number of bytes to allocate */
- int i; /* Used to iterate through columns */
-
- assert( rc==SQLITE_OK );
- pTab->nEntry++;
-
- /* Figure out how large an allocation is required */
- nByte = sizeof(SessionChange);
- for(i=0; i<pTab->nCol; i++){
- sqlite3_value *p = 0;
- if( op!=SQLITE_INSERT ){
- TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p);
- assert( trc==SQLITE_OK );
- }else if( pTab->abPK[i] ){
- TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p);
- assert( trc==SQLITE_OK );
- }
-
- /* This may fail if SQLite value p contains a utf-16 string that must
- ** be converted to utf-8 and an OOM error occurs while doing so. */
- rc = sessionSerializeValue(0, p, &nByte);
- if( rc!=SQLITE_OK ) goto error_out;
- }
-
- /* Allocate the change object */
+ int i; /* Used to iterate through columns */
+
+ assert( rc==SQLITE_OK );
+ pTab->nEntry++;
+
+ /* Figure out how large an allocation is required */
+ nByte = sizeof(SessionChange);
+ for(i=0; i<pTab->nCol; i++){
+ sqlite3_value *p = 0;
+ if( op!=SQLITE_INSERT ){
+ TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p);
+ assert( trc==SQLITE_OK );
+ }else if( pTab->abPK[i] ){
+ TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p);
+ assert( trc==SQLITE_OK );
+ }
+
+ /* This may fail if SQLite value p contains a utf-16 string that must
+ ** be converted to utf-8 and an OOM error occurs while doing so. */
+ rc = sessionSerializeValue(0, p, &nByte);
+ if( rc!=SQLITE_OK ) goto error_out;
+ }
+
+ /* Allocate the change object */
pC = (SessionChange *)sessionMalloc64(pSession, nByte);
if( !pC ){
- rc = SQLITE_NOMEM;
- goto error_out;
- }else{
+ rc = SQLITE_NOMEM;
+ goto error_out;
+ }else{
memset(pC, 0, sizeof(SessionChange));
pC->aRecord = (u8 *)&pC[1];
- }
-
- /* Populate the change object. None of the preupdate_old(),
- ** preupdate_new() or SerializeValue() calls below may fail as all
- ** required values and encodings have already been cached in memory.
- ** It is not possible for an OOM to occur in this block. */
- nByte = 0;
- for(i=0; i<pTab->nCol; i++){
- sqlite3_value *p = 0;
- if( op!=SQLITE_INSERT ){
- pSession->hook.xOld(pSession->hook.pCtx, i, &p);
- }else if( pTab->abPK[i] ){
- pSession->hook.xNew(pSession->hook.pCtx, i, &p);
- }
+ }
+
+ /* Populate the change object. None of the preupdate_old(),
+ ** preupdate_new() or SerializeValue() calls below may fail as all
+ ** required values and encodings have already been cached in memory.
+ ** It is not possible for an OOM to occur in this block. */
+ nByte = 0;
+ for(i=0; i<pTab->nCol; i++){
+ sqlite3_value *p = 0;
+ if( op!=SQLITE_INSERT ){
+ pSession->hook.xOld(pSession->hook.pCtx, i, &p);
+ }else if( pTab->abPK[i] ){
+ pSession->hook.xNew(pSession->hook.pCtx, i, &p);
+ }
sessionSerializeValue(&pC->aRecord[nByte], p, &nByte);
- }
-
- /* Add the change to the hash-table */
- if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){
+ }
+
+ /* Add the change to the hash-table */
+ if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){
pC->bIndirect = 1;
- }
+ }
pC->nRecord = nByte;
pC->op = op;
pC->pNext = pTab->apChange[iHash];
pTab->apChange[iHash] = pC;
-
- }else if( pC->bIndirect ){
- /* If the existing change is considered "indirect", but this current
- ** change is "direct", mark the change object as direct. */
+
+ }else if( pC->bIndirect ){
+ /* If the existing change is considered "indirect", but this current
+ ** change is "direct", mark the change object as direct. */
if( pSession->hook.xDepth(pSession->hook.pCtx)==0
&& pSession->bIndirect==0
- ){
- pC->bIndirect = 0;
- }
- }
+ ){
+ pC->bIndirect = 0;
+ }
+ }
assert( rc==SQLITE_OK );
if( pSession->bEnableSize ){
rc = sessionUpdateMaxSize(op, pSession, pTab, pC);
}
- }
-
-
- /* If an error has occurred, mark the session object as failed. */
- error_out:
- if( pTab->bStat1 ){
- pSession->hook = stat1.hook;
- }
- if( rc!=SQLITE_OK ){
- pSession->rc = rc;
- }
-}
-
-static int sessionFindTable(
+ }
+
+
+ /* If an error has occurred, mark the session object as failed. */
+ error_out:
+ if( pTab->bStat1 ){
+ pSession->hook = stat1.hook;
+ }
+ if( rc!=SQLITE_OK ){
+ pSession->rc = rc;
+ }
+}
+
+static int sessionFindTable(
sqlite3_session *pSession,
- const char *zName,
- SessionTable **ppTab
-){
- int rc = SQLITE_OK;
- int nName = sqlite3Strlen30(zName);
- SessionTable *pRet;
-
- /* Search for an existing table */
- for(pRet=pSession->pTable; pRet; pRet=pRet->pNext){
- if( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ) break;
- }
-
- if( pRet==0 && pSession->bAutoAttach ){
- /* If there is a table-filter configured, invoke it. If it returns 0,
- ** do not automatically add the new table. */
- if( pSession->xTableFilter==0
+ const char *zName,
+ SessionTable **ppTab
+){
+ int rc = SQLITE_OK;
+ int nName = sqlite3Strlen30(zName);
+ SessionTable *pRet;
+
+ /* Search for an existing table */
+ for(pRet=pSession->pTable; pRet; pRet=pRet->pNext){
+ if( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ) break;
+ }
+
+ if( pRet==0 && pSession->bAutoAttach ){
+ /* If there is a table-filter configured, invoke it. If it returns 0,
+ ** do not automatically add the new table. */
+ if( pSession->xTableFilter==0
|| pSession->xTableFilter(pSession->pFilterCtx, zName)
- ){
- rc = sqlite3session_attach(pSession, zName);
- if( rc==SQLITE_OK ){
+ ){
+ rc = sqlite3session_attach(pSession, zName);
+ if( rc==SQLITE_OK ){
pRet = pSession->pTable;
while( ALWAYS(pRet) && pRet->pNext ){
pRet = pRet->pNext;
}
assert( pRet!=0 );
- assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) );
- }
- }
- }
-
- assert( rc==SQLITE_OK || pRet==0 );
- *ppTab = pRet;
- return rc;
-}
-
-/*
-** The 'pre-update' hook registered by this module with SQLite databases.
-*/
-static void xPreUpdate(
- void *pCtx, /* Copy of third arg to preupdate_hook() */
- sqlite3 *db, /* Database handle */
- int op, /* SQLITE_UPDATE, DELETE or INSERT */
- char const *zDb, /* Database name */
- char const *zName, /* Table name */
- sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */
- sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */
-){
- sqlite3_session *pSession;
- int nDb = sqlite3Strlen30(zDb);
-
- assert( sqlite3_mutex_held(db->mutex) );
-
- for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){
- SessionTable *pTab;
-
+ assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) );
+ }
+ }
+ }
+
+ assert( rc==SQLITE_OK || pRet==0 );
+ *ppTab = pRet;
+ return rc;
+}
+
+/*
+** The 'pre-update' hook registered by this module with SQLite databases.
+*/
+static void xPreUpdate(
+ void *pCtx, /* Copy of third arg to preupdate_hook() */
+ sqlite3 *db, /* Database handle */
+ int op, /* SQLITE_UPDATE, DELETE or INSERT */
+ char const *zDb, /* Database name */
+ char const *zName, /* Table name */
+ sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */
+ sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */
+){
+ sqlite3_session *pSession;
+ int nDb = sqlite3Strlen30(zDb);
+
+ assert( sqlite3_mutex_held(db->mutex) );
+
+ for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){
+ SessionTable *pTab;
+
/* If this session is attached to a different database ("main", "temp"
** etc.), or if it is not currently enabled, there is nothing to do. Skip
- ** to the next session object attached to this database. */
- if( pSession->bEnable==0 ) continue;
- if( pSession->rc ) continue;
- if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue;
-
- pSession->rc = sessionFindTable(pSession, zName, &pTab);
- if( pTab ){
- assert( pSession->rc==SQLITE_OK );
- sessionPreupdateOneChange(op, pSession, pTab);
- if( op==SQLITE_UPDATE ){
- sessionPreupdateOneChange(SQLITE_INSERT, pSession, pTab);
- }
- }
- }
-}
-
-/*
-** The pre-update hook implementations.
-*/
-static int sessionPreupdateOld(void *pCtx, int iVal, sqlite3_value **ppVal){
- return sqlite3_preupdate_old((sqlite3*)pCtx, iVal, ppVal);
-}
-static int sessionPreupdateNew(void *pCtx, int iVal, sqlite3_value **ppVal){
- return sqlite3_preupdate_new((sqlite3*)pCtx, iVal, ppVal);
-}
-static int sessionPreupdateCount(void *pCtx){
- return sqlite3_preupdate_count((sqlite3*)pCtx);
-}
-static int sessionPreupdateDepth(void *pCtx){
- return sqlite3_preupdate_depth((sqlite3*)pCtx);
-}
-
-/*
-** Install the pre-update hooks on the session object passed as the only
-** argument.
-*/
-static void sessionPreupdateHooks(
- sqlite3_session *pSession
-){
- pSession->hook.pCtx = (void*)pSession->db;
- pSession->hook.xOld = sessionPreupdateOld;
- pSession->hook.xNew = sessionPreupdateNew;
- pSession->hook.xCount = sessionPreupdateCount;
- pSession->hook.xDepth = sessionPreupdateDepth;
-}
-
-typedef struct SessionDiffCtx SessionDiffCtx;
-struct SessionDiffCtx {
- sqlite3_stmt *pStmt;
- int nOldOff;
-};
-
-/*
-** The diff hook implementations.
-*/
-static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){
- SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
- *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff);
- return SQLITE_OK;
-}
-static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){
- SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
- *ppVal = sqlite3_column_value(p->pStmt, iVal);
- return SQLITE_OK;
-}
-static int sessionDiffCount(void *pCtx){
- SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
- return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt);
-}
-static int sessionDiffDepth(void *pCtx){
- return 0;
-}
-
-/*
-** Install the diff hooks on the session object passed as the only
-** argument.
-*/
-static void sessionDiffHooks(
- sqlite3_session *pSession,
- SessionDiffCtx *pDiffCtx
-){
- pSession->hook.pCtx = (void*)pDiffCtx;
- pSession->hook.xOld = sessionDiffOld;
- pSession->hook.xNew = sessionDiffNew;
- pSession->hook.xCount = sessionDiffCount;
- pSession->hook.xDepth = sessionDiffDepth;
-}
-
-static char *sessionExprComparePK(
- int nCol,
+ ** to the next session object attached to this database. */
+ if( pSession->bEnable==0 ) continue;
+ if( pSession->rc ) continue;
+ if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue;
+
+ pSession->rc = sessionFindTable(pSession, zName, &pTab);
+ if( pTab ){
+ assert( pSession->rc==SQLITE_OK );
+ sessionPreupdateOneChange(op, pSession, pTab);
+ if( op==SQLITE_UPDATE ){
+ sessionPreupdateOneChange(SQLITE_INSERT, pSession, pTab);
+ }
+ }
+ }
+}
+
+/*
+** The pre-update hook implementations.
+*/
+static int sessionPreupdateOld(void *pCtx, int iVal, sqlite3_value **ppVal){
+ return sqlite3_preupdate_old((sqlite3*)pCtx, iVal, ppVal);
+}
+static int sessionPreupdateNew(void *pCtx, int iVal, sqlite3_value **ppVal){
+ return sqlite3_preupdate_new((sqlite3*)pCtx, iVal, ppVal);
+}
+static int sessionPreupdateCount(void *pCtx){
+ return sqlite3_preupdate_count((sqlite3*)pCtx);
+}
+static int sessionPreupdateDepth(void *pCtx){
+ return sqlite3_preupdate_depth((sqlite3*)pCtx);
+}
+
+/*
+** Install the pre-update hooks on the session object passed as the only
+** argument.
+*/
+static void sessionPreupdateHooks(
+ sqlite3_session *pSession
+){
+ pSession->hook.pCtx = (void*)pSession->db;
+ pSession->hook.xOld = sessionPreupdateOld;
+ pSession->hook.xNew = sessionPreupdateNew;
+ pSession->hook.xCount = sessionPreupdateCount;
+ pSession->hook.xDepth = sessionPreupdateDepth;
+}
+
+typedef struct SessionDiffCtx SessionDiffCtx;
+struct SessionDiffCtx {
+ sqlite3_stmt *pStmt;
+ int nOldOff;
+};
+
+/*
+** The diff hook implementations.
+*/
+static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){
+ SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
+ *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff);
+ return SQLITE_OK;
+}
+static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){
+ SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
+ *ppVal = sqlite3_column_value(p->pStmt, iVal);
+ return SQLITE_OK;
+}
+static int sessionDiffCount(void *pCtx){
+ SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
+ return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt);
+}
+static int sessionDiffDepth(void *pCtx){
+ return 0;
+}
+
+/*
+** Install the diff hooks on the session object passed as the only
+** argument.
+*/
+static void sessionDiffHooks(
+ sqlite3_session *pSession,
+ SessionDiffCtx *pDiffCtx
+){
+ pSession->hook.pCtx = (void*)pDiffCtx;
+ pSession->hook.xOld = sessionDiffOld;
+ pSession->hook.xNew = sessionDiffNew;
+ pSession->hook.xCount = sessionDiffCount;
+ pSession->hook.xDepth = sessionDiffDepth;
+}
+
+static char *sessionExprComparePK(
+ int nCol,
const char *zDb1, const char *zDb2,
- const char *zTab,
- const char **azCol, u8 *abPK
-){
- int i;
- const char *zSep = "";
- char *zRet = 0;
-
- for(i=0; i<nCol; i++){
- if( abPK[i] ){
- zRet = sqlite3_mprintf("%z%s\"%w\".\"%w\".\"%w\"=\"%w\".\"%w\".\"%w\"",
- zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
- );
- zSep = " AND ";
- if( zRet==0 ) break;
- }
- }
-
- return zRet;
-}
-
-static char *sessionExprCompareOther(
- int nCol,
+ const char *zTab,
+ const char **azCol, u8 *abPK
+){
+ int i;
+ const char *zSep = "";
+ char *zRet = 0;
+
+ for(i=0; i<nCol; i++){
+ if( abPK[i] ){
+ zRet = sqlite3_mprintf("%z%s\"%w\".\"%w\".\"%w\"=\"%w\".\"%w\".\"%w\"",
+ zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
+ );
+ zSep = " AND ";
+ if( zRet==0 ) break;
+ }
+ }
+
+ return zRet;
+}
+
+static char *sessionExprCompareOther(
+ int nCol,
const char *zDb1, const char *zDb2,
- const char *zTab,
- const char **azCol, u8 *abPK
-){
- int i;
- const char *zSep = "";
- char *zRet = 0;
- int bHave = 0;
-
- for(i=0; i<nCol; i++){
- if( abPK[i]==0 ){
- bHave = 1;
- zRet = sqlite3_mprintf(
- "%z%s\"%w\".\"%w\".\"%w\" IS NOT \"%w\".\"%w\".\"%w\"",
- zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
- );
- zSep = " OR ";
- if( zRet==0 ) break;
- }
- }
-
- if( bHave==0 ){
- assert( zRet==0 );
- zRet = sqlite3_mprintf("0");
- }
-
- return zRet;
-}
-
-static char *sessionSelectFindNew(
- int nCol,
- const char *zDb1, /* Pick rows in this db only */
- const char *zDb2, /* But not in this one */
- const char *zTbl, /* Table name */
- const char *zExpr
-){
- char *zRet = sqlite3_mprintf(
- "SELECT * FROM \"%w\".\"%w\" WHERE NOT EXISTS ("
- " SELECT 1 FROM \"%w\".\"%w\" WHERE %s"
- ")",
- zDb1, zTbl, zDb2, zTbl, zExpr
- );
- return zRet;
-}
-
-static int sessionDiffFindNew(
- int op,
- sqlite3_session *pSession,
- SessionTable *pTab,
- const char *zDb1,
- const char *zDb2,
- char *zExpr
-){
- int rc = SQLITE_OK;
- char *zStmt = sessionSelectFindNew(pTab->nCol, zDb1, zDb2, pTab->zName,zExpr);
-
- if( zStmt==0 ){
- rc = SQLITE_NOMEM;
- }else{
- sqlite3_stmt *pStmt;
- rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
- if( rc==SQLITE_OK ){
- SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
- pDiffCtx->pStmt = pStmt;
- pDiffCtx->nOldOff = 0;
- while( SQLITE_ROW==sqlite3_step(pStmt) ){
- sessionPreupdateOneChange(op, pSession, pTab);
- }
- rc = sqlite3_finalize(pStmt);
- }
- sqlite3_free(zStmt);
- }
-
- return rc;
-}
-
-static int sessionDiffFindModified(
+ const char *zTab,
+ const char **azCol, u8 *abPK
+){
+ int i;
+ const char *zSep = "";
+ char *zRet = 0;
+ int bHave = 0;
+
+ for(i=0; i<nCol; i++){
+ if( abPK[i]==0 ){
+ bHave = 1;
+ zRet = sqlite3_mprintf(
+ "%z%s\"%w\".\"%w\".\"%w\" IS NOT \"%w\".\"%w\".\"%w\"",
+ zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
+ );
+ zSep = " OR ";
+ if( zRet==0 ) break;
+ }
+ }
+
+ if( bHave==0 ){
+ assert( zRet==0 );
+ zRet = sqlite3_mprintf("0");
+ }
+
+ return zRet;
+}
+
+static char *sessionSelectFindNew(
+ int nCol,
+ const char *zDb1, /* Pick rows in this db only */
+ const char *zDb2, /* But not in this one */
+ const char *zTbl, /* Table name */
+ const char *zExpr
+){
+ char *zRet = sqlite3_mprintf(
+ "SELECT * FROM \"%w\".\"%w\" WHERE NOT EXISTS ("
+ " SELECT 1 FROM \"%w\".\"%w\" WHERE %s"
+ ")",
+ zDb1, zTbl, zDb2, zTbl, zExpr
+ );
+ return zRet;
+}
+
+static int sessionDiffFindNew(
+ int op,
+ sqlite3_session *pSession,
+ SessionTable *pTab,
+ const char *zDb1,
+ const char *zDb2,
+ char *zExpr
+){
+ int rc = SQLITE_OK;
+ char *zStmt = sessionSelectFindNew(pTab->nCol, zDb1, zDb2, pTab->zName,zExpr);
+
+ if( zStmt==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_stmt *pStmt;
+ rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
+ if( rc==SQLITE_OK ){
+ SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
+ pDiffCtx->pStmt = pStmt;
+ pDiffCtx->nOldOff = 0;
+ while( SQLITE_ROW==sqlite3_step(pStmt) ){
+ sessionPreupdateOneChange(op, pSession, pTab);
+ }
+ rc = sqlite3_finalize(pStmt);
+ }
+ sqlite3_free(zStmt);
+ }
+
+ return rc;
+}
+
+static int sessionDiffFindModified(
sqlite3_session *pSession,
SessionTable *pTab,
const char *zFrom,
- const char *zExpr
-){
- int rc = SQLITE_OK;
-
- char *zExpr2 = sessionExprCompareOther(pTab->nCol,
- pSession->zDb, zFrom, pTab->zName, pTab->azCol, pTab->abPK
- );
- if( zExpr2==0 ){
- rc = SQLITE_NOMEM;
- }else{
- char *zStmt = sqlite3_mprintf(
- "SELECT * FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)",
- pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2
- );
- if( zStmt==0 ){
- rc = SQLITE_NOMEM;
- }else{
- sqlite3_stmt *pStmt;
- rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
-
- if( rc==SQLITE_OK ){
- SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
- pDiffCtx->pStmt = pStmt;
- pDiffCtx->nOldOff = pTab->nCol;
- while( SQLITE_ROW==sqlite3_step(pStmt) ){
- sessionPreupdateOneChange(SQLITE_UPDATE, pSession, pTab);
- }
- rc = sqlite3_finalize(pStmt);
- }
- sqlite3_free(zStmt);
- }
- }
-
- return rc;
-}
-
-SQLITE_API int sqlite3session_diff(
- sqlite3_session *pSession,
- const char *zFrom,
- const char *zTbl,
- char **pzErrMsg
-){
- const char *zDb = pSession->zDb;
- int rc = pSession->rc;
- SessionDiffCtx d;
-
- memset(&d, 0, sizeof(d));
- sessionDiffHooks(pSession, &d);
-
- sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
- if( pzErrMsg ) *pzErrMsg = 0;
- if( rc==SQLITE_OK ){
- char *zExpr = 0;
- sqlite3 *db = pSession->db;
- SessionTable *pTo; /* Table zTbl */
-
- /* Locate and if necessary initialize the target table object */
- rc = sessionFindTable(pSession, zTbl, &pTo);
- if( pTo==0 ) goto diff_out;
- if( sessionInitTable(pSession, pTo) ){
- rc = pSession->rc;
- goto diff_out;
- }
-
- /* Check the table schemas match */
- if( rc==SQLITE_OK ){
- int bHasPk = 0;
- int bMismatch = 0;
- int nCol; /* Columns in zFrom.zTbl */
- u8 *abPK;
- const char **azCol = 0;
+ const char *zExpr
+){
+ int rc = SQLITE_OK;
+
+ char *zExpr2 = sessionExprCompareOther(pTab->nCol,
+ pSession->zDb, zFrom, pTab->zName, pTab->azCol, pTab->abPK
+ );
+ if( zExpr2==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ char *zStmt = sqlite3_mprintf(
+ "SELECT * FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)",
+ pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2
+ );
+ if( zStmt==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_stmt *pStmt;
+ rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
+
+ if( rc==SQLITE_OK ){
+ SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
+ pDiffCtx->pStmt = pStmt;
+ pDiffCtx->nOldOff = pTab->nCol;
+ while( SQLITE_ROW==sqlite3_step(pStmt) ){
+ sessionPreupdateOneChange(SQLITE_UPDATE, pSession, pTab);
+ }
+ rc = sqlite3_finalize(pStmt);
+ }
+ sqlite3_free(zStmt);
+ }
+ }
+
+ return rc;
+}
+
+SQLITE_API int sqlite3session_diff(
+ sqlite3_session *pSession,
+ const char *zFrom,
+ const char *zTbl,
+ char **pzErrMsg
+){
+ const char *zDb = pSession->zDb;
+ int rc = pSession->rc;
+ SessionDiffCtx d;
+
+ memset(&d, 0, sizeof(d));
+ sessionDiffHooks(pSession, &d);
+
+ sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
+ if( pzErrMsg ) *pzErrMsg = 0;
+ if( rc==SQLITE_OK ){
+ char *zExpr = 0;
+ sqlite3 *db = pSession->db;
+ SessionTable *pTo; /* Table zTbl */
+
+ /* Locate and if necessary initialize the target table object */
+ rc = sessionFindTable(pSession, zTbl, &pTo);
+ if( pTo==0 ) goto diff_out;
+ if( sessionInitTable(pSession, pTo) ){
+ rc = pSession->rc;
+ goto diff_out;
+ }
+
+ /* Check the table schemas match */
+ if( rc==SQLITE_OK ){
+ int bHasPk = 0;
+ int bMismatch = 0;
+ int nCol; /* Columns in zFrom.zTbl */
+ u8 *abPK;
+ const char **azCol = 0;
rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK);
- if( rc==SQLITE_OK ){
- if( pTo->nCol!=nCol ){
- bMismatch = 1;
- }else{
- int i;
- for(i=0; i<nCol; i++){
- if( pTo->abPK[i]!=abPK[i] ) bMismatch = 1;
- if( sqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1;
- if( abPK[i] ) bHasPk = 1;
- }
- }
- }
- sqlite3_free((char*)azCol);
- if( bMismatch ){
+ if( rc==SQLITE_OK ){
+ if( pTo->nCol!=nCol ){
+ bMismatch = 1;
+ }else{
+ int i;
+ for(i=0; i<nCol; i++){
+ if( pTo->abPK[i]!=abPK[i] ) bMismatch = 1;
+ if( sqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1;
+ if( abPK[i] ) bHasPk = 1;
+ }
+ }
+ }
+ sqlite3_free((char*)azCol);
+ if( bMismatch ){
if( pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("table schemas do not match");
}
- rc = SQLITE_SCHEMA;
- }
- if( bHasPk==0 ){
- /* Ignore tables with no primary keys */
- goto diff_out;
- }
- }
-
- if( rc==SQLITE_OK ){
+ rc = SQLITE_SCHEMA;
+ }
+ if( bHasPk==0 ){
+ /* Ignore tables with no primary keys */
+ goto diff_out;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
zExpr = sessionExprComparePK(pTo->nCol,
- zDb, zFrom, pTo->zName, pTo->azCol, pTo->abPK
- );
- }
-
- /* Find new rows */
- if( rc==SQLITE_OK ){
- rc = sessionDiffFindNew(SQLITE_INSERT, pSession, pTo, zDb, zFrom, zExpr);
- }
-
- /* Find old rows */
- if( rc==SQLITE_OK ){
- rc = sessionDiffFindNew(SQLITE_DELETE, pSession, pTo, zFrom, zDb, zExpr);
- }
-
- /* Find modified rows */
- if( rc==SQLITE_OK ){
- rc = sessionDiffFindModified(pSession, pTo, zFrom, zExpr);
- }
-
- sqlite3_free(zExpr);
- }
-
- diff_out:
- sessionPreupdateHooks(pSession);
- sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
- return rc;
-}
-
-/*
-** Create a session object. This session object will record changes to
-** database zDb attached to connection db.
-*/
-SQLITE_API int sqlite3session_create(
- sqlite3 *db, /* Database handle */
- const char *zDb, /* Name of db (e.g. "main") */
- sqlite3_session **ppSession /* OUT: New session object */
-){
- sqlite3_session *pNew; /* Newly allocated session object */
- sqlite3_session *pOld; /* Session object already attached to db */
- int nDb = sqlite3Strlen30(zDb); /* Length of zDb in bytes */
-
- /* Zero the output value in case an error occurs. */
- *ppSession = 0;
-
- /* Allocate and populate the new session object. */
+ zDb, zFrom, pTo->zName, pTo->azCol, pTo->abPK
+ );
+ }
+
+ /* Find new rows */
+ if( rc==SQLITE_OK ){
+ rc = sessionDiffFindNew(SQLITE_INSERT, pSession, pTo, zDb, zFrom, zExpr);
+ }
+
+ /* Find old rows */
+ if( rc==SQLITE_OK ){
+ rc = sessionDiffFindNew(SQLITE_DELETE, pSession, pTo, zFrom, zDb, zExpr);
+ }
+
+ /* Find modified rows */
+ if( rc==SQLITE_OK ){
+ rc = sessionDiffFindModified(pSession, pTo, zFrom, zExpr);
+ }
+
+ sqlite3_free(zExpr);
+ }
+
+ diff_out:
+ sessionPreupdateHooks(pSession);
+ sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
+ return rc;
+}
+
+/*
+** Create a session object. This session object will record changes to
+** database zDb attached to connection db.
+*/
+SQLITE_API int sqlite3session_create(
+ sqlite3 *db, /* Database handle */
+ const char *zDb, /* Name of db (e.g. "main") */
+ sqlite3_session **ppSession /* OUT: New session object */
+){
+ sqlite3_session *pNew; /* Newly allocated session object */
+ sqlite3_session *pOld; /* Session object already attached to db */
+ int nDb = sqlite3Strlen30(zDb); /* Length of zDb in bytes */
+
+ /* Zero the output value in case an error occurs. */
+ *ppSession = 0;
+
+ /* Allocate and populate the new session object. */
pNew = (sqlite3_session *)sqlite3_malloc64(sizeof(sqlite3_session) + nDb + 1);
- if( !pNew ) return SQLITE_NOMEM;
- memset(pNew, 0, sizeof(sqlite3_session));
- pNew->db = db;
- pNew->zDb = (char *)&pNew[1];
- pNew->bEnable = 1;
- memcpy(pNew->zDb, zDb, nDb+1);
- sessionPreupdateHooks(pNew);
-
+ if( !pNew ) return SQLITE_NOMEM;
+ memset(pNew, 0, sizeof(sqlite3_session));
+ pNew->db = db;
+ pNew->zDb = (char *)&pNew[1];
+ pNew->bEnable = 1;
+ memcpy(pNew->zDb, zDb, nDb+1);
+ sessionPreupdateHooks(pNew);
+
/* Add the new session object to the linked list of session objects
- ** attached to database handle $db. Do this under the cover of the db
- ** handle mutex. */
- sqlite3_mutex_enter(sqlite3_db_mutex(db));
- pOld = (sqlite3_session*)sqlite3_preupdate_hook(db, xPreUpdate, (void*)pNew);
- pNew->pNext = pOld;
- sqlite3_mutex_leave(sqlite3_db_mutex(db));
-
- *ppSession = pNew;
- return SQLITE_OK;
-}
-
-/*
-** Free the list of table objects passed as the first argument. The contents
-** of the changed-rows hash tables are also deleted.
-*/
+ ** attached to database handle $db. Do this under the cover of the db
+ ** handle mutex. */
+ sqlite3_mutex_enter(sqlite3_db_mutex(db));
+ pOld = (sqlite3_session*)sqlite3_preupdate_hook(db, xPreUpdate, (void*)pNew);
+ pNew->pNext = pOld;
+ sqlite3_mutex_leave(sqlite3_db_mutex(db));
+
+ *ppSession = pNew;
+ return SQLITE_OK;
+}
+
+/*
+** Free the list of table objects passed as the first argument. The contents
+** of the changed-rows hash tables are also deleted.
+*/
static void sessionDeleteTable(sqlite3_session *pSession, SessionTable *pList){
- SessionTable *pNext;
- SessionTable *pTab;
-
- for(pTab=pList; pTab; pTab=pNext){
- int i;
- pNext = pTab->pNext;
- for(i=0; i<pTab->nChange; i++){
- SessionChange *p;
- SessionChange *pNextChange;
- for(p=pTab->apChange[i]; p; p=pNextChange){
- pNextChange = p->pNext;
+ SessionTable *pNext;
+ SessionTable *pTab;
+
+ for(pTab=pList; pTab; pTab=pNext){
+ int i;
+ pNext = pTab->pNext;
+ for(i=0; i<pTab->nChange; i++){
+ SessionChange *p;
+ SessionChange *pNextChange;
+ for(p=pTab->apChange[i]; p; p=pNextChange){
+ pNextChange = p->pNext;
sessionFree(pSession, p);
- }
- }
+ }
+ }
sessionFree(pSession, (char*)pTab->azCol); /* cast works around VC++ bug */
sessionFree(pSession, pTab->apChange);
sessionFree(pSession, pTab);
- }
-}
-
-/*
-** Delete a session object previously allocated using sqlite3session_create().
-*/
-SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){
- sqlite3 *db = pSession->db;
- sqlite3_session *pHead;
- sqlite3_session **pp;
-
- /* Unlink the session from the linked list of sessions attached to the
- ** database handle. Hold the db mutex while doing so. */
- sqlite3_mutex_enter(sqlite3_db_mutex(db));
- pHead = (sqlite3_session*)sqlite3_preupdate_hook(db, 0, 0);
- for(pp=&pHead; ALWAYS((*pp)!=0); pp=&((*pp)->pNext)){
- if( (*pp)==pSession ){
- *pp = (*pp)->pNext;
- if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void*)pHead);
- break;
- }
- }
- sqlite3_mutex_leave(sqlite3_db_mutex(db));
- sqlite3ValueFree(pSession->pZeroBlob);
-
+ }
+}
+
+/*
+** Delete a session object previously allocated using sqlite3session_create().
+*/
+SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){
+ sqlite3 *db = pSession->db;
+ sqlite3_session *pHead;
+ sqlite3_session **pp;
+
+ /* Unlink the session from the linked list of sessions attached to the
+ ** database handle. Hold the db mutex while doing so. */
+ sqlite3_mutex_enter(sqlite3_db_mutex(db));
+ pHead = (sqlite3_session*)sqlite3_preupdate_hook(db, 0, 0);
+ for(pp=&pHead; ALWAYS((*pp)!=0); pp=&((*pp)->pNext)){
+ if( (*pp)==pSession ){
+ *pp = (*pp)->pNext;
+ if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void*)pHead);
+ break;
+ }
+ }
+ sqlite3_mutex_leave(sqlite3_db_mutex(db));
+ sqlite3ValueFree(pSession->pZeroBlob);
+
/* Delete all attached table objects. And the contents of their
- ** associated hash-tables. */
+ ** associated hash-tables. */
sessionDeleteTable(pSession, pSession->pTable);
-
+
/* Assert that all allocations have been freed and then free the
** session object itself. */
assert( pSession->nMalloc==0 );
- sqlite3_free(pSession);
-}
-
-/*
-** Set a table filter on a Session Object.
-*/
-SQLITE_API void sqlite3session_table_filter(
+ sqlite3_free(pSession);
+}
+
+/*
+** Set a table filter on a Session Object.
+*/
+SQLITE_API void sqlite3session_table_filter(
sqlite3_session *pSession,
- int(*xFilter)(void*, const char*),
- void *pCtx /* First argument passed to xFilter */
-){
- pSession->bAutoAttach = 1;
- pSession->pFilterCtx = pCtx;
- pSession->xTableFilter = xFilter;
-}
-
-/*
-** Attach a table to a session. All subsequent changes made to the table
-** while the session object is enabled will be recorded.
-**
-** Only tables that have a PRIMARY KEY defined may be attached. It does
-** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias)
-** or not.
-*/
-SQLITE_API int sqlite3session_attach(
- sqlite3_session *pSession, /* Session object */
- const char *zName /* Table name */
-){
- int rc = SQLITE_OK;
- sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
-
- if( !zName ){
- pSession->bAutoAttach = 1;
- }else{
- SessionTable *pTab; /* New table object (if required) */
- int nName; /* Number of bytes in string zName */
-
- /* First search for an existing entry. If one is found, this call is
- ** a no-op. Return early. */
- nName = sqlite3Strlen30(zName);
- for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
- if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
- }
-
- if( !pTab ){
- /* Allocate new SessionTable object. */
+ int(*xFilter)(void*, const char*),
+ void *pCtx /* First argument passed to xFilter */
+){
+ pSession->bAutoAttach = 1;
+ pSession->pFilterCtx = pCtx;
+ pSession->xTableFilter = xFilter;
+}
+
+/*
+** Attach a table to a session. All subsequent changes made to the table
+** while the session object is enabled will be recorded.
+**
+** Only tables that have a PRIMARY KEY defined may be attached. It does
+** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias)
+** or not.
+*/
+SQLITE_API int sqlite3session_attach(
+ sqlite3_session *pSession, /* Session object */
+ const char *zName /* Table name */
+){
+ int rc = SQLITE_OK;
+ sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
+
+ if( !zName ){
+ pSession->bAutoAttach = 1;
+ }else{
+ SessionTable *pTab; /* New table object (if required) */
+ int nName; /* Number of bytes in string zName */
+
+ /* First search for an existing entry. If one is found, this call is
+ ** a no-op. Return early. */
+ nName = sqlite3Strlen30(zName);
+ for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
+ if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
+ }
+
+ if( !pTab ){
+ /* Allocate new SessionTable object. */
int nByte = sizeof(SessionTable) + nName + 1;
pTab = (SessionTable*)sessionMalloc64(pSession, nByte);
- if( !pTab ){
- rc = SQLITE_NOMEM;
- }else{
- /* Populate the new SessionTable object and link it into the list.
+ if( !pTab ){
+ rc = SQLITE_NOMEM;
+ }else{
+ /* Populate the new SessionTable object and link it into the list.
** The new object must be linked onto the end of the list, not
- ** simply added to the start of it in order to ensure that tables
- ** appear in the correct order when a changeset or patchset is
- ** eventually generated. */
- SessionTable **ppTab;
- memset(pTab, 0, sizeof(SessionTable));
- pTab->zName = (char *)&pTab[1];
- memcpy(pTab->zName, zName, nName+1);
- for(ppTab=&pSession->pTable; *ppTab; ppTab=&(*ppTab)->pNext);
- *ppTab = pTab;
- }
- }
- }
-
- sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
- return rc;
-}
-
-/*
-** Ensure that there is room in the buffer to append nByte bytes of data.
-** If not, use sqlite3_realloc() to grow the buffer so that there is.
-**
-** If successful, return zero. Otherwise, if an OOM condition is encountered,
-** set *pRc to SQLITE_NOMEM and return non-zero.
-*/
+ ** simply added to the start of it in order to ensure that tables
+ ** appear in the correct order when a changeset or patchset is
+ ** eventually generated. */
+ SessionTable **ppTab;
+ memset(pTab, 0, sizeof(SessionTable));
+ pTab->zName = (char *)&pTab[1];
+ memcpy(pTab->zName, zName, nName+1);
+ for(ppTab=&pSession->pTable; *ppTab; ppTab=&(*ppTab)->pNext);
+ *ppTab = pTab;
+ }
+ }
+ }
+
+ sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
+ return rc;
+}
+
+/*
+** Ensure that there is room in the buffer to append nByte bytes of data.
+** If not, use sqlite3_realloc() to grow the buffer so that there is.
+**
+** If successful, return zero. Otherwise, if an OOM condition is encountered,
+** set *pRc to SQLITE_NOMEM and return non-zero.
+*/
static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){
#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1)
i64 nReq = p->nBuf + nByte;
if( *pRc==SQLITE_OK && nReq>p->nAlloc ){
- u8 *aNew;
+ u8 *aNew;
i64 nNew = p->nAlloc ? p->nAlloc : 128;
- do {
- nNew = nNew*2;
+ do {
+ nNew = nNew*2;
}while( nNew<nReq );
-
+
/* The value of SESSION_MAX_BUFFER_SZ is copied from the implementation
** of sqlite3_realloc64(). Allocations greater than this size in bytes
** always fail. It is used here to ensure that this routine can always
@@ -210490,658 +210490,658 @@ static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){
}
aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
- if( 0==aNew ){
- *pRc = SQLITE_NOMEM;
- }else{
- p->aBuf = aNew;
- p->nAlloc = nNew;
- }
- }
- return (*pRc!=SQLITE_OK);
-}
-
-/*
-** Append the value passed as the second argument to the buffer passed
-** as the first.
-**
-** This function is a no-op if *pRc is non-zero when it is called.
-** Otherwise, if an error occurs, *pRc is set to an SQLite error code
-** before returning.
-*/
-static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){
- int rc = *pRc;
- if( rc==SQLITE_OK ){
+ if( 0==aNew ){
+ *pRc = SQLITE_NOMEM;
+ }else{
+ p->aBuf = aNew;
+ p->nAlloc = nNew;
+ }
+ }
+ return (*pRc!=SQLITE_OK);
+}
+
+/*
+** Append the value passed as the second argument to the buffer passed
+** as the first.
+**
+** This function is a no-op if *pRc is non-zero when it is called.
+** Otherwise, if an error occurs, *pRc is set to an SQLite error code
+** before returning.
+*/
+static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){
+ int rc = *pRc;
+ if( rc==SQLITE_OK ){
sqlite3_int64 nByte = 0;
- rc = sessionSerializeValue(0, pVal, &nByte);
- sessionBufferGrow(p, nByte, &rc);
- if( rc==SQLITE_OK ){
- rc = sessionSerializeValue(&p->aBuf[p->nBuf], pVal, 0);
- p->nBuf += nByte;
- }else{
- *pRc = rc;
- }
- }
-}
-
-/*
+ rc = sessionSerializeValue(0, pVal, &nByte);
+ sessionBufferGrow(p, nByte, &rc);
+ if( rc==SQLITE_OK ){
+ rc = sessionSerializeValue(&p->aBuf[p->nBuf], pVal, 0);
+ p->nBuf += nByte;
+ }else{
+ *pRc = rc;
+ }
+ }
+}
+
+/*
** This function is a no-op if *pRc is other than SQLITE_OK when it is
** called. Otherwise, append a single byte to the buffer.
-**
-** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
-** returning.
-*/
-static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){
- if( 0==sessionBufferGrow(p, 1, pRc) ){
- p->aBuf[p->nBuf++] = v;
- }
-}
-
-/*
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){
+ if( 0==sessionBufferGrow(p, 1, pRc) ){
+ p->aBuf[p->nBuf++] = v;
+ }
+}
+
+/*
** This function is a no-op if *pRc is other than SQLITE_OK when it is
** called. Otherwise, append a single varint to the buffer.
-**
-** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
-** returning.
-*/
-static void sessionAppendVarint(SessionBuffer *p, int v, int *pRc){
- if( 0==sessionBufferGrow(p, 9, pRc) ){
- p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v);
- }
-}
-
-/*
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendVarint(SessionBuffer *p, int v, int *pRc){
+ if( 0==sessionBufferGrow(p, 9, pRc) ){
+ p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v);
+ }
+}
+
+/*
** This function is a no-op if *pRc is other than SQLITE_OK when it is
** called. Otherwise, append a blob of data to the buffer.
-**
-** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
-** returning.
-*/
-static void sessionAppendBlob(
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendBlob(
SessionBuffer *p,
const u8 *aBlob,
int nBlob,
- int *pRc
-){
- if( nBlob>0 && 0==sessionBufferGrow(p, nBlob, pRc) ){
- memcpy(&p->aBuf[p->nBuf], aBlob, nBlob);
- p->nBuf += nBlob;
- }
-}
-
-/*
+ int *pRc
+){
+ if( nBlob>0 && 0==sessionBufferGrow(p, nBlob, pRc) ){
+ memcpy(&p->aBuf[p->nBuf], aBlob, nBlob);
+ p->nBuf += nBlob;
+ }
+}
+
+/*
** This function is a no-op if *pRc is other than SQLITE_OK when it is
-** called. Otherwise, append a string to the buffer. All bytes in the string
-** up to (but not including) the nul-terminator are written to the buffer.
-**
-** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
-** returning.
-*/
-static void sessionAppendStr(
+** called. Otherwise, append a string to the buffer. All bytes in the string
+** up to (but not including) the nul-terminator are written to the buffer.
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendStr(
SessionBuffer *p,
const char *zStr,
- int *pRc
-){
- int nStr = sqlite3Strlen30(zStr);
- if( 0==sessionBufferGrow(p, nStr, pRc) ){
- memcpy(&p->aBuf[p->nBuf], zStr, nStr);
- p->nBuf += nStr;
- }
-}
-
-/*
+ int *pRc
+){
+ int nStr = sqlite3Strlen30(zStr);
+ if( 0==sessionBufferGrow(p, nStr, pRc) ){
+ memcpy(&p->aBuf[p->nBuf], zStr, nStr);
+ p->nBuf += nStr;
+ }
+}
+
+/*
** This function is a no-op if *pRc is other than SQLITE_OK when it is
-** called. Otherwise, append the string representation of integer iVal
-** to the buffer. No nul-terminator is written.
-**
-** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
-** returning.
-*/
-static void sessionAppendInteger(
- SessionBuffer *p, /* Buffer to append to */
- int iVal, /* Value to write the string rep. of */
- int *pRc /* IN/OUT: Error code */
-){
- char aBuf[24];
- sqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal);
- sessionAppendStr(p, aBuf, pRc);
-}
-
-/*
+** called. Otherwise, append the string representation of integer iVal
+** to the buffer. No nul-terminator is written.
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendInteger(
+ SessionBuffer *p, /* Buffer to append to */
+ int iVal, /* Value to write the string rep. of */
+ int *pRc /* IN/OUT: Error code */
+){
+ char aBuf[24];
+ sqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal);
+ sessionAppendStr(p, aBuf, pRc);
+}
+
+/*
** This function is a no-op if *pRc is other than SQLITE_OK when it is
-** called. Otherwise, append the string zStr enclosed in quotes (") and
+** called. Otherwise, append the string zStr enclosed in quotes (") and
** with any embedded quote characters escaped to the buffer. No
-** nul-terminator byte is written.
-**
-** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
-** returning.
-*/
-static void sessionAppendIdent(
- SessionBuffer *p, /* Buffer to a append to */
- const char *zStr, /* String to quote, escape and append */
- int *pRc /* IN/OUT: Error code */
-){
- int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1;
- if( 0==sessionBufferGrow(p, nStr, pRc) ){
- char *zOut = (char *)&p->aBuf[p->nBuf];
- const char *zIn = zStr;
- *zOut++ = '"';
- while( *zIn ){
- if( *zIn=='"' ) *zOut++ = '"';
- *zOut++ = *(zIn++);
- }
- *zOut++ = '"';
- p->nBuf = (int)((u8 *)zOut - p->aBuf);
- }
-}
-
-/*
-** This function is a no-op if *pRc is other than SQLITE_OK when it is
-** called. Otherwse, it appends the serialized version of the value stored
-** in column iCol of the row that SQL statement pStmt currently points
-** to to the buffer.
-*/
-static void sessionAppendCol(
- SessionBuffer *p, /* Buffer to append to */
- sqlite3_stmt *pStmt, /* Handle pointing to row containing value */
- int iCol, /* Column to read value from */
- int *pRc /* IN/OUT: Error code */
-){
- if( *pRc==SQLITE_OK ){
- int eType = sqlite3_column_type(pStmt, iCol);
- sessionAppendByte(p, (u8)eType, pRc);
- if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
- sqlite3_int64 i;
- u8 aBuf[8];
- if( eType==SQLITE_INTEGER ){
- i = sqlite3_column_int64(pStmt, iCol);
- }else{
- double r = sqlite3_column_double(pStmt, iCol);
- memcpy(&i, &r, 8);
- }
- sessionPutI64(aBuf, i);
- sessionAppendBlob(p, aBuf, 8, pRc);
- }
- if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){
- u8 *z;
- int nByte;
- if( eType==SQLITE_BLOB ){
- z = (u8 *)sqlite3_column_blob(pStmt, iCol);
- }else{
- z = (u8 *)sqlite3_column_text(pStmt, iCol);
- }
- nByte = sqlite3_column_bytes(pStmt, iCol);
- if( z || (eType==SQLITE_BLOB && nByte==0) ){
- sessionAppendVarint(p, nByte, pRc);
- sessionAppendBlob(p, z, nByte, pRc);
- }else{
- *pRc = SQLITE_NOMEM;
- }
- }
- }
-}
-
-/*
-**
+** nul-terminator byte is written.
+**
+** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
+** returning.
+*/
+static void sessionAppendIdent(
+ SessionBuffer *p, /* Buffer to a append to */
+ const char *zStr, /* String to quote, escape and append */
+ int *pRc /* IN/OUT: Error code */
+){
+ int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1;
+ if( 0==sessionBufferGrow(p, nStr, pRc) ){
+ char *zOut = (char *)&p->aBuf[p->nBuf];
+ const char *zIn = zStr;
+ *zOut++ = '"';
+ while( *zIn ){
+ if( *zIn=='"' ) *zOut++ = '"';
+ *zOut++ = *(zIn++);
+ }
+ *zOut++ = '"';
+ p->nBuf = (int)((u8 *)zOut - p->aBuf);
+ }
+}
+
+/*
+** This function is a no-op if *pRc is other than SQLITE_OK when it is
+** called. Otherwse, it appends the serialized version of the value stored
+** in column iCol of the row that SQL statement pStmt currently points
+** to to the buffer.
+*/
+static void sessionAppendCol(
+ SessionBuffer *p, /* Buffer to append to */
+ sqlite3_stmt *pStmt, /* Handle pointing to row containing value */
+ int iCol, /* Column to read value from */
+ int *pRc /* IN/OUT: Error code */
+){
+ if( *pRc==SQLITE_OK ){
+ int eType = sqlite3_column_type(pStmt, iCol);
+ sessionAppendByte(p, (u8)eType, pRc);
+ if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+ sqlite3_int64 i;
+ u8 aBuf[8];
+ if( eType==SQLITE_INTEGER ){
+ i = sqlite3_column_int64(pStmt, iCol);
+ }else{
+ double r = sqlite3_column_double(pStmt, iCol);
+ memcpy(&i, &r, 8);
+ }
+ sessionPutI64(aBuf, i);
+ sessionAppendBlob(p, aBuf, 8, pRc);
+ }
+ if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){
+ u8 *z;
+ int nByte;
+ if( eType==SQLITE_BLOB ){
+ z = (u8 *)sqlite3_column_blob(pStmt, iCol);
+ }else{
+ z = (u8 *)sqlite3_column_text(pStmt, iCol);
+ }
+ nByte = sqlite3_column_bytes(pStmt, iCol);
+ if( z || (eType==SQLITE_BLOB && nByte==0) ){
+ sessionAppendVarint(p, nByte, pRc);
+ sessionAppendBlob(p, z, nByte, pRc);
+ }else{
+ *pRc = SQLITE_NOMEM;
+ }
+ }
+ }
+}
+
+/*
+**
** This function appends an update change to the buffer (see the comments
** under "CHANGESET FORMAT" at the top of the file). An update change
-** consists of:
-**
-** 1 byte: SQLITE_UPDATE (0x17)
-** n bytes: old.* record (see RECORD FORMAT)
-** m bytes: new.* record (see RECORD FORMAT)
-**
-** The SessionChange object passed as the third argument contains the
-** values that were stored in the row when the session began (the old.*
-** values). The statement handle passed as the second argument points
-** at the current version of the row (the new.* values).
-**
-** If all of the old.* values are equal to their corresponding new.* value
-** (i.e. nothing has changed), then no data at all is appended to the buffer.
-**
+** consists of:
+**
+** 1 byte: SQLITE_UPDATE (0x17)
+** n bytes: old.* record (see RECORD FORMAT)
+** m bytes: new.* record (see RECORD FORMAT)
+**
+** The SessionChange object passed as the third argument contains the
+** values that were stored in the row when the session began (the old.*
+** values). The statement handle passed as the second argument points
+** at the current version of the row (the new.* values).
+**
+** If all of the old.* values are equal to their corresponding new.* value
+** (i.e. nothing has changed), then no data at all is appended to the buffer.
+**
** Otherwise, the old.* record contains all primary key values and the
** original values of any fields that have been modified. The new.* record
-** contains the new values of only those fields that have been modified.
-*/
-static int sessionAppendUpdate(
- SessionBuffer *pBuf, /* Buffer to append to */
- int bPatchset, /* True for "patchset", 0 for "changeset" */
- sqlite3_stmt *pStmt, /* Statement handle pointing at new row */
- SessionChange *p, /* Object containing old values */
- u8 *abPK /* Boolean array - true for PK columns */
-){
- int rc = SQLITE_OK;
- SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */
- int bNoop = 1; /* Set to zero if any values are modified */
- int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */
- int i; /* Used to iterate through columns */
- u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */
-
+** contains the new values of only those fields that have been modified.
+*/
+static int sessionAppendUpdate(
+ SessionBuffer *pBuf, /* Buffer to append to */
+ int bPatchset, /* True for "patchset", 0 for "changeset" */
+ sqlite3_stmt *pStmt, /* Statement handle pointing at new row */
+ SessionChange *p, /* Object containing old values */
+ u8 *abPK /* Boolean array - true for PK columns */
+){
+ int rc = SQLITE_OK;
+ SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */
+ int bNoop = 1; /* Set to zero if any values are modified */
+ int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */
+ int i; /* Used to iterate through columns */
+ u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */
+
assert( abPK!=0 );
- sessionAppendByte(pBuf, SQLITE_UPDATE, &rc);
- sessionAppendByte(pBuf, p->bIndirect, &rc);
- for(i=0; i<sqlite3_column_count(pStmt); i++){
- int bChanged = 0;
- int nAdvance;
- int eType = *pCsr;
- switch( eType ){
- case SQLITE_NULL:
- nAdvance = 1;
- if( sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
- bChanged = 1;
- }
- break;
-
- case SQLITE_FLOAT:
- case SQLITE_INTEGER: {
- nAdvance = 9;
- if( eType==sqlite3_column_type(pStmt, i) ){
- sqlite3_int64 iVal = sessionGetI64(&pCsr[1]);
- if( eType==SQLITE_INTEGER ){
- if( iVal==sqlite3_column_int64(pStmt, i) ) break;
- }else{
- double dVal;
- memcpy(&dVal, &iVal, 8);
- if( dVal==sqlite3_column_double(pStmt, i) ) break;
- }
- }
- bChanged = 1;
- break;
- }
-
- default: {
- int n;
- int nHdr = 1 + sessionVarintGet(&pCsr[1], &n);
- assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
- nAdvance = nHdr + n;
+ sessionAppendByte(pBuf, SQLITE_UPDATE, &rc);
+ sessionAppendByte(pBuf, p->bIndirect, &rc);
+ for(i=0; i<sqlite3_column_count(pStmt); i++){
+ int bChanged = 0;
+ int nAdvance;
+ int eType = *pCsr;
+ switch( eType ){
+ case SQLITE_NULL:
+ nAdvance = 1;
+ if( sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
+ bChanged = 1;
+ }
+ break;
+
+ case SQLITE_FLOAT:
+ case SQLITE_INTEGER: {
+ nAdvance = 9;
+ if( eType==sqlite3_column_type(pStmt, i) ){
+ sqlite3_int64 iVal = sessionGetI64(&pCsr[1]);
+ if( eType==SQLITE_INTEGER ){
+ if( iVal==sqlite3_column_int64(pStmt, i) ) break;
+ }else{
+ double dVal;
+ memcpy(&dVal, &iVal, 8);
+ if( dVal==sqlite3_column_double(pStmt, i) ) break;
+ }
+ }
+ bChanged = 1;
+ break;
+ }
+
+ default: {
+ int n;
+ int nHdr = 1 + sessionVarintGet(&pCsr[1], &n);
+ assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
+ nAdvance = nHdr + n;
if( eType==sqlite3_column_type(pStmt, i)
&& n==sqlite3_column_bytes(pStmt, i)
- && (n==0 || 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), n))
- ){
- break;
- }
- bChanged = 1;
- }
- }
-
- /* If at least one field has been modified, this is not a no-op. */
- if( bChanged ) bNoop = 0;
-
- /* Add a field to the old.* record. This is omitted if this modules is
- ** currently generating a patchset. */
- if( bPatchset==0 ){
- if( bChanged || abPK[i] ){
- sessionAppendBlob(pBuf, pCsr, nAdvance, &rc);
- }else{
- sessionAppendByte(pBuf, 0, &rc);
- }
- }
-
- /* Add a field to the new.* record. Or the only record if currently
- ** generating a patchset. */
- if( bChanged || (bPatchset && abPK[i]) ){
- sessionAppendCol(&buf2, pStmt, i, &rc);
- }else{
- sessionAppendByte(&buf2, 0, &rc);
- }
-
- pCsr += nAdvance;
- }
-
- if( bNoop ){
- pBuf->nBuf = nRewind;
- }else{
- sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, &rc);
- }
- sqlite3_free(buf2.aBuf);
-
- return rc;
-}
-
-/*
-** Append a DELETE change to the buffer passed as the first argument. Use
-** the changeset format if argument bPatchset is zero, or the patchset
-** format otherwise.
-*/
-static int sessionAppendDelete(
- SessionBuffer *pBuf, /* Buffer to append to */
- int bPatchset, /* True for "patchset", 0 for "changeset" */
- SessionChange *p, /* Object containing old values */
- int nCol, /* Number of columns in table */
- u8 *abPK /* Boolean array - true for PK columns */
-){
- int rc = SQLITE_OK;
-
- sessionAppendByte(pBuf, SQLITE_DELETE, &rc);
- sessionAppendByte(pBuf, p->bIndirect, &rc);
-
- if( bPatchset==0 ){
- sessionAppendBlob(pBuf, p->aRecord, p->nRecord, &rc);
- }else{
- int i;
- u8 *a = p->aRecord;
- for(i=0; i<nCol; i++){
- u8 *pStart = a;
- int eType = *a++;
-
- switch( eType ){
- case 0:
- case SQLITE_NULL:
- assert( abPK[i]==0 );
- break;
-
- case SQLITE_FLOAT:
- case SQLITE_INTEGER:
- a += 8;
- break;
-
- default: {
- int n;
- a += sessionVarintGet(a, &n);
- a += n;
- break;
- }
- }
- if( abPK[i] ){
- sessionAppendBlob(pBuf, pStart, (int)(a-pStart), &rc);
- }
- }
- assert( (a - p->aRecord)==p->nRecord );
- }
-
- return rc;
-}
-
-/*
-** Formulate and prepare a SELECT statement to retrieve a row from table
-** zTab in database zDb based on its primary key. i.e.
-**
-** SELECT * FROM zDb.zTab WHERE pk1 = ? AND pk2 = ? AND ...
-*/
-static int sessionSelectStmt(
- sqlite3 *db, /* Database handle */
- const char *zDb, /* Database name */
- const char *zTab, /* Table name */
- int nCol, /* Number of columns in table */
- const char **azCol, /* Names of table columns */
- u8 *abPK, /* PRIMARY KEY array */
- sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
-){
- int rc = SQLITE_OK;
- char *zSql = 0;
- int nSql = -1;
-
- if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
- zSql = sqlite3_mprintf(
- "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND "
- "idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb
- );
+ && (n==0 || 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), n))
+ ){
+ break;
+ }
+ bChanged = 1;
+ }
+ }
+
+ /* If at least one field has been modified, this is not a no-op. */
+ if( bChanged ) bNoop = 0;
+
+ /* Add a field to the old.* record. This is omitted if this modules is
+ ** currently generating a patchset. */
+ if( bPatchset==0 ){
+ if( bChanged || abPK[i] ){
+ sessionAppendBlob(pBuf, pCsr, nAdvance, &rc);
+ }else{
+ sessionAppendByte(pBuf, 0, &rc);
+ }
+ }
+
+ /* Add a field to the new.* record. Or the only record if currently
+ ** generating a patchset. */
+ if( bChanged || (bPatchset && abPK[i]) ){
+ sessionAppendCol(&buf2, pStmt, i, &rc);
+ }else{
+ sessionAppendByte(&buf2, 0, &rc);
+ }
+
+ pCsr += nAdvance;
+ }
+
+ if( bNoop ){
+ pBuf->nBuf = nRewind;
+ }else{
+ sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, &rc);
+ }
+ sqlite3_free(buf2.aBuf);
+
+ return rc;
+}
+
+/*
+** Append a DELETE change to the buffer passed as the first argument. Use
+** the changeset format if argument bPatchset is zero, or the patchset
+** format otherwise.
+*/
+static int sessionAppendDelete(
+ SessionBuffer *pBuf, /* Buffer to append to */
+ int bPatchset, /* True for "patchset", 0 for "changeset" */
+ SessionChange *p, /* Object containing old values */
+ int nCol, /* Number of columns in table */
+ u8 *abPK /* Boolean array - true for PK columns */
+){
+ int rc = SQLITE_OK;
+
+ sessionAppendByte(pBuf, SQLITE_DELETE, &rc);
+ sessionAppendByte(pBuf, p->bIndirect, &rc);
+
+ if( bPatchset==0 ){
+ sessionAppendBlob(pBuf, p->aRecord, p->nRecord, &rc);
+ }else{
+ int i;
+ u8 *a = p->aRecord;
+ for(i=0; i<nCol; i++){
+ u8 *pStart = a;
+ int eType = *a++;
+
+ switch( eType ){
+ case 0:
+ case SQLITE_NULL:
+ assert( abPK[i]==0 );
+ break;
+
+ case SQLITE_FLOAT:
+ case SQLITE_INTEGER:
+ a += 8;
+ break;
+
+ default: {
+ int n;
+ a += sessionVarintGet(a, &n);
+ a += n;
+ break;
+ }
+ }
+ if( abPK[i] ){
+ sessionAppendBlob(pBuf, pStart, (int)(a-pStart), &rc);
+ }
+ }
+ assert( (a - p->aRecord)==p->nRecord );
+ }
+
+ return rc;
+}
+
+/*
+** Formulate and prepare a SELECT statement to retrieve a row from table
+** zTab in database zDb based on its primary key. i.e.
+**
+** SELECT * FROM zDb.zTab WHERE pk1 = ? AND pk2 = ? AND ...
+*/
+static int sessionSelectStmt(
+ sqlite3 *db, /* Database handle */
+ const char *zDb, /* Database name */
+ const char *zTab, /* Table name */
+ int nCol, /* Number of columns in table */
+ const char **azCol, /* Names of table columns */
+ u8 *abPK, /* PRIMARY KEY array */
+ sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
+){
+ int rc = SQLITE_OK;
+ char *zSql = 0;
+ int nSql = -1;
+
+ if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
+ zSql = sqlite3_mprintf(
+ "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND "
+ "idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb
+ );
if( zSql==0 ) rc = SQLITE_NOMEM;
- }else{
- int i;
- const char *zSep = "";
- SessionBuffer buf = {0, 0, 0};
-
- sessionAppendStr(&buf, "SELECT * FROM ", &rc);
- sessionAppendIdent(&buf, zDb, &rc);
- sessionAppendStr(&buf, ".", &rc);
- sessionAppendIdent(&buf, zTab, &rc);
- sessionAppendStr(&buf, " WHERE ", &rc);
- for(i=0; i<nCol; i++){
- if( abPK[i] ){
- sessionAppendStr(&buf, zSep, &rc);
- sessionAppendIdent(&buf, azCol[i], &rc);
- sessionAppendStr(&buf, " IS ?", &rc);
- sessionAppendInteger(&buf, i+1, &rc);
- zSep = " AND ";
- }
- }
- zSql = (char*)buf.aBuf;
- nSql = buf.nBuf;
- }
-
- if( rc==SQLITE_OK ){
- rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
- }
- sqlite3_free(zSql);
- return rc;
-}
-
-/*
-** Bind the PRIMARY KEY values from the change passed in argument pChange
-** to the SELECT statement passed as the first argument. The SELECT statement
-** is as prepared by function sessionSelectStmt().
-**
-** Return SQLITE_OK if all PK values are successfully bound, or an SQLite
-** error code (e.g. SQLITE_NOMEM) otherwise.
-*/
-static int sessionSelectBind(
- sqlite3_stmt *pSelect, /* SELECT from sessionSelectStmt() */
- int nCol, /* Number of columns in table */
- u8 *abPK, /* PRIMARY KEY array */
- SessionChange *pChange /* Change structure */
-){
- int i;
- int rc = SQLITE_OK;
- u8 *a = pChange->aRecord;
-
- for(i=0; i<nCol && rc==SQLITE_OK; i++){
- int eType = *a++;
-
- switch( eType ){
- case 0:
- case SQLITE_NULL:
- assert( abPK[i]==0 );
- break;
-
- case SQLITE_INTEGER: {
- if( abPK[i] ){
- i64 iVal = sessionGetI64(a);
- rc = sqlite3_bind_int64(pSelect, i+1, iVal);
- }
- a += 8;
- break;
- }
-
- case SQLITE_FLOAT: {
- if( abPK[i] ){
- double rVal;
- i64 iVal = sessionGetI64(a);
- memcpy(&rVal, &iVal, 8);
- rc = sqlite3_bind_double(pSelect, i+1, rVal);
- }
- a += 8;
- break;
- }
-
- case SQLITE_TEXT: {
- int n;
- a += sessionVarintGet(a, &n);
- if( abPK[i] ){
- rc = sqlite3_bind_text(pSelect, i+1, (char *)a, n, SQLITE_TRANSIENT);
- }
- a += n;
- break;
- }
-
- default: {
- int n;
- assert( eType==SQLITE_BLOB );
- a += sessionVarintGet(a, &n);
- if( abPK[i] ){
- rc = sqlite3_bind_blob(pSelect, i+1, a, n, SQLITE_TRANSIENT);
- }
- a += n;
- break;
- }
- }
- }
-
- return rc;
-}
-
-/*
-** This function is a no-op if *pRc is set to other than SQLITE_OK when it
+ }else{
+ int i;
+ const char *zSep = "";
+ SessionBuffer buf = {0, 0, 0};
+
+ sessionAppendStr(&buf, "SELECT * FROM ", &rc);
+ sessionAppendIdent(&buf, zDb, &rc);
+ sessionAppendStr(&buf, ".", &rc);
+ sessionAppendIdent(&buf, zTab, &rc);
+ sessionAppendStr(&buf, " WHERE ", &rc);
+ for(i=0; i<nCol; i++){
+ if( abPK[i] ){
+ sessionAppendStr(&buf, zSep, &rc);
+ sessionAppendIdent(&buf, azCol[i], &rc);
+ sessionAppendStr(&buf, " IS ?", &rc);
+ sessionAppendInteger(&buf, i+1, &rc);
+ zSep = " AND ";
+ }
+ }
+ zSql = (char*)buf.aBuf;
+ nSql = buf.nBuf;
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
+ }
+ sqlite3_free(zSql);
+ return rc;
+}
+
+/*
+** Bind the PRIMARY KEY values from the change passed in argument pChange
+** to the SELECT statement passed as the first argument. The SELECT statement
+** is as prepared by function sessionSelectStmt().
+**
+** Return SQLITE_OK if all PK values are successfully bound, or an SQLite
+** error code (e.g. SQLITE_NOMEM) otherwise.
+*/
+static int sessionSelectBind(
+ sqlite3_stmt *pSelect, /* SELECT from sessionSelectStmt() */
+ int nCol, /* Number of columns in table */
+ u8 *abPK, /* PRIMARY KEY array */
+ SessionChange *pChange /* Change structure */
+){
+ int i;
+ int rc = SQLITE_OK;
+ u8 *a = pChange->aRecord;
+
+ for(i=0; i<nCol && rc==SQLITE_OK; i++){
+ int eType = *a++;
+
+ switch( eType ){
+ case 0:
+ case SQLITE_NULL:
+ assert( abPK[i]==0 );
+ break;
+
+ case SQLITE_INTEGER: {
+ if( abPK[i] ){
+ i64 iVal = sessionGetI64(a);
+ rc = sqlite3_bind_int64(pSelect, i+1, iVal);
+ }
+ a += 8;
+ break;
+ }
+
+ case SQLITE_FLOAT: {
+ if( abPK[i] ){
+ double rVal;
+ i64 iVal = sessionGetI64(a);
+ memcpy(&rVal, &iVal, 8);
+ rc = sqlite3_bind_double(pSelect, i+1, rVal);
+ }
+ a += 8;
+ break;
+ }
+
+ case SQLITE_TEXT: {
+ int n;
+ a += sessionVarintGet(a, &n);
+ if( abPK[i] ){
+ rc = sqlite3_bind_text(pSelect, i+1, (char *)a, n, SQLITE_TRANSIENT);
+ }
+ a += n;
+ break;
+ }
+
+ default: {
+ int n;
+ assert( eType==SQLITE_BLOB );
+ a += sessionVarintGet(a, &n);
+ if( abPK[i] ){
+ rc = sqlite3_bind_blob(pSelect, i+1, a, n, SQLITE_TRANSIENT);
+ }
+ a += n;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*
+** This function is a no-op if *pRc is set to other than SQLITE_OK when it
** is called. Otherwise, append a serialized table header (part of the binary
-** changeset format) to buffer *pBuf. If an error occurs, set *pRc to an
-** SQLite error code before returning.
-*/
-static void sessionAppendTableHdr(
- SessionBuffer *pBuf, /* Append header to this buffer */
- int bPatchset, /* Use the patchset format if true */
- SessionTable *pTab, /* Table object to append header for */
- int *pRc /* IN/OUT: Error code */
-){
- /* Write a table header */
- sessionAppendByte(pBuf, (bPatchset ? 'P' : 'T'), pRc);
- sessionAppendVarint(pBuf, pTab->nCol, pRc);
- sessionAppendBlob(pBuf, pTab->abPK, pTab->nCol, pRc);
- sessionAppendBlob(pBuf, (u8 *)pTab->zName, (int)strlen(pTab->zName)+1, pRc);
-}
-
-/*
-** Generate either a changeset (if argument bPatchset is zero) or a patchset
-** (if it is non-zero) based on the current contents of the session object
-** passed as the first argument.
-**
-** If no error occurs, SQLITE_OK is returned and the new changeset/patchset
-** stored in output variables *pnChangeset and *ppChangeset. Or, if an error
+** changeset format) to buffer *pBuf. If an error occurs, set *pRc to an
+** SQLite error code before returning.
+*/
+static void sessionAppendTableHdr(
+ SessionBuffer *pBuf, /* Append header to this buffer */
+ int bPatchset, /* Use the patchset format if true */
+ SessionTable *pTab, /* Table object to append header for */
+ int *pRc /* IN/OUT: Error code */
+){
+ /* Write a table header */
+ sessionAppendByte(pBuf, (bPatchset ? 'P' : 'T'), pRc);
+ sessionAppendVarint(pBuf, pTab->nCol, pRc);
+ sessionAppendBlob(pBuf, pTab->abPK, pTab->nCol, pRc);
+ sessionAppendBlob(pBuf, (u8 *)pTab->zName, (int)strlen(pTab->zName)+1, pRc);
+}
+
+/*
+** Generate either a changeset (if argument bPatchset is zero) or a patchset
+** (if it is non-zero) based on the current contents of the session object
+** passed as the first argument.
+**
+** If no error occurs, SQLITE_OK is returned and the new changeset/patchset
+** stored in output variables *pnChangeset and *ppChangeset. Or, if an error
** occurs, an SQLite error code is returned and both output variables set
-** to 0.
-*/
-static int sessionGenerateChangeset(
- sqlite3_session *pSession, /* Session object */
- int bPatchset, /* True for patchset, false for changeset */
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut, /* First argument for xOutput */
- int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
- void **ppChangeset /* OUT: Buffer containing changeset */
-){
- sqlite3 *db = pSession->db; /* Source database handle */
- SessionTable *pTab; /* Used to iterate through attached tables */
- SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */
- int rc; /* Return code */
-
+** to 0.
+*/
+static int sessionGenerateChangeset(
+ sqlite3_session *pSession, /* Session object */
+ int bPatchset, /* True for patchset, false for changeset */
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut, /* First argument for xOutput */
+ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
+ void **ppChangeset /* OUT: Buffer containing changeset */
+){
+ sqlite3 *db = pSession->db; /* Source database handle */
+ SessionTable *pTab; /* Used to iterate through attached tables */
+ SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */
+ int rc; /* Return code */
+
assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0) );
assert( xOutput!=0 || (pnChangeset!=0 && ppChangeset!=0) );
-
- /* Zero the output variables in case an error occurs. If this session
- ** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
- ** this call will be a no-op. */
- if( xOutput==0 ){
+
+ /* Zero the output variables in case an error occurs. If this session
+ ** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
+ ** this call will be a no-op. */
+ if( xOutput==0 ){
assert( pnChangeset!=0 && ppChangeset!=0 );
- *pnChangeset = 0;
- *ppChangeset = 0;
- }
-
- if( pSession->rc ) return pSession->rc;
- rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0);
- if( rc!=SQLITE_OK ) return rc;
-
- sqlite3_mutex_enter(sqlite3_db_mutex(db));
-
- for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
- if( pTab->nEntry ){
- const char *zName = pTab->zName;
+ *pnChangeset = 0;
+ *ppChangeset = 0;
+ }
+
+ if( pSession->rc ) return pSession->rc;
+ rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0);
+ if( rc!=SQLITE_OK ) return rc;
+
+ sqlite3_mutex_enter(sqlite3_db_mutex(db));
+
+ for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
+ if( pTab->nEntry ){
+ const char *zName = pTab->zName;
int nCol = 0; /* Number of columns in table */
u8 *abPK = 0; /* Primary key array */
- const char **azCol = 0; /* Table columns */
- int i; /* Used to iterate through hash buckets */
- sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */
- int nRewind = buf.nBuf; /* Initial size of write buffer */
- int nNoop; /* Size of buffer after writing tbl header */
-
- /* Check the table schema is still Ok. */
+ const char **azCol = 0; /* Table columns */
+ int i; /* Used to iterate through hash buckets */
+ sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */
+ int nRewind = buf.nBuf; /* Initial size of write buffer */
+ int nNoop; /* Size of buffer after writing tbl header */
+
+ /* Check the table schema is still Ok. */
rc = sessionTableInfo(0, db, pSession->zDb, zName, &nCol, 0,&azCol,&abPK);
- if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){
- rc = SQLITE_SCHEMA;
- }
-
- /* Write a table header */
- sessionAppendTableHdr(&buf, bPatchset, pTab, &rc);
-
- /* Build and compile a statement to execute: */
- if( rc==SQLITE_OK ){
- rc = sessionSelectStmt(
- db, pSession->zDb, zName, nCol, azCol, abPK, &pSel);
- }
-
- nNoop = buf.nBuf;
- for(i=0; i<pTab->nChange && rc==SQLITE_OK; i++){
- SessionChange *p; /* Used to iterate through changes */
-
- for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){
- rc = sessionSelectBind(pSel, nCol, abPK, p);
- if( rc!=SQLITE_OK ) continue;
- if( sqlite3_step(pSel)==SQLITE_ROW ){
- if( p->op==SQLITE_INSERT ){
- int iCol;
- sessionAppendByte(&buf, SQLITE_INSERT, &rc);
- sessionAppendByte(&buf, p->bIndirect, &rc);
- for(iCol=0; iCol<nCol; iCol++){
- sessionAppendCol(&buf, pSel, iCol, &rc);
- }
- }else{
+ if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){
+ rc = SQLITE_SCHEMA;
+ }
+
+ /* Write a table header */
+ sessionAppendTableHdr(&buf, bPatchset, pTab, &rc);
+
+ /* Build and compile a statement to execute: */
+ if( rc==SQLITE_OK ){
+ rc = sessionSelectStmt(
+ db, pSession->zDb, zName, nCol, azCol, abPK, &pSel);
+ }
+
+ nNoop = buf.nBuf;
+ for(i=0; i<pTab->nChange && rc==SQLITE_OK; i++){
+ SessionChange *p; /* Used to iterate through changes */
+
+ for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){
+ rc = sessionSelectBind(pSel, nCol, abPK, p);
+ if( rc!=SQLITE_OK ) continue;
+ if( sqlite3_step(pSel)==SQLITE_ROW ){
+ if( p->op==SQLITE_INSERT ){
+ int iCol;
+ sessionAppendByte(&buf, SQLITE_INSERT, &rc);
+ sessionAppendByte(&buf, p->bIndirect, &rc);
+ for(iCol=0; iCol<nCol; iCol++){
+ sessionAppendCol(&buf, pSel, iCol, &rc);
+ }
+ }else{
assert( abPK!=0 ); /* Because sessionSelectStmt() returned ok */
- rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK);
- }
- }else if( p->op!=SQLITE_INSERT ){
- rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3_reset(pSel);
- }
-
+ rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK);
+ }
+ }else if( p->op!=SQLITE_INSERT ){
+ rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_reset(pSel);
+ }
+
/* If the buffer is now larger than sessions_strm_chunk_size, pass
- ** its contents to the xOutput() callback. */
+ ** its contents to the xOutput() callback. */
if( xOutput
&& rc==SQLITE_OK
&& buf.nBuf>nNoop
&& buf.nBuf>sessions_strm_chunk_size
- ){
- rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
- nNoop = -1;
- buf.nBuf = 0;
- }
-
- }
- }
-
- sqlite3_finalize(pSel);
- if( buf.nBuf==nNoop ){
- buf.nBuf = nRewind;
- }
- sqlite3_free((char*)azCol); /* cast works around VC++ bug */
- }
- }
-
- if( rc==SQLITE_OK ){
- if( xOutput==0 ){
- *pnChangeset = buf.nBuf;
- *ppChangeset = buf.aBuf;
- buf.aBuf = 0;
- }else if( buf.nBuf>0 ){
- rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
- }
- }
-
- sqlite3_free(buf.aBuf);
- sqlite3_exec(db, "RELEASE changeset", 0, 0, 0);
- sqlite3_mutex_leave(sqlite3_db_mutex(db));
- return rc;
-}
-
-/*
+ ){
+ rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
+ nNoop = -1;
+ buf.nBuf = 0;
+ }
+
+ }
+ }
+
+ sqlite3_finalize(pSel);
+ if( buf.nBuf==nNoop ){
+ buf.nBuf = nRewind;
+ }
+ sqlite3_free((char*)azCol); /* cast works around VC++ bug */
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ if( xOutput==0 ){
+ *pnChangeset = buf.nBuf;
+ *ppChangeset = buf.aBuf;
+ buf.aBuf = 0;
+ }else if( buf.nBuf>0 ){
+ rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
+ }
+ }
+
+ sqlite3_free(buf.aBuf);
+ sqlite3_exec(db, "RELEASE changeset", 0, 0, 0);
+ sqlite3_mutex_leave(sqlite3_db_mutex(db));
+ return rc;
+}
+
+/*
** Obtain a changeset object containing all changes recorded by the
-** session object passed as the first argument.
-**
+** session object passed as the first argument.
+**
** It is the responsibility of the caller to eventually free the buffer
-** using sqlite3_free().
-*/
-SQLITE_API int sqlite3session_changeset(
- sqlite3_session *pSession, /* Session object */
- int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
- void **ppChangeset /* OUT: Buffer containing changeset */
-){
+** using sqlite3_free().
+*/
+SQLITE_API int sqlite3session_changeset(
+ sqlite3_session *pSession, /* Session object */
+ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
+ void **ppChangeset /* OUT: Buffer containing changeset */
+){
int rc;
if( pnChangeset==0 || ppChangeset==0 ) return SQLITE_MISUSE;
@@ -211150,94 +211150,94 @@ SQLITE_API int sqlite3session_changeset(
|| pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize
);
return rc;
-}
-
-/*
-** Streaming version of sqlite3session_changeset().
-*/
-SQLITE_API int sqlite3session_changeset_strm(
- sqlite3_session *pSession,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-){
+}
+
+/*
+** Streaming version of sqlite3session_changeset().
+*/
+SQLITE_API int sqlite3session_changeset_strm(
+ sqlite3_session *pSession,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+){
if( xOutput==0 ) return SQLITE_MISUSE;
- return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0);
-}
-
-/*
-** Streaming version of sqlite3session_patchset().
-*/
-SQLITE_API int sqlite3session_patchset_strm(
- sqlite3_session *pSession,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-){
+ return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0);
+}
+
+/*
+** Streaming version of sqlite3session_patchset().
+*/
+SQLITE_API int sqlite3session_patchset_strm(
+ sqlite3_session *pSession,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+){
if( xOutput==0 ) return SQLITE_MISUSE;
- return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0);
-}
-
-/*
+ return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0);
+}
+
+/*
** Obtain a patchset object containing all changes recorded by the
-** session object passed as the first argument.
-**
+** session object passed as the first argument.
+**
** It is the responsibility of the caller to eventually free the buffer
-** using sqlite3_free().
-*/
-SQLITE_API int sqlite3session_patchset(
- sqlite3_session *pSession, /* Session object */
- int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
- void **ppPatchset /* OUT: Buffer containing changeset */
-){
+** using sqlite3_free().
+*/
+SQLITE_API int sqlite3session_patchset(
+ sqlite3_session *pSession, /* Session object */
+ int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
+ void **ppPatchset /* OUT: Buffer containing changeset */
+){
if( pnPatchset==0 || ppPatchset==0 ) return SQLITE_MISUSE;
- return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset);
-}
-
-/*
-** Enable or disable the session object passed as the first argument.
-*/
-SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable){
- int ret;
- sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
- if( bEnable>=0 ){
- pSession->bEnable = bEnable;
- }
- ret = pSession->bEnable;
- sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
- return ret;
-}
-
-/*
-** Enable or disable the session object passed as the first argument.
-*/
-SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect){
- int ret;
- sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
- if( bIndirect>=0 ){
- pSession->bIndirect = bIndirect;
- }
- ret = pSession->bIndirect;
- sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
- return ret;
-}
-
-/*
-** Return true if there have been no changes to monitored tables recorded
-** by the session object passed as the only argument.
-*/
-SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession){
- int ret = 0;
- SessionTable *pTab;
-
- sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
- for(pTab=pSession->pTable; pTab && ret==0; pTab=pTab->pNext){
- ret = (pTab->nEntry>0);
- }
- sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
-
- return (ret==0);
-}
-
-/*
+ return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset);
+}
+
+/*
+** Enable or disable the session object passed as the first argument.
+*/
+SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable){
+ int ret;
+ sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
+ if( bEnable>=0 ){
+ pSession->bEnable = bEnable;
+ }
+ ret = pSession->bEnable;
+ sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
+ return ret;
+}
+
+/*
+** Enable or disable the session object passed as the first argument.
+*/
+SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect){
+ int ret;
+ sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
+ if( bIndirect>=0 ){
+ pSession->bIndirect = bIndirect;
+ }
+ ret = pSession->bIndirect;
+ sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
+ return ret;
+}
+
+/*
+** Return true if there have been no changes to monitored tables recorded
+** by the session object passed as the only argument.
+*/
+SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession){
+ int ret = 0;
+ SessionTable *pTab;
+
+ sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
+ for(pTab=pSession->pTable; pTab && ret==0; pTab=pTab->pNext){
+ ret = (pTab->nEntry>0);
+ }
+ sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
+
+ return (ret==0);
+}
+
+/*
** Return the amount of heap memory in use.
*/
SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){
@@ -211278,53 +211278,53 @@ SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession
}
/*
-** Do the work for either sqlite3changeset_start() or start_strm().
-*/
-static int sessionChangesetStart(
- sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
- int (*xInput)(void *pIn, void *pData, int *pnData),
- void *pIn,
- int nChangeset, /* Size of buffer pChangeset in bytes */
+** Do the work for either sqlite3changeset_start() or start_strm().
+*/
+static int sessionChangesetStart(
+ sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn,
+ int nChangeset, /* Size of buffer pChangeset in bytes */
void *pChangeset, /* Pointer to buffer containing changeset */
int bInvert, /* True to invert changeset */
int bSkipEmpty /* True to skip empty UPDATE changes */
-){
- sqlite3_changeset_iter *pRet; /* Iterator to return */
- int nByte; /* Number of bytes to allocate for iterator */
-
- assert( xInput==0 || (pChangeset==0 && nChangeset==0) );
-
- /* Zero the output variable in case an error occurs. */
- *pp = 0;
-
- /* Allocate and initialize the iterator structure. */
- nByte = sizeof(sqlite3_changeset_iter);
- pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte);
- if( !pRet ) return SQLITE_NOMEM;
- memset(pRet, 0, sizeof(sqlite3_changeset_iter));
- pRet->in.aData = (u8 *)pChangeset;
- pRet->in.nData = nChangeset;
- pRet->in.xInput = xInput;
- pRet->in.pIn = pIn;
- pRet->in.bEof = (xInput ? 0 : 1);
+){
+ sqlite3_changeset_iter *pRet; /* Iterator to return */
+ int nByte; /* Number of bytes to allocate for iterator */
+
+ assert( xInput==0 || (pChangeset==0 && nChangeset==0) );
+
+ /* Zero the output variable in case an error occurs. */
+ *pp = 0;
+
+ /* Allocate and initialize the iterator structure. */
+ nByte = sizeof(sqlite3_changeset_iter);
+ pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte);
+ if( !pRet ) return SQLITE_NOMEM;
+ memset(pRet, 0, sizeof(sqlite3_changeset_iter));
+ pRet->in.aData = (u8 *)pChangeset;
+ pRet->in.nData = nChangeset;
+ pRet->in.xInput = xInput;
+ pRet->in.pIn = pIn;
+ pRet->in.bEof = (xInput ? 0 : 1);
pRet->bInvert = bInvert;
pRet->bSkipEmpty = bSkipEmpty;
-
- /* Populate the output variable and return success. */
- *pp = pRet;
- return SQLITE_OK;
-}
-
-/*
-** Create an iterator used to iterate through the contents of a changeset.
-*/
-SQLITE_API int sqlite3changeset_start(
- sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
- int nChangeset, /* Size of buffer pChangeset in bytes */
- void *pChangeset /* Pointer to buffer containing changeset */
-){
+
+ /* Populate the output variable and return success. */
+ *pp = pRet;
+ return SQLITE_OK;
+}
+
+/*
+** Create an iterator used to iterate through the contents of a changeset.
+*/
+SQLITE_API int sqlite3changeset_start(
+ sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
+ int nChangeset, /* Size of buffer pChangeset in bytes */
+ void *pChangeset /* Pointer to buffer containing changeset */
+){
return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0, 0);
-}
+}
SQLITE_API int sqlite3changeset_start_v2(
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
int nChangeset, /* Size of buffer pChangeset in bytes */
@@ -211334,17 +211334,17 @@ SQLITE_API int sqlite3changeset_start_v2(
int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert, 0);
}
-
-/*
-** Streaming version of sqlite3changeset_start().
-*/
-SQLITE_API int sqlite3changeset_start_strm(
- sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
- int (*xInput)(void *pIn, void *pData, int *pnData),
- void *pIn
-){
+
+/*
+** Streaming version of sqlite3changeset_start().
+*/
+SQLITE_API int sqlite3changeset_start_strm(
+ sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn
+){
return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0, 0);
-}
+}
SQLITE_API int sqlite3changeset_start_v2_strm(
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
int (*xInput)(void *pIn, void *pData, int *pnData),
@@ -211354,143 +211354,143 @@ SQLITE_API int sqlite3changeset_start_v2_strm(
int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert, 0);
}
-
-/*
-** If the SessionInput object passed as the only argument is a streaming
-** object and the buffer is full, discard some data to free up space.
-*/
-static void sessionDiscardData(SessionInput *pIn){
+
+/*
+** If the SessionInput object passed as the only argument is a streaming
+** object and the buffer is full, discard some data to free up space.
+*/
+static void sessionDiscardData(SessionInput *pIn){
if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){
- int nMove = pIn->buf.nBuf - pIn->iNext;
- assert( nMove>=0 );
- if( nMove>0 ){
- memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove);
- }
- pIn->buf.nBuf -= pIn->iNext;
- pIn->iNext = 0;
- pIn->nData = pIn->buf.nBuf;
- }
-}
-
-/*
-** Ensure that there are at least nByte bytes available in the buffer. Or,
-** if there are not nByte bytes remaining in the input, that all available
-** data is in the buffer.
-**
-** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
-*/
-static int sessionInputBuffer(SessionInput *pIn, int nByte){
- int rc = SQLITE_OK;
- if( pIn->xInput ){
- while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
+ int nMove = pIn->buf.nBuf - pIn->iNext;
+ assert( nMove>=0 );
+ if( nMove>0 ){
+ memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove);
+ }
+ pIn->buf.nBuf -= pIn->iNext;
+ pIn->iNext = 0;
+ pIn->nData = pIn->buf.nBuf;
+ }
+}
+
+/*
+** Ensure that there are at least nByte bytes available in the buffer. Or,
+** if there are not nByte bytes remaining in the input, that all available
+** data is in the buffer.
+**
+** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
+*/
+static int sessionInputBuffer(SessionInput *pIn, int nByte){
+ int rc = SQLITE_OK;
+ if( pIn->xInput ){
+ while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
int nNew = sessions_strm_chunk_size;
-
- if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
- if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
- rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew);
- if( nNew==0 ){
- pIn->bEof = 1;
- }else{
- pIn->buf.nBuf += nNew;
- }
- }
-
- pIn->aData = pIn->buf.aBuf;
- pIn->nData = pIn->buf.nBuf;
- }
- }
- return rc;
-}
-
-/*
-** When this function is called, *ppRec points to the start of a record
-** that contains nCol values. This function advances the pointer *ppRec
-** until it points to the byte immediately following that record.
-*/
-static void sessionSkipRecord(
- u8 **ppRec, /* IN/OUT: Record pointer */
- int nCol /* Number of values in record */
-){
- u8 *aRec = *ppRec;
- int i;
- for(i=0; i<nCol; i++){
- int eType = *aRec++;
- if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
- int nByte;
- aRec += sessionVarintGet((u8*)aRec, &nByte);
- aRec += nByte;
- }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
- aRec += 8;
- }
- }
-
- *ppRec = aRec;
-}
-
-/*
-** This function sets the value of the sqlite3_value object passed as the
+
+ if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
+ if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
+ rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew);
+ if( nNew==0 ){
+ pIn->bEof = 1;
+ }else{
+ pIn->buf.nBuf += nNew;
+ }
+ }
+
+ pIn->aData = pIn->buf.aBuf;
+ pIn->nData = pIn->buf.nBuf;
+ }
+ }
+ return rc;
+}
+
+/*
+** When this function is called, *ppRec points to the start of a record
+** that contains nCol values. This function advances the pointer *ppRec
+** until it points to the byte immediately following that record.
+*/
+static void sessionSkipRecord(
+ u8 **ppRec, /* IN/OUT: Record pointer */
+ int nCol /* Number of values in record */
+){
+ u8 *aRec = *ppRec;
+ int i;
+ for(i=0; i<nCol; i++){
+ int eType = *aRec++;
+ if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
+ int nByte;
+ aRec += sessionVarintGet((u8*)aRec, &nByte);
+ aRec += nByte;
+ }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+ aRec += 8;
+ }
+ }
+
+ *ppRec = aRec;
+}
+
+/*
+** This function sets the value of the sqlite3_value object passed as the
** first argument to a copy of the string or blob held in the aData[]
-** buffer. SQLITE_OK is returned if successful, or SQLITE_NOMEM if an OOM
-** error occurs.
-*/
-static int sessionValueSetStr(
- sqlite3_value *pVal, /* Set the value of this object */
- u8 *aData, /* Buffer containing string or blob data */
- int nData, /* Size of buffer aData[] in bytes */
- u8 enc /* String encoding (0 for blobs) */
-){
- /* In theory this code could just pass SQLITE_TRANSIENT as the final
+** buffer. SQLITE_OK is returned if successful, or SQLITE_NOMEM if an OOM
+** error occurs.
+*/
+static int sessionValueSetStr(
+ sqlite3_value *pVal, /* Set the value of this object */
+ u8 *aData, /* Buffer containing string or blob data */
+ int nData, /* Size of buffer aData[] in bytes */
+ u8 enc /* String encoding (0 for blobs) */
+){
+ /* In theory this code could just pass SQLITE_TRANSIENT as the final
** argument to sqlite3ValueSetStr() and have the copy created
- ** automatically. But doing so makes it difficult to detect any OOM
- ** error. Hence the code to create the copy externally. */
+ ** automatically. But doing so makes it difficult to detect any OOM
+ ** error. Hence the code to create the copy externally. */
u8 *aCopy = sqlite3_malloc64((sqlite3_int64)nData+1);
- if( aCopy==0 ) return SQLITE_NOMEM;
- memcpy(aCopy, aData, nData);
- sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free);
- return SQLITE_OK;
-}
-
-/*
-** Deserialize a single record from a buffer in memory. See "RECORD FORMAT"
-** for details.
-**
-** When this function is called, *paChange points to the start of the record
-** to deserialize. Assuming no error occurs, *paChange is set to point to
-** one byte after the end of the same record before this function returns.
-** If the argument abPK is NULL, then the record contains nCol values. Or,
-** if abPK is other than NULL, then the record contains only the PK fields
-** (in other words, it is a patchset DELETE record).
-**
-** If successful, each element of the apOut[] array (allocated by the caller)
-** is set to point to an sqlite3_value object containing the value read
-** from the corresponding position in the record. If that value is not
-** included in the record (i.e. because the record is part of an UPDATE change
-** and the field was not modified), the corresponding element of apOut[] is
-** set to NULL.
-**
-** It is the responsibility of the caller to free all sqlite_value structures
-** using sqlite3_free().
-**
-** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
-** The apOut[] array may have been partially populated in this case.
-*/
-static int sessionReadRecord(
- SessionInput *pIn, /* Input data */
- int nCol, /* Number of values in record */
- u8 *abPK, /* Array of primary key flags, or NULL */
+ if( aCopy==0 ) return SQLITE_NOMEM;
+ memcpy(aCopy, aData, nData);
+ sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free);
+ return SQLITE_OK;
+}
+
+/*
+** Deserialize a single record from a buffer in memory. See "RECORD FORMAT"
+** for details.
+**
+** When this function is called, *paChange points to the start of the record
+** to deserialize. Assuming no error occurs, *paChange is set to point to
+** one byte after the end of the same record before this function returns.
+** If the argument abPK is NULL, then the record contains nCol values. Or,
+** if abPK is other than NULL, then the record contains only the PK fields
+** (in other words, it is a patchset DELETE record).
+**
+** If successful, each element of the apOut[] array (allocated by the caller)
+** is set to point to an sqlite3_value object containing the value read
+** from the corresponding position in the record. If that value is not
+** included in the record (i.e. because the record is part of an UPDATE change
+** and the field was not modified), the corresponding element of apOut[] is
+** set to NULL.
+**
+** It is the responsibility of the caller to free all sqlite_value structures
+** using sqlite3_free().
+**
+** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
+** The apOut[] array may have been partially populated in this case.
+*/
+static int sessionReadRecord(
+ SessionInput *pIn, /* Input data */
+ int nCol, /* Number of values in record */
+ u8 *abPK, /* Array of primary key flags, or NULL */
sqlite3_value **apOut, /* Write values to this array */
int *pbEmpty
-){
- int i; /* Used to iterate through columns */
- int rc = SQLITE_OK;
-
+){
+ int i; /* Used to iterate through columns */
+ int rc = SQLITE_OK;
+
assert( pbEmpty==0 || *pbEmpty==0 );
if( pbEmpty ) *pbEmpty = 1;
- for(i=0; i<nCol && rc==SQLITE_OK; i++){
- int eType = 0; /* Type of value (SQLITE_NULL, TEXT etc.) */
- if( abPK && abPK[i]==0 ) continue;
- rc = sessionInputBuffer(pIn, 9);
- if( rc==SQLITE_OK ){
+ for(i=0; i<nCol && rc==SQLITE_OK; i++){
+ int eType = 0; /* Type of value (SQLITE_NULL, TEXT etc.) */
+ if( abPK && abPK[i]==0 ) continue;
+ rc = sessionInputBuffer(pIn, 9);
+ if( rc==SQLITE_OK ){
if( pIn->iNext>=pIn->nData ){
rc = SQLITE_CORRUPT_BKPT;
}else{
@@ -211502,15 +211502,15 @@ static int sessionReadRecord(
if( !apOut[i] ) rc = SQLITE_NOMEM;
}
}
- }
-
- if( rc==SQLITE_OK ){
- u8 *aVal = &pIn->aData[pIn->iNext];
- if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
- int nByte;
- pIn->iNext += sessionVarintGet(aVal, &nByte);
- rc = sessionInputBuffer(pIn, nByte);
- if( rc==SQLITE_OK ){
+ }
+
+ if( rc==SQLITE_OK ){
+ u8 *aVal = &pIn->aData[pIn->iNext];
+ if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
+ int nByte;
+ pIn->iNext += sessionVarintGet(aVal, &nByte);
+ rc = sessionInputBuffer(pIn, nByte);
+ if( rc==SQLITE_OK ){
if( nByte<0 || nByte>pIn->nData-pIn->iNext ){
rc = SQLITE_CORRUPT_BKPT;
}else{
@@ -211518,46 +211518,46 @@ static int sessionReadRecord(
rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
pIn->iNext += nByte;
}
- }
- }
- if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
- sqlite3_int64 v = sessionGetI64(aVal);
- if( eType==SQLITE_INTEGER ){
- sqlite3VdbeMemSetInt64(apOut[i], v);
- }else{
- double d;
- memcpy(&d, &v, 8);
- sqlite3VdbeMemSetDouble(apOut[i], d);
- }
- pIn->iNext += 8;
- }
- }
- }
-
- return rc;
-}
-
-/*
-** The input pointer currently points to the second byte of a table-header.
-** Specifically, to the following:
-**
-** + number of columns in table (varint)
-** + array of PK flags (1 byte per column),
-** + table name (nul terminated).
-**
+ }
+ }
+ if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+ sqlite3_int64 v = sessionGetI64(aVal);
+ if( eType==SQLITE_INTEGER ){
+ sqlite3VdbeMemSetInt64(apOut[i], v);
+ }else{
+ double d;
+ memcpy(&d, &v, 8);
+ sqlite3VdbeMemSetDouble(apOut[i], d);
+ }
+ pIn->iNext += 8;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*
+** The input pointer currently points to the second byte of a table-header.
+** Specifically, to the following:
+**
+** + number of columns in table (varint)
+** + array of PK flags (1 byte per column),
+** + table name (nul terminated).
+**
** This function ensures that all of the above is present in the input
-** buffer (i.e. that it can be accessed without any calls to xInput()).
-** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
-** The input pointer is not moved.
-*/
-static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){
- int rc = SQLITE_OK;
- int nCol = 0;
- int nRead = 0;
-
- rc = sessionInputBuffer(pIn, 9);
- if( rc==SQLITE_OK ){
- nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol);
+** buffer (i.e. that it can be accessed without any calls to xInput()).
+** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
+** The input pointer is not moved.
+*/
+static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){
+ int rc = SQLITE_OK;
+ int nCol = 0;
+ int nRead = 0;
+
+ rc = sessionInputBuffer(pIn, 9);
+ if( rc==SQLITE_OK ){
+ nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol);
/* The hard upper limit for the number of columns in an SQLite
** database table is, according to sqliteLimit.h, 32676. So
** consider any table-header that purports to have more than 65536
@@ -211571,82 +211571,82 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){
rc = sessionInputBuffer(pIn, nRead+nCol+100);
nRead += nCol;
}
- }
-
- while( rc==SQLITE_OK ){
- while( (pIn->iNext + nRead)<pIn->nData && pIn->aData[pIn->iNext + nRead] ){
- nRead++;
- }
- if( (pIn->iNext + nRead)<pIn->nData ) break;
- rc = sessionInputBuffer(pIn, nRead + 100);
- }
- *pnByte = nRead+1;
- return rc;
-}
-
-/*
-** The input pointer currently points to the first byte of the first field
-** of a record consisting of nCol columns. This function ensures the entire
-** record is buffered. It does not move the input pointer.
-**
-** If successful, SQLITE_OK is returned and *pnByte is set to the size of
-** the record in bytes. Otherwise, an SQLite error code is returned. The
-** final value of *pnByte is undefined in this case.
-*/
-static int sessionChangesetBufferRecord(
- SessionInput *pIn, /* Input data */
- int nCol, /* Number of columns in record */
- int *pnByte /* OUT: Size of record in bytes */
-){
- int rc = SQLITE_OK;
- int nByte = 0;
- int i;
- for(i=0; rc==SQLITE_OK && i<nCol; i++){
- int eType;
- rc = sessionInputBuffer(pIn, nByte + 10);
- if( rc==SQLITE_OK ){
- eType = pIn->aData[pIn->iNext + nByte++];
- if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
- int n;
- nByte += sessionVarintGet(&pIn->aData[pIn->iNext+nByte], &n);
- nByte += n;
- rc = sessionInputBuffer(pIn, nByte);
- }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
- nByte += 8;
- }
- }
- }
- *pnByte = nByte;
- return rc;
-}
-
-/*
-** The input pointer currently points to the second byte of a table-header.
-** Specifically, to the following:
-**
-** + number of columns in table (varint)
-** + array of PK flags (1 byte per column),
-** + table name (nul terminated).
-**
+ }
+
+ while( rc==SQLITE_OK ){
+ while( (pIn->iNext + nRead)<pIn->nData && pIn->aData[pIn->iNext + nRead] ){
+ nRead++;
+ }
+ if( (pIn->iNext + nRead)<pIn->nData ) break;
+ rc = sessionInputBuffer(pIn, nRead + 100);
+ }
+ *pnByte = nRead+1;
+ return rc;
+}
+
+/*
+** The input pointer currently points to the first byte of the first field
+** of a record consisting of nCol columns. This function ensures the entire
+** record is buffered. It does not move the input pointer.
+**
+** If successful, SQLITE_OK is returned and *pnByte is set to the size of
+** the record in bytes. Otherwise, an SQLite error code is returned. The
+** final value of *pnByte is undefined in this case.
+*/
+static int sessionChangesetBufferRecord(
+ SessionInput *pIn, /* Input data */
+ int nCol, /* Number of columns in record */
+ int *pnByte /* OUT: Size of record in bytes */
+){
+ int rc = SQLITE_OK;
+ int nByte = 0;
+ int i;
+ for(i=0; rc==SQLITE_OK && i<nCol; i++){
+ int eType;
+ rc = sessionInputBuffer(pIn, nByte + 10);
+ if( rc==SQLITE_OK ){
+ eType = pIn->aData[pIn->iNext + nByte++];
+ if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
+ int n;
+ nByte += sessionVarintGet(&pIn->aData[pIn->iNext+nByte], &n);
+ nByte += n;
+ rc = sessionInputBuffer(pIn, nByte);
+ }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+ nByte += 8;
+ }
+ }
+ }
+ *pnByte = nByte;
+ return rc;
+}
+
+/*
+** The input pointer currently points to the second byte of a table-header.
+** Specifically, to the following:
+**
+** + number of columns in table (varint)
+** + array of PK flags (1 byte per column),
+** + table name (nul terminated).
+**
** This function decodes the table-header and populates the p->nCol,
** p->zTab and p->abPK[] variables accordingly. The p->apValue[] array is
-** also allocated or resized according to the new value of p->nCol. The
-** input pointer is left pointing to the byte following the table header.
-**
-** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code
-** is returned and the final values of the various fields enumerated above
-** are undefined.
-*/
-static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
- int rc;
- int nCopy;
- assert( p->rc==SQLITE_OK );
-
- rc = sessionChangesetBufferTblhdr(&p->in, &nCopy);
- if( rc==SQLITE_OK ){
- int nByte;
- int nVarint;
- nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol);
+** also allocated or resized according to the new value of p->nCol. The
+** input pointer is left pointing to the byte following the table header.
+**
+** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code
+** is returned and the final values of the various fields enumerated above
+** are undefined.
+*/
+static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
+ int rc;
+ int nCopy;
+ assert( p->rc==SQLITE_OK );
+
+ rc = sessionChangesetBufferTblhdr(&p->in, &nCopy);
+ if( rc==SQLITE_OK ){
+ int nByte;
+ int nVarint;
+ nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol);
if( p->nCol>0 ){
nCopy -= nVarint;
p->in.iNext += nVarint;
@@ -211656,16 +211656,16 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
}else{
rc = SQLITE_CORRUPT_BKPT;
}
- }
-
- if( rc==SQLITE_OK ){
+ }
+
+ if( rc==SQLITE_OK ){
size_t iPK = sizeof(sqlite3_value*)*p->nCol*2;
- memset(p->tblhdr.aBuf, 0, iPK);
- memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy);
- p->in.iNext += nCopy;
- }
-
- p->apValue = (sqlite3_value**)p->tblhdr.aBuf;
+ memset(p->tblhdr.aBuf, 0, iPK);
+ memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy);
+ p->in.iNext += nCopy;
+ }
+
+ p->apValue = (sqlite3_value**)p->tblhdr.aBuf;
if( p->apValue==0 ){
p->abPK = 0;
p->zTab = 0;
@@ -211673,69 +211673,69 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
p->abPK = (u8*)&p->apValue[p->nCol*2];
p->zTab = p->abPK ? (char*)&p->abPK[p->nCol] : 0;
}
- return (p->rc = rc);
-}
-
-/*
+ return (p->rc = rc);
+}
+
+/*
** Advance the changeset iterator to the next change. The differences between
** this function and sessionChangesetNext() are that
-**
+**
** * If pbEmpty is not NULL and the change is a no-op UPDATE (an UPDATE
** that modifies no columns), this function sets (*pbEmpty) to 1.
-**
+**
** * If the iterator is configured to skip no-op UPDATEs,
** sessionChangesetNext() does that. This function does not.
-*/
+*/
static int sessionChangesetNextOne(
- sqlite3_changeset_iter *p, /* Changeset iterator */
- u8 **paRec, /* If non-NULL, store record pointer here */
+ sqlite3_changeset_iter *p, /* Changeset iterator */
+ u8 **paRec, /* If non-NULL, store record pointer here */
int *pnRec, /* If non-NULL, store size of record here */
int *pbNew, /* If non-NULL, true if new table */
int *pbEmpty
-){
- int i;
- u8 op;
-
- assert( (paRec==0 && pnRec==0) || (paRec && pnRec) );
+){
+ int i;
+ u8 op;
+
+ assert( (paRec==0 && pnRec==0) || (paRec && pnRec) );
assert( pbEmpty==0 || *pbEmpty==0 );
-
- /* If the iterator is in the error-state, return immediately. */
- if( p->rc!=SQLITE_OK ) return p->rc;
-
- /* Free the current contents of p->apValue[], if any. */
- if( p->apValue ){
- for(i=0; i<p->nCol*2; i++){
- sqlite3ValueFree(p->apValue[i]);
- }
- memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2);
- }
-
- /* Make sure the buffer contains at least 10 bytes of input data, or all
- ** remaining data if there are less than 10 bytes available. This is
- ** sufficient either for the 'T' or 'P' byte and the varint that follows
- ** it, or for the two single byte values otherwise. */
- p->rc = sessionInputBuffer(&p->in, 2);
- if( p->rc!=SQLITE_OK ) return p->rc;
-
- /* If the iterator is already at the end of the changeset, return DONE. */
- if( p->in.iNext>=p->in.nData ){
- return SQLITE_DONE;
- }
-
- sessionDiscardData(&p->in);
- p->in.iCurrent = p->in.iNext;
-
- op = p->in.aData[p->in.iNext++];
- while( op=='T' || op=='P' ){
+
+ /* If the iterator is in the error-state, return immediately. */
+ if( p->rc!=SQLITE_OK ) return p->rc;
+
+ /* Free the current contents of p->apValue[], if any. */
+ if( p->apValue ){
+ for(i=0; i<p->nCol*2; i++){
+ sqlite3ValueFree(p->apValue[i]);
+ }
+ memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2);
+ }
+
+ /* Make sure the buffer contains at least 10 bytes of input data, or all
+ ** remaining data if there are less than 10 bytes available. This is
+ ** sufficient either for the 'T' or 'P' byte and the varint that follows
+ ** it, or for the two single byte values otherwise. */
+ p->rc = sessionInputBuffer(&p->in, 2);
+ if( p->rc!=SQLITE_OK ) return p->rc;
+
+ /* If the iterator is already at the end of the changeset, return DONE. */
+ if( p->in.iNext>=p->in.nData ){
+ return SQLITE_DONE;
+ }
+
+ sessionDiscardData(&p->in);
+ p->in.iCurrent = p->in.iNext;
+
+ op = p->in.aData[p->in.iNext++];
+ while( op=='T' || op=='P' ){
if( pbNew ) *pbNew = 1;
- p->bPatchset = (op=='P');
- if( sessionChangesetReadTblhdr(p) ) return p->rc;
- if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc;
- p->in.iCurrent = p->in.iNext;
- if( p->in.iNext>=p->in.nData ) return SQLITE_DONE;
- op = p->in.aData[p->in.iNext++];
- }
-
+ p->bPatchset = (op=='P');
+ if( sessionChangesetReadTblhdr(p) ) return p->rc;
+ if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc;
+ p->in.iCurrent = p->in.iNext;
+ if( p->in.iNext>=p->in.nData ) return SQLITE_DONE;
+ op = p->in.aData[p->in.iNext++];
+ }
+
if( p->zTab==0 || (p->bPatchset && p->bInvert) ){
/* The first record in the changeset is not a table header. Must be a
** corrupt changeset. */
@@ -211743,67 +211743,67 @@ static int sessionChangesetNextOne(
return (p->rc = SQLITE_CORRUPT_BKPT);
}
- p->op = op;
- p->bIndirect = p->in.aData[p->in.iNext++];
- if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){
- return (p->rc = SQLITE_CORRUPT_BKPT);
- }
-
+ p->op = op;
+ p->bIndirect = p->in.aData[p->in.iNext++];
+ if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){
+ return (p->rc = SQLITE_CORRUPT_BKPT);
+ }
+
if( paRec ){
- int nVal; /* Number of values to buffer */
- if( p->bPatchset==0 && op==SQLITE_UPDATE ){
- nVal = p->nCol * 2;
- }else if( p->bPatchset && op==SQLITE_DELETE ){
- nVal = 0;
- for(i=0; i<p->nCol; i++) if( p->abPK[i] ) nVal++;
- }else{
- nVal = p->nCol;
- }
- p->rc = sessionChangesetBufferRecord(&p->in, nVal, pnRec);
- if( p->rc!=SQLITE_OK ) return p->rc;
- *paRec = &p->in.aData[p->in.iNext];
- p->in.iNext += *pnRec;
- }else{
+ int nVal; /* Number of values to buffer */
+ if( p->bPatchset==0 && op==SQLITE_UPDATE ){
+ nVal = p->nCol * 2;
+ }else if( p->bPatchset && op==SQLITE_DELETE ){
+ nVal = 0;
+ for(i=0; i<p->nCol; i++) if( p->abPK[i] ) nVal++;
+ }else{
+ nVal = p->nCol;
+ }
+ p->rc = sessionChangesetBufferRecord(&p->in, nVal, pnRec);
+ if( p->rc!=SQLITE_OK ) return p->rc;
+ *paRec = &p->in.aData[p->in.iNext];
+ p->in.iNext += *pnRec;
+ }else{
sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);
-
- /* If this is an UPDATE or DELETE, read the old.* record. */
- if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
- u8 *abPK = p->bPatchset ? p->abPK : 0;
+
+ /* If this is an UPDATE or DELETE, read the old.* record. */
+ if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
+ u8 *abPK = p->bPatchset ? p->abPK : 0;
p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld, 0);
- if( p->rc!=SQLITE_OK ) return p->rc;
- }
-
- /* If this is an INSERT or UPDATE, read the new.* record. */
- if( p->op!=SQLITE_DELETE ){
+ if( p->rc!=SQLITE_OK ) return p->rc;
+ }
+
+ /* If this is an INSERT or UPDATE, read the new.* record. */
+ if( p->op!=SQLITE_DELETE ){
p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew, pbEmpty);
- if( p->rc!=SQLITE_OK ) return p->rc;
- }
-
+ if( p->rc!=SQLITE_OK ) return p->rc;
+ }
+
if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
- /* If this is an UPDATE that is part of a patchset, then all PK and
- ** modified fields are present in the new.* record. The old.* record
- ** is currently completely empty. This block shifts the PK fields from
- ** new.* to old.*, to accommodate the code that reads these arrays. */
- for(i=0; i<p->nCol; i++){
+ /* If this is an UPDATE that is part of a patchset, then all PK and
+ ** modified fields are present in the new.* record. The old.* record
+ ** is currently completely empty. This block shifts the PK fields from
+ ** new.* to old.*, to accommodate the code that reads these arrays. */
+ for(i=0; i<p->nCol; i++){
assert( p->bPatchset==0 || p->apValue[i]==0 );
- if( p->abPK[i] ){
+ if( p->abPK[i] ){
assert( p->apValue[i]==0 );
- p->apValue[i] = p->apValue[i+p->nCol];
+ p->apValue[i] = p->apValue[i+p->nCol];
if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
- p->apValue[i+p->nCol] = 0;
- }
- }
+ p->apValue[i+p->nCol] = 0;
+ }
+ }
}else if( p->bInvert ){
if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
- }
- }
-
- return SQLITE_ROW;
-}
-
-/*
+ }
+ }
+
+ return SQLITE_ROW;
+}
+
+/*
** Advance the changeset iterator to the next change.
**
** If both paRec and pnRec are NULL, then this function works like the public
@@ -211835,380 +211835,380 @@ static int sessionChangesetNext(
}
/*
-** Advance an iterator created by sqlite3changeset_start() to the next
-** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE
-** or SQLITE_CORRUPT.
-**
-** This function may not be called on iterators passed to a conflict handler
-** callback by changeset_apply().
-*/
-SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *p){
+** Advance an iterator created by sqlite3changeset_start() to the next
+** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE
+** or SQLITE_CORRUPT.
+**
+** This function may not be called on iterators passed to a conflict handler
+** callback by changeset_apply().
+*/
+SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *p){
return sessionChangesetNext(p, 0, 0, 0);
-}
-
-/*
-** The following function extracts information on the current change
-** from a changeset iterator. It may only be called after changeset_next()
-** has returned SQLITE_ROW.
-*/
-SQLITE_API int sqlite3changeset_op(
- sqlite3_changeset_iter *pIter, /* Iterator handle */
- const char **pzTab, /* OUT: Pointer to table name */
- int *pnCol, /* OUT: Number of columns in table */
- int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */
- int *pbIndirect /* OUT: True if change is indirect */
-){
- *pOp = pIter->op;
- *pnCol = pIter->nCol;
- *pzTab = pIter->zTab;
- if( pbIndirect ) *pbIndirect = pIter->bIndirect;
- return SQLITE_OK;
-}
-
-/*
-** Return information regarding the PRIMARY KEY and number of columns in
-** the database table affected by the change that pIter currently points
-** to. This function may only be called after changeset_next() returns
-** SQLITE_ROW.
-*/
-SQLITE_API int sqlite3changeset_pk(
- sqlite3_changeset_iter *pIter, /* Iterator object */
- unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
- int *pnCol /* OUT: Number of entries in output array */
-){
- *pabPK = pIter->abPK;
- if( pnCol ) *pnCol = pIter->nCol;
- return SQLITE_OK;
-}
-
-/*
-** This function may only be called while the iterator is pointing to an
-** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()).
-** Otherwise, SQLITE_MISUSE is returned.
-**
-** It sets *ppValue to point to an sqlite3_value structure containing the
-** iVal'th value in the old.* record. Or, if that particular value is not
-** included in the record (because the change is an UPDATE and the field
-** was not modified and is not a PK column), set *ppValue to NULL.
-**
-** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
-** not modified. Otherwise, SQLITE_OK.
-*/
-SQLITE_API int sqlite3changeset_old(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int iVal, /* Index of old.* value to retrieve */
- sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
-){
- if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_DELETE ){
- return SQLITE_MISUSE;
- }
- if( iVal<0 || iVal>=pIter->nCol ){
- return SQLITE_RANGE;
- }
- *ppValue = pIter->apValue[iVal];
- return SQLITE_OK;
-}
-
-/*
-** This function may only be called while the iterator is pointing to an
-** SQLITE_UPDATE or SQLITE_INSERT change (see sqlite3changeset_op()).
-** Otherwise, SQLITE_MISUSE is returned.
-**
-** It sets *ppValue to point to an sqlite3_value structure containing the
-** iVal'th value in the new.* record. Or, if that particular value is not
-** included in the record (because the change is an UPDATE and the field
-** was not modified), set *ppValue to NULL.
-**
-** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
-** not modified. Otherwise, SQLITE_OK.
-*/
-SQLITE_API int sqlite3changeset_new(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int iVal, /* Index of new.* value to retrieve */
- sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
-){
- if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_INSERT ){
- return SQLITE_MISUSE;
- }
- if( iVal<0 || iVal>=pIter->nCol ){
- return SQLITE_RANGE;
- }
- *ppValue = pIter->apValue[pIter->nCol+iVal];
- return SQLITE_OK;
-}
-
-/*
-** The following two macros are used internally. They are similar to the
-** sqlite3changeset_new() and sqlite3changeset_old() functions, except that
-** they omit all error checking and return a pointer to the requested value.
-*/
-#define sessionChangesetNew(pIter, iVal) (pIter)->apValue[(pIter)->nCol+(iVal)]
-#define sessionChangesetOld(pIter, iVal) (pIter)->apValue[(iVal)]
-
-/*
-** This function may only be called with a changeset iterator that has been
+}
+
+/*
+** The following function extracts information on the current change
+** from a changeset iterator. It may only be called after changeset_next()
+** has returned SQLITE_ROW.
+*/
+SQLITE_API int sqlite3changeset_op(
+ sqlite3_changeset_iter *pIter, /* Iterator handle */
+ const char **pzTab, /* OUT: Pointer to table name */
+ int *pnCol, /* OUT: Number of columns in table */
+ int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */
+ int *pbIndirect /* OUT: True if change is indirect */
+){
+ *pOp = pIter->op;
+ *pnCol = pIter->nCol;
+ *pzTab = pIter->zTab;
+ if( pbIndirect ) *pbIndirect = pIter->bIndirect;
+ return SQLITE_OK;
+}
+
+/*
+** Return information regarding the PRIMARY KEY and number of columns in
+** the database table affected by the change that pIter currently points
+** to. This function may only be called after changeset_next() returns
+** SQLITE_ROW.
+*/
+SQLITE_API int sqlite3changeset_pk(
+ sqlite3_changeset_iter *pIter, /* Iterator object */
+ unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
+ int *pnCol /* OUT: Number of entries in output array */
+){
+ *pabPK = pIter->abPK;
+ if( pnCol ) *pnCol = pIter->nCol;
+ return SQLITE_OK;
+}
+
+/*
+** This function may only be called while the iterator is pointing to an
+** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()).
+** Otherwise, SQLITE_MISUSE is returned.
+**
+** It sets *ppValue to point to an sqlite3_value structure containing the
+** iVal'th value in the old.* record. Or, if that particular value is not
+** included in the record (because the change is an UPDATE and the field
+** was not modified and is not a PK column), set *ppValue to NULL.
+**
+** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
+** not modified. Otherwise, SQLITE_OK.
+*/
+SQLITE_API int sqlite3changeset_old(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int iVal, /* Index of old.* value to retrieve */
+ sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
+){
+ if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_DELETE ){
+ return SQLITE_MISUSE;
+ }
+ if( iVal<0 || iVal>=pIter->nCol ){
+ return SQLITE_RANGE;
+ }
+ *ppValue = pIter->apValue[iVal];
+ return SQLITE_OK;
+}
+
+/*
+** This function may only be called while the iterator is pointing to an
+** SQLITE_UPDATE or SQLITE_INSERT change (see sqlite3changeset_op()).
+** Otherwise, SQLITE_MISUSE is returned.
+**
+** It sets *ppValue to point to an sqlite3_value structure containing the
+** iVal'th value in the new.* record. Or, if that particular value is not
+** included in the record (because the change is an UPDATE and the field
+** was not modified), set *ppValue to NULL.
+**
+** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
+** not modified. Otherwise, SQLITE_OK.
+*/
+SQLITE_API int sqlite3changeset_new(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int iVal, /* Index of new.* value to retrieve */
+ sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
+){
+ if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_INSERT ){
+ return SQLITE_MISUSE;
+ }
+ if( iVal<0 || iVal>=pIter->nCol ){
+ return SQLITE_RANGE;
+ }
+ *ppValue = pIter->apValue[pIter->nCol+iVal];
+ return SQLITE_OK;
+}
+
+/*
+** The following two macros are used internally. They are similar to the
+** sqlite3changeset_new() and sqlite3changeset_old() functions, except that
+** they omit all error checking and return a pointer to the requested value.
+*/
+#define sessionChangesetNew(pIter, iVal) (pIter)->apValue[(pIter)->nCol+(iVal)]
+#define sessionChangesetOld(pIter, iVal) (pIter)->apValue[(iVal)]
+
+/*
+** This function may only be called with a changeset iterator that has been
** passed to an SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT
-** conflict-handler function. Otherwise, SQLITE_MISUSE is returned.
-**
-** If successful, *ppValue is set to point to an sqlite3_value structure
-** containing the iVal'th value of the conflicting record.
-**
-** If value iVal is out-of-range or some other error occurs, an SQLite error
-** code is returned. Otherwise, SQLITE_OK.
-*/
-SQLITE_API int sqlite3changeset_conflict(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int iVal, /* Index of conflict record value to fetch */
- sqlite3_value **ppValue /* OUT: Value from conflicting row */
-){
- if( !pIter->pConflict ){
- return SQLITE_MISUSE;
- }
- if( iVal<0 || iVal>=pIter->nCol ){
- return SQLITE_RANGE;
- }
- *ppValue = sqlite3_column_value(pIter->pConflict, iVal);
- return SQLITE_OK;
-}
-
-/*
-** This function may only be called with an iterator passed to an
-** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
-** it sets the output variable to the total number of known foreign key
-** violations in the destination database and returns SQLITE_OK.
-**
-** In all other cases this function returns SQLITE_MISUSE.
-*/
-SQLITE_API int sqlite3changeset_fk_conflicts(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int *pnOut /* OUT: Number of FK violations */
-){
- if( pIter->pConflict || pIter->apValue ){
- return SQLITE_MISUSE;
- }
- *pnOut = pIter->nCol;
- return SQLITE_OK;
-}
-
-
-/*
-** Finalize an iterator allocated with sqlite3changeset_start().
-**
-** This function may not be called on iterators passed to a conflict handler
-** callback by changeset_apply().
-*/
-SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *p){
- int rc = SQLITE_OK;
- if( p ){
- int i; /* Used to iterate through p->apValue[] */
- rc = p->rc;
- if( p->apValue ){
- for(i=0; i<p->nCol*2; i++) sqlite3ValueFree(p->apValue[i]);
- }
- sqlite3_free(p->tblhdr.aBuf);
- sqlite3_free(p->in.buf.aBuf);
- sqlite3_free(p);
- }
- return rc;
-}
-
-static int sessionChangesetInvert(
- SessionInput *pInput, /* Input changeset */
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut,
- int *pnInverted, /* OUT: Number of bytes in output changeset */
- void **ppInverted /* OUT: Inverse of pChangeset */
-){
- int rc = SQLITE_OK; /* Return value */
- SessionBuffer sOut; /* Output buffer */
- int nCol = 0; /* Number of cols in current table */
- u8 *abPK = 0; /* PK array for current table */
- sqlite3_value **apVal = 0; /* Space for values for UPDATE inversion */
- SessionBuffer sPK = {0, 0, 0}; /* PK array for current table */
-
- /* Initialize the output buffer */
- memset(&sOut, 0, sizeof(SessionBuffer));
-
- /* Zero the output variables in case an error occurs. */
- if( ppInverted ){
- *ppInverted = 0;
- *pnInverted = 0;
- }
-
- while( 1 ){
- u8 eType;
-
- /* Test for EOF. */
- if( (rc = sessionInputBuffer(pInput, 2)) ) goto finished_invert;
- if( pInput->iNext>=pInput->nData ) break;
- eType = pInput->aData[pInput->iNext];
-
- switch( eType ){
- case 'T': {
- /* A 'table' record consists of:
- **
- ** * A constant 'T' character,
- ** * Number of columns in said table (a varint),
- ** * An array of nCol bytes (sPK),
- ** * A nul-terminated table name.
- */
- int nByte;
- int nVar;
- pInput->iNext++;
- if( (rc = sessionChangesetBufferTblhdr(pInput, &nByte)) ){
- goto finished_invert;
- }
- nVar = sessionVarintGet(&pInput->aData[pInput->iNext], &nCol);
- sPK.nBuf = 0;
- sessionAppendBlob(&sPK, &pInput->aData[pInput->iNext+nVar], nCol, &rc);
- sessionAppendByte(&sOut, eType, &rc);
- sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
- if( rc ) goto finished_invert;
-
- pInput->iNext += nByte;
- sqlite3_free(apVal);
- apVal = 0;
- abPK = sPK.aBuf;
- break;
- }
-
- case SQLITE_INSERT:
- case SQLITE_DELETE: {
- int nByte;
- int bIndirect = pInput->aData[pInput->iNext+1];
- int eType2 = (eType==SQLITE_DELETE ? SQLITE_INSERT : SQLITE_DELETE);
- pInput->iNext += 2;
- assert( rc==SQLITE_OK );
- rc = sessionChangesetBufferRecord(pInput, nCol, &nByte);
- sessionAppendByte(&sOut, eType2, &rc);
- sessionAppendByte(&sOut, bIndirect, &rc);
- sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
- pInput->iNext += nByte;
- if( rc ) goto finished_invert;
- break;
- }
-
- case SQLITE_UPDATE: {
- int iCol;
-
- if( 0==apVal ){
+** conflict-handler function. Otherwise, SQLITE_MISUSE is returned.
+**
+** If successful, *ppValue is set to point to an sqlite3_value structure
+** containing the iVal'th value of the conflicting record.
+**
+** If value iVal is out-of-range or some other error occurs, an SQLite error
+** code is returned. Otherwise, SQLITE_OK.
+*/
+SQLITE_API int sqlite3changeset_conflict(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int iVal, /* Index of conflict record value to fetch */
+ sqlite3_value **ppValue /* OUT: Value from conflicting row */
+){
+ if( !pIter->pConflict ){
+ return SQLITE_MISUSE;
+ }
+ if( iVal<0 || iVal>=pIter->nCol ){
+ return SQLITE_RANGE;
+ }
+ *ppValue = sqlite3_column_value(pIter->pConflict, iVal);
+ return SQLITE_OK;
+}
+
+/*
+** This function may only be called with an iterator passed to an
+** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
+** it sets the output variable to the total number of known foreign key
+** violations in the destination database and returns SQLITE_OK.
+**
+** In all other cases this function returns SQLITE_MISUSE.
+*/
+SQLITE_API int sqlite3changeset_fk_conflicts(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int *pnOut /* OUT: Number of FK violations */
+){
+ if( pIter->pConflict || pIter->apValue ){
+ return SQLITE_MISUSE;
+ }
+ *pnOut = pIter->nCol;
+ return SQLITE_OK;
+}
+
+
+/*
+** Finalize an iterator allocated with sqlite3changeset_start().
+**
+** This function may not be called on iterators passed to a conflict handler
+** callback by changeset_apply().
+*/
+SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *p){
+ int rc = SQLITE_OK;
+ if( p ){
+ int i; /* Used to iterate through p->apValue[] */
+ rc = p->rc;
+ if( p->apValue ){
+ for(i=0; i<p->nCol*2; i++) sqlite3ValueFree(p->apValue[i]);
+ }
+ sqlite3_free(p->tblhdr.aBuf);
+ sqlite3_free(p->in.buf.aBuf);
+ sqlite3_free(p);
+ }
+ return rc;
+}
+
+static int sessionChangesetInvert(
+ SessionInput *pInput, /* Input changeset */
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut,
+ int *pnInverted, /* OUT: Number of bytes in output changeset */
+ void **ppInverted /* OUT: Inverse of pChangeset */
+){
+ int rc = SQLITE_OK; /* Return value */
+ SessionBuffer sOut; /* Output buffer */
+ int nCol = 0; /* Number of cols in current table */
+ u8 *abPK = 0; /* PK array for current table */
+ sqlite3_value **apVal = 0; /* Space for values for UPDATE inversion */
+ SessionBuffer sPK = {0, 0, 0}; /* PK array for current table */
+
+ /* Initialize the output buffer */
+ memset(&sOut, 0, sizeof(SessionBuffer));
+
+ /* Zero the output variables in case an error occurs. */
+ if( ppInverted ){
+ *ppInverted = 0;
+ *pnInverted = 0;
+ }
+
+ while( 1 ){
+ u8 eType;
+
+ /* Test for EOF. */
+ if( (rc = sessionInputBuffer(pInput, 2)) ) goto finished_invert;
+ if( pInput->iNext>=pInput->nData ) break;
+ eType = pInput->aData[pInput->iNext];
+
+ switch( eType ){
+ case 'T': {
+ /* A 'table' record consists of:
+ **
+ ** * A constant 'T' character,
+ ** * Number of columns in said table (a varint),
+ ** * An array of nCol bytes (sPK),
+ ** * A nul-terminated table name.
+ */
+ int nByte;
+ int nVar;
+ pInput->iNext++;
+ if( (rc = sessionChangesetBufferTblhdr(pInput, &nByte)) ){
+ goto finished_invert;
+ }
+ nVar = sessionVarintGet(&pInput->aData[pInput->iNext], &nCol);
+ sPK.nBuf = 0;
+ sessionAppendBlob(&sPK, &pInput->aData[pInput->iNext+nVar], nCol, &rc);
+ sessionAppendByte(&sOut, eType, &rc);
+ sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
+ if( rc ) goto finished_invert;
+
+ pInput->iNext += nByte;
+ sqlite3_free(apVal);
+ apVal = 0;
+ abPK = sPK.aBuf;
+ break;
+ }
+
+ case SQLITE_INSERT:
+ case SQLITE_DELETE: {
+ int nByte;
+ int bIndirect = pInput->aData[pInput->iNext+1];
+ int eType2 = (eType==SQLITE_DELETE ? SQLITE_INSERT : SQLITE_DELETE);
+ pInput->iNext += 2;
+ assert( rc==SQLITE_OK );
+ rc = sessionChangesetBufferRecord(pInput, nCol, &nByte);
+ sessionAppendByte(&sOut, eType2, &rc);
+ sessionAppendByte(&sOut, bIndirect, &rc);
+ sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
+ pInput->iNext += nByte;
+ if( rc ) goto finished_invert;
+ break;
+ }
+
+ case SQLITE_UPDATE: {
+ int iCol;
+
+ if( 0==apVal ){
apVal = (sqlite3_value **)sqlite3_malloc64(sizeof(apVal[0])*nCol*2);
- if( 0==apVal ){
- rc = SQLITE_NOMEM;
- goto finished_invert;
- }
- memset(apVal, 0, sizeof(apVal[0])*nCol*2);
- }
-
- /* Write the header for the new UPDATE change. Same as the original. */
- sessionAppendByte(&sOut, eType, &rc);
- sessionAppendByte(&sOut, pInput->aData[pInput->iNext+1], &rc);
-
- /* Read the old.* and new.* records for the update change. */
- pInput->iNext += 2;
+ if( 0==apVal ){
+ rc = SQLITE_NOMEM;
+ goto finished_invert;
+ }
+ memset(apVal, 0, sizeof(apVal[0])*nCol*2);
+ }
+
+ /* Write the header for the new UPDATE change. Same as the original. */
+ sessionAppendByte(&sOut, eType, &rc);
+ sessionAppendByte(&sOut, pInput->aData[pInput->iNext+1], &rc);
+
+ /* Read the old.* and new.* records for the update change. */
+ pInput->iNext += 2;
rc = sessionReadRecord(pInput, nCol, 0, &apVal[0], 0);
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol], 0);
- }
-
- /* Write the new old.* record. Consists of the PK columns from the
- ** original old.* record, and the other values from the original
- ** new.* record. */
- for(iCol=0; iCol<nCol; iCol++){
- sqlite3_value *pVal = apVal[iCol + (abPK[iCol] ? 0 : nCol)];
- sessionAppendValue(&sOut, pVal, &rc);
- }
-
- /* Write the new new.* record. Consists of a copy of all values
- ** from the original old.* record, except for the PK columns, which
- ** are set to "undefined". */
- for(iCol=0; iCol<nCol; iCol++){
- sqlite3_value *pVal = (abPK[iCol] ? 0 : apVal[iCol]);
- sessionAppendValue(&sOut, pVal, &rc);
- }
-
- for(iCol=0; iCol<nCol*2; iCol++){
- sqlite3ValueFree(apVal[iCol]);
- }
- memset(apVal, 0, sizeof(apVal[0])*nCol*2);
- if( rc!=SQLITE_OK ){
- goto finished_invert;
- }
-
- break;
- }
-
- default:
- rc = SQLITE_CORRUPT_BKPT;
- goto finished_invert;
- }
-
- assert( rc==SQLITE_OK );
+ }
+
+ /* Write the new old.* record. Consists of the PK columns from the
+ ** original old.* record, and the other values from the original
+ ** new.* record. */
+ for(iCol=0; iCol<nCol; iCol++){
+ sqlite3_value *pVal = apVal[iCol + (abPK[iCol] ? 0 : nCol)];
+ sessionAppendValue(&sOut, pVal, &rc);
+ }
+
+ /* Write the new new.* record. Consists of a copy of all values
+ ** from the original old.* record, except for the PK columns, which
+ ** are set to "undefined". */
+ for(iCol=0; iCol<nCol; iCol++){
+ sqlite3_value *pVal = (abPK[iCol] ? 0 : apVal[iCol]);
+ sessionAppendValue(&sOut, pVal, &rc);
+ }
+
+ for(iCol=0; iCol<nCol*2; iCol++){
+ sqlite3ValueFree(apVal[iCol]);
+ }
+ memset(apVal, 0, sizeof(apVal[0])*nCol*2);
+ if( rc!=SQLITE_OK ){
+ goto finished_invert;
+ }
+
+ break;
+ }
+
+ default:
+ rc = SQLITE_CORRUPT_BKPT;
+ goto finished_invert;
+ }
+
+ assert( rc==SQLITE_OK );
if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){
- rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
- sOut.nBuf = 0;
- if( rc!=SQLITE_OK ) goto finished_invert;
- }
- }
-
- assert( rc==SQLITE_OK );
+ rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
+ sOut.nBuf = 0;
+ if( rc!=SQLITE_OK ) goto finished_invert;
+ }
+ }
+
+ assert( rc==SQLITE_OK );
if( pnInverted && ALWAYS(ppInverted) ){
- *pnInverted = sOut.nBuf;
- *ppInverted = sOut.aBuf;
- sOut.aBuf = 0;
+ *pnInverted = sOut.nBuf;
+ *ppInverted = sOut.aBuf;
+ sOut.aBuf = 0;
}else if( sOut.nBuf>0 && ALWAYS(xOutput!=0) ){
- rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
- }
-
- finished_invert:
- sqlite3_free(sOut.aBuf);
- sqlite3_free(apVal);
- sqlite3_free(sPK.aBuf);
- return rc;
-}
-
-
-/*
-** Invert a changeset object.
-*/
-SQLITE_API int sqlite3changeset_invert(
- int nChangeset, /* Number of bytes in input */
- const void *pChangeset, /* Input changeset */
- int *pnInverted, /* OUT: Number of bytes in output changeset */
- void **ppInverted /* OUT: Inverse of pChangeset */
-){
- SessionInput sInput;
-
- /* Set up the input stream */
- memset(&sInput, 0, sizeof(SessionInput));
- sInput.nData = nChangeset;
- sInput.aData = (u8*)pChangeset;
-
- return sessionChangesetInvert(&sInput, 0, 0, pnInverted, ppInverted);
-}
-
-/*
-** Streaming version of sqlite3changeset_invert().
-*/
-SQLITE_API int sqlite3changeset_invert_strm(
- int (*xInput)(void *pIn, void *pData, int *pnData),
- void *pIn,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-){
- SessionInput sInput;
- int rc;
-
- /* Set up the input stream */
- memset(&sInput, 0, sizeof(SessionInput));
- sInput.xInput = xInput;
- sInput.pIn = pIn;
-
- rc = sessionChangesetInvert(&sInput, xOutput, pOut, 0, 0);
- sqlite3_free(sInput.buf.aBuf);
- return rc;
-}
-
+ rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
+ }
+
+ finished_invert:
+ sqlite3_free(sOut.aBuf);
+ sqlite3_free(apVal);
+ sqlite3_free(sPK.aBuf);
+ return rc;
+}
+
+
+/*
+** Invert a changeset object.
+*/
+SQLITE_API int sqlite3changeset_invert(
+ int nChangeset, /* Number of bytes in input */
+ const void *pChangeset, /* Input changeset */
+ int *pnInverted, /* OUT: Number of bytes in output changeset */
+ void **ppInverted /* OUT: Inverse of pChangeset */
+){
+ SessionInput sInput;
+
+ /* Set up the input stream */
+ memset(&sInput, 0, sizeof(SessionInput));
+ sInput.nData = nChangeset;
+ sInput.aData = (u8*)pChangeset;
+
+ return sessionChangesetInvert(&sInput, 0, 0, pnInverted, ppInverted);
+}
+
+/*
+** Streaming version of sqlite3changeset_invert().
+*/
+SQLITE_API int sqlite3changeset_invert_strm(
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+){
+ SessionInput sInput;
+ int rc;
+
+ /* Set up the input stream */
+ memset(&sInput, 0, sizeof(SessionInput));
+ sInput.xInput = xInput;
+ sInput.pIn = pIn;
+
+ rc = sessionChangesetInvert(&sInput, xOutput, pOut, 0, 0);
+ sqlite3_free(sInput.buf.aBuf);
+ return rc;
+}
+
typedef struct SessionUpdate SessionUpdate;
struct SessionUpdate {
@@ -212217,30 +212217,30 @@ struct SessionUpdate {
SessionUpdate *pNext;
};
-typedef struct SessionApplyCtx SessionApplyCtx;
-struct SessionApplyCtx {
- sqlite3 *db;
- sqlite3_stmt *pDelete; /* DELETE statement */
- sqlite3_stmt *pInsert; /* INSERT statement */
- sqlite3_stmt *pSelect; /* SELECT statement */
- int nCol; /* Size of azCol[] and abPK[] arrays */
- const char **azCol; /* Array of column names */
- u8 *abPK; /* Boolean array - true if column is in PK */
+typedef struct SessionApplyCtx SessionApplyCtx;
+struct SessionApplyCtx {
+ sqlite3 *db;
+ sqlite3_stmt *pDelete; /* DELETE statement */
+ sqlite3_stmt *pInsert; /* INSERT statement */
+ sqlite3_stmt *pSelect; /* SELECT statement */
+ int nCol; /* Size of azCol[] and abPK[] arrays */
+ const char **azCol; /* Array of column names */
+ u8 *abPK; /* Boolean array - true if column is in PK */
u32 *aUpdateMask; /* Used by sessionUpdateFind */
SessionUpdate *pUp;
- int bStat1; /* True if table is sqlite_stat1 */
- int bDeferConstraints; /* True to defer constraints */
+ int bStat1; /* True if table is sqlite_stat1 */
+ int bDeferConstraints; /* True to defer constraints */
int bInvertConstraints; /* Invert when iterating constraints buffer */
- SessionBuffer constraints; /* Deferred constraints are stored here */
+ SessionBuffer constraints; /* Deferred constraints are stored here */
SessionBuffer rebase; /* Rebase information (if any) here */
u8 bRebaseStarted; /* If table header is already in rebase */
u8 bRebase; /* True to collect rebase information */
-};
-
+};
+
/* Number of prepared UPDATE statements to cache. */
#define SESSION_UPDATE_CACHE_SZ 12
-/*
+/*
** Find a prepared UPDATE statement suitable for the UPDATE step currently
** being visited by the iterator. The UPDATE is of the form:
**
@@ -212399,221 +212399,221 @@ static void sessionUpdateFree(SessionApplyCtx *p){
}
/*
-** Formulate a statement to DELETE a row from database db. Assuming a table
-** structure like this:
-**
-** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
-**
-** The DELETE statement looks like this:
-**
-** DELETE FROM x WHERE a = :1 AND c = :3 AND (:5 OR b IS :2 AND d IS :4)
-**
-** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require
-** matching b and d values, or 1 otherwise. The second case comes up if the
-** conflict handler is invoked with NOTFOUND and returns CHANGESET_REPLACE.
-**
-** If successful, SQLITE_OK is returned and SessionApplyCtx.pDelete is left
-** pointing to the prepared version of the SQL statement.
-*/
-static int sessionDeleteRow(
- sqlite3 *db, /* Database handle */
- const char *zTab, /* Table name */
- SessionApplyCtx *p /* Session changeset-apply context */
-){
- int i;
- const char *zSep = "";
- int rc = SQLITE_OK;
- SessionBuffer buf = {0, 0, 0};
- int nPk = 0;
-
+** Formulate a statement to DELETE a row from database db. Assuming a table
+** structure like this:
+**
+** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
+**
+** The DELETE statement looks like this:
+**
+** DELETE FROM x WHERE a = :1 AND c = :3 AND (:5 OR b IS :2 AND d IS :4)
+**
+** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require
+** matching b and d values, or 1 otherwise. The second case comes up if the
+** conflict handler is invoked with NOTFOUND and returns CHANGESET_REPLACE.
+**
+** If successful, SQLITE_OK is returned and SessionApplyCtx.pDelete is left
+** pointing to the prepared version of the SQL statement.
+*/
+static int sessionDeleteRow(
+ sqlite3 *db, /* Database handle */
+ const char *zTab, /* Table name */
+ SessionApplyCtx *p /* Session changeset-apply context */
+){
+ int i;
+ const char *zSep = "";
+ int rc = SQLITE_OK;
+ SessionBuffer buf = {0, 0, 0};
+ int nPk = 0;
+
sessionAppendStr(&buf, "DELETE FROM main.", &rc);
- sessionAppendIdent(&buf, zTab, &rc);
- sessionAppendStr(&buf, " WHERE ", &rc);
-
- for(i=0; i<p->nCol; i++){
- if( p->abPK[i] ){
- nPk++;
- sessionAppendStr(&buf, zSep, &rc);
- sessionAppendIdent(&buf, p->azCol[i], &rc);
- sessionAppendStr(&buf, " = ?", &rc);
- sessionAppendInteger(&buf, i+1, &rc);
- zSep = " AND ";
- }
- }
-
- if( nPk<p->nCol ){
- sessionAppendStr(&buf, " AND (?", &rc);
- sessionAppendInteger(&buf, p->nCol+1, &rc);
- sessionAppendStr(&buf, " OR ", &rc);
-
- zSep = "";
- for(i=0; i<p->nCol; i++){
- if( !p->abPK[i] ){
- sessionAppendStr(&buf, zSep, &rc);
- sessionAppendIdent(&buf, p->azCol[i], &rc);
- sessionAppendStr(&buf, " IS ?", &rc);
- sessionAppendInteger(&buf, i+1, &rc);
- zSep = "AND ";
- }
- }
- sessionAppendStr(&buf, ")", &rc);
- }
-
- if( rc==SQLITE_OK ){
- rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
- }
- sqlite3_free(buf.aBuf);
-
- return rc;
-}
-
-/*
-** Formulate and prepare an SQL statement to query table zTab by primary
-** key. Assuming the following table structure:
-**
-** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
-**
-** The SELECT statement looks like this:
-**
-** SELECT * FROM x WHERE a = ?1 AND c = ?3
-**
-** If successful, SQLITE_OK is returned and SessionApplyCtx.pSelect is left
-** pointing to the prepared version of the SQL statement.
-*/
-static int sessionSelectRow(
- sqlite3 *db, /* Database handle */
- const char *zTab, /* Table name */
- SessionApplyCtx *p /* Session changeset-apply context */
-){
- return sessionSelectStmt(
- db, "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect);
-}
-
-/*
-** Formulate and prepare an INSERT statement to add a record to table zTab.
-** For example:
-**
-** INSERT INTO main."zTab" VALUES(?1, ?2, ?3 ...);
-**
-** If successful, SQLITE_OK is returned and SessionApplyCtx.pInsert is left
-** pointing to the prepared version of the SQL statement.
-*/
-static int sessionInsertRow(
- sqlite3 *db, /* Database handle */
- const char *zTab, /* Table name */
- SessionApplyCtx *p /* Session changeset-apply context */
-){
- int rc = SQLITE_OK;
- int i;
- SessionBuffer buf = {0, 0, 0};
-
- sessionAppendStr(&buf, "INSERT INTO main.", &rc);
- sessionAppendIdent(&buf, zTab, &rc);
- sessionAppendStr(&buf, "(", &rc);
- for(i=0; i<p->nCol; i++){
- if( i!=0 ) sessionAppendStr(&buf, ", ", &rc);
- sessionAppendIdent(&buf, p->azCol[i], &rc);
- }
-
- sessionAppendStr(&buf, ") VALUES(?", &rc);
- for(i=1; i<p->nCol; i++){
- sessionAppendStr(&buf, ", ?", &rc);
- }
- sessionAppendStr(&buf, ")", &rc);
-
- if( rc==SQLITE_OK ){
- rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0);
- }
- sqlite3_free(buf.aBuf);
- return rc;
-}
-
-static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){
- return sqlite3_prepare_v2(db, zSql, -1, pp, 0);
-}
-
-/*
-** Prepare statements for applying changes to the sqlite_stat1 table.
-** These are similar to those created by sessionSelectRow(),
+ sessionAppendIdent(&buf, zTab, &rc);
+ sessionAppendStr(&buf, " WHERE ", &rc);
+
+ for(i=0; i<p->nCol; i++){
+ if( p->abPK[i] ){
+ nPk++;
+ sessionAppendStr(&buf, zSep, &rc);
+ sessionAppendIdent(&buf, p->azCol[i], &rc);
+ sessionAppendStr(&buf, " = ?", &rc);
+ sessionAppendInteger(&buf, i+1, &rc);
+ zSep = " AND ";
+ }
+ }
+
+ if( nPk<p->nCol ){
+ sessionAppendStr(&buf, " AND (?", &rc);
+ sessionAppendInteger(&buf, p->nCol+1, &rc);
+ sessionAppendStr(&buf, " OR ", &rc);
+
+ zSep = "";
+ for(i=0; i<p->nCol; i++){
+ if( !p->abPK[i] ){
+ sessionAppendStr(&buf, zSep, &rc);
+ sessionAppendIdent(&buf, p->azCol[i], &rc);
+ sessionAppendStr(&buf, " IS ?", &rc);
+ sessionAppendInteger(&buf, i+1, &rc);
+ zSep = "AND ";
+ }
+ }
+ sessionAppendStr(&buf, ")", &rc);
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
+ }
+ sqlite3_free(buf.aBuf);
+
+ return rc;
+}
+
+/*
+** Formulate and prepare an SQL statement to query table zTab by primary
+** key. Assuming the following table structure:
+**
+** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
+**
+** The SELECT statement looks like this:
+**
+** SELECT * FROM x WHERE a = ?1 AND c = ?3
+**
+** If successful, SQLITE_OK is returned and SessionApplyCtx.pSelect is left
+** pointing to the prepared version of the SQL statement.
+*/
+static int sessionSelectRow(
+ sqlite3 *db, /* Database handle */
+ const char *zTab, /* Table name */
+ SessionApplyCtx *p /* Session changeset-apply context */
+){
+ return sessionSelectStmt(
+ db, "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect);
+}
+
+/*
+** Formulate and prepare an INSERT statement to add a record to table zTab.
+** For example:
+**
+** INSERT INTO main."zTab" VALUES(?1, ?2, ?3 ...);
+**
+** If successful, SQLITE_OK is returned and SessionApplyCtx.pInsert is left
+** pointing to the prepared version of the SQL statement.
+*/
+static int sessionInsertRow(
+ sqlite3 *db, /* Database handle */
+ const char *zTab, /* Table name */
+ SessionApplyCtx *p /* Session changeset-apply context */
+){
+ int rc = SQLITE_OK;
+ int i;
+ SessionBuffer buf = {0, 0, 0};
+
+ sessionAppendStr(&buf, "INSERT INTO main.", &rc);
+ sessionAppendIdent(&buf, zTab, &rc);
+ sessionAppendStr(&buf, "(", &rc);
+ for(i=0; i<p->nCol; i++){
+ if( i!=0 ) sessionAppendStr(&buf, ", ", &rc);
+ sessionAppendIdent(&buf, p->azCol[i], &rc);
+ }
+
+ sessionAppendStr(&buf, ") VALUES(?", &rc);
+ for(i=1; i<p->nCol; i++){
+ sessionAppendStr(&buf, ", ?", &rc);
+ }
+ sessionAppendStr(&buf, ")", &rc);
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0);
+ }
+ sqlite3_free(buf.aBuf);
+ return rc;
+}
+
+static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){
+ return sqlite3_prepare_v2(db, zSql, -1, pp, 0);
+}
+
+/*
+** Prepare statements for applying changes to the sqlite_stat1 table.
+** These are similar to those created by sessionSelectRow(),
** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for
-** other tables.
-*/
-static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
- int rc = sessionSelectRow(db, "sqlite_stat1", p);
- if( rc==SQLITE_OK ){
- rc = sessionPrepare(db, &p->pInsert,
- "INSERT INTO main.sqlite_stat1 VALUES(?1, "
- "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
- "?3)"
- );
- }
- if( rc==SQLITE_OK ){
- rc = sessionPrepare(db, &p->pDelete,
- "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
- "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
- "AND (?4 OR stat IS ?3)"
- );
- }
- return rc;
-}
-
-/*
+** other tables.
+*/
+static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
+ int rc = sessionSelectRow(db, "sqlite_stat1", p);
+ if( rc==SQLITE_OK ){
+ rc = sessionPrepare(db, &p->pInsert,
+ "INSERT INTO main.sqlite_stat1 VALUES(?1, "
+ "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
+ "?3)"
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sessionPrepare(db, &p->pDelete,
+ "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
+ "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
+ "AND (?4 OR stat IS ?3)"
+ );
+ }
+ return rc;
+}
+
+/*
** A wrapper around sqlite3_bind_value() that detects an extra problem.
-** See comments in the body of this function for details.
-*/
-static int sessionBindValue(
- sqlite3_stmt *pStmt, /* Statement to bind value to */
- int i, /* Parameter number to bind to */
- sqlite3_value *pVal /* Value to bind */
-){
- int eType = sqlite3_value_type(pVal);
- /* COVERAGE: The (pVal->z==0) branch is never true using current versions
- ** of SQLite. If a malloc fails in an sqlite3_value_xxx() function, either
- ** the (pVal->z) variable remains as it was or the type of the value is
- ** set to SQLITE_NULL. */
- if( (eType==SQLITE_TEXT || eType==SQLITE_BLOB) && pVal->z==0 ){
- /* This condition occurs when an earlier OOM in a call to
- ** sqlite3_value_text() or sqlite3_value_blob() (perhaps from within
- ** a conflict-handler) has zeroed the pVal->z pointer. Return NOMEM. */
- return SQLITE_NOMEM;
- }
- return sqlite3_bind_value(pStmt, i, pVal);
-}
-
-/*
+** See comments in the body of this function for details.
+*/
+static int sessionBindValue(
+ sqlite3_stmt *pStmt, /* Statement to bind value to */
+ int i, /* Parameter number to bind to */
+ sqlite3_value *pVal /* Value to bind */
+){
+ int eType = sqlite3_value_type(pVal);
+ /* COVERAGE: The (pVal->z==0) branch is never true using current versions
+ ** of SQLite. If a malloc fails in an sqlite3_value_xxx() function, either
+ ** the (pVal->z) variable remains as it was or the type of the value is
+ ** set to SQLITE_NULL. */
+ if( (eType==SQLITE_TEXT || eType==SQLITE_BLOB) && pVal->z==0 ){
+ /* This condition occurs when an earlier OOM in a call to
+ ** sqlite3_value_text() or sqlite3_value_blob() (perhaps from within
+ ** a conflict-handler) has zeroed the pVal->z pointer. Return NOMEM. */
+ return SQLITE_NOMEM;
+ }
+ return sqlite3_bind_value(pStmt, i, pVal);
+}
+
+/*
** Iterator pIter must point to an SQLITE_INSERT entry. This function
-** transfers new.* values from the current iterator entry to statement
-** pStmt. The table being inserted into has nCol columns.
-**
+** transfers new.* values from the current iterator entry to statement
+** pStmt. The table being inserted into has nCol columns.
+**
** New.* value $i from the iterator is bound to variable ($i+1) of
-** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1)
-** are transfered to the statement. Otherwise, if abPK is not NULL, it points
+** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1)
+** are transfered to the statement. Otherwise, if abPK is not NULL, it points
** to an array nCol elements in size. In this case only those values for
** which abPK[$i] is true are read from the iterator and bound to the
-** statement.
-**
-** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK.
-*/
-static int sessionBindRow(
- sqlite3_changeset_iter *pIter, /* Iterator to read values from */
- int(*xValue)(sqlite3_changeset_iter *, int, sqlite3_value **),
- int nCol, /* Number of columns */
- u8 *abPK, /* If not NULL, bind only if true */
- sqlite3_stmt *pStmt /* Bind values to this statement */
-){
- int i;
- int rc = SQLITE_OK;
-
- /* Neither sqlite3changeset_old or sqlite3changeset_new can fail if the
+** statement.
+**
+** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK.
+*/
+static int sessionBindRow(
+ sqlite3_changeset_iter *pIter, /* Iterator to read values from */
+ int(*xValue)(sqlite3_changeset_iter *, int, sqlite3_value **),
+ int nCol, /* Number of columns */
+ u8 *abPK, /* If not NULL, bind only if true */
+ sqlite3_stmt *pStmt /* Bind values to this statement */
+){
+ int i;
+ int rc = SQLITE_OK;
+
+ /* Neither sqlite3changeset_old or sqlite3changeset_new can fail if the
** argument iterator points to a suitable entry. Make sure that xValue
** is one of these to guarantee that it is safe to ignore the return
- ** in the code below. */
- assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new );
-
- for(i=0; rc==SQLITE_OK && i<nCol; i++){
- if( !abPK || abPK[i] ){
+ ** in the code below. */
+ assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new );
+
+ for(i=0; rc==SQLITE_OK && i<nCol; i++){
+ if( !abPK || abPK[i] ){
sqlite3_value *pVal = 0;
- (void)xValue(pIter, i, &pVal);
+ (void)xValue(pIter, i, &pVal);
if( pVal==0 ){
/* The value in the changeset was "undefined". This indicates a
** corrupt changeset blob. */
@@ -212621,54 +212621,54 @@ static int sessionBindRow(
}else{
rc = sessionBindValue(pStmt, i+1, pVal);
}
- }
- }
- return rc;
-}
-
-/*
-** SQL statement pSelect is as generated by the sessionSelectRow() function.
-** This function binds the primary key values from the change that changeset
-** iterator pIter points to to the SELECT and attempts to seek to the table
+ }
+ }
+ return rc;
+}
+
+/*
+** SQL statement pSelect is as generated by the sessionSelectRow() function.
+** This function binds the primary key values from the change that changeset
+** iterator pIter points to to the SELECT and attempts to seek to the table
** entry. If a row is found, the SELECT statement left pointing at the row
-** and SQLITE_ROW is returned. Otherwise, if no row is found and no error
-** has occured, the statement is reset and SQLITE_OK is returned. If an
-** error occurs, the statement is reset and an SQLite error code is returned.
-**
+** and SQLITE_ROW is returned. Otherwise, if no row is found and no error
+** has occured, the statement is reset and SQLITE_OK is returned. If an
+** error occurs, the statement is reset and an SQLite error code is returned.
+**
** If this function returns SQLITE_ROW, the caller must eventually reset()
-** statement pSelect. If any other value is returned, the statement does
-** not require a reset().
-**
-** If the iterator currently points to an INSERT record, bind values from the
-** new.* record to the SELECT statement. Or, if it points to a DELETE or
+** statement pSelect. If any other value is returned, the statement does
+** not require a reset().
+**
+** If the iterator currently points to an INSERT record, bind values from the
+** new.* record to the SELECT statement. Or, if it points to a DELETE or
** UPDATE, bind values from the old.* record.
-*/
-static int sessionSeekToRow(
- sqlite3 *db, /* Database handle */
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- u8 *abPK, /* Primary key flags array */
- sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */
-){
- int rc; /* Return code */
- int nCol; /* Number of columns in table */
- int op; /* Changset operation (SQLITE_UPDATE etc.) */
- const char *zDummy; /* Unused */
-
- sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
+*/
+static int sessionSeekToRow(
+ sqlite3 *db, /* Database handle */
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ u8 *abPK, /* Primary key flags array */
+ sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */
+){
+ int rc; /* Return code */
+ int nCol; /* Number of columns in table */
+ int op; /* Changset operation (SQLITE_UPDATE etc.) */
+ const char *zDummy; /* Unused */
+
+ sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
rc = sessionBindRow(pIter,
- op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old,
- nCol, abPK, pSelect
- );
-
- if( rc==SQLITE_OK ){
- rc = sqlite3_step(pSelect);
- if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect);
- }
-
- return rc;
-}
-
-/*
+ op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old,
+ nCol, abPK, pSelect
+ );
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_step(pSelect);
+ if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect);
+ }
+
+ return rc;
+}
+
+/*
** This function is called from within sqlite3changeset_apply_v2() when
** a conflict is encountered and resolved using conflict resolution
** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE)..
@@ -212718,283 +212718,283 @@ static int sessionRebaseAdd(
}
/*
-** Invoke the conflict handler for the change that the changeset iterator
-** currently points to.
-**
-** Argument eType must be either CHANGESET_DATA or CHANGESET_CONFLICT.
-** If argument pbReplace is NULL, then the type of conflict handler invoked
-** depends solely on eType, as follows:
-**
-** eType value Value passed to xConflict
-** -------------------------------------------------
-** CHANGESET_DATA CHANGESET_NOTFOUND
-** CHANGESET_CONFLICT CHANGESET_CONSTRAINT
-**
-** Or, if pbReplace is not NULL, then an attempt is made to find an existing
-** record with the same primary key as the record about to be deleted, updated
-** or inserted. If such a record can be found, it is available to the conflict
-** handler as the "conflicting" record. In this case the type of conflict
-** handler invoked is as follows:
-**
-** eType value PK Record found? Value passed to xConflict
-** ----------------------------------------------------------------
-** CHANGESET_DATA Yes CHANGESET_DATA
-** CHANGESET_DATA No CHANGESET_NOTFOUND
-** CHANGESET_CONFLICT Yes CHANGESET_CONFLICT
-** CHANGESET_CONFLICT No CHANGESET_CONSTRAINT
-**
-** If pbReplace is not NULL, and a record with a matching PK is found, and
-** the conflict handler function returns SQLITE_CHANGESET_REPLACE, *pbReplace
-** is set to non-zero before returning SQLITE_OK.
-**
-** If the conflict handler returns SQLITE_CHANGESET_ABORT, SQLITE_ABORT is
+** Invoke the conflict handler for the change that the changeset iterator
+** currently points to.
+**
+** Argument eType must be either CHANGESET_DATA or CHANGESET_CONFLICT.
+** If argument pbReplace is NULL, then the type of conflict handler invoked
+** depends solely on eType, as follows:
+**
+** eType value Value passed to xConflict
+** -------------------------------------------------
+** CHANGESET_DATA CHANGESET_NOTFOUND
+** CHANGESET_CONFLICT CHANGESET_CONSTRAINT
+**
+** Or, if pbReplace is not NULL, then an attempt is made to find an existing
+** record with the same primary key as the record about to be deleted, updated
+** or inserted. If such a record can be found, it is available to the conflict
+** handler as the "conflicting" record. In this case the type of conflict
+** handler invoked is as follows:
+**
+** eType value PK Record found? Value passed to xConflict
+** ----------------------------------------------------------------
+** CHANGESET_DATA Yes CHANGESET_DATA
+** CHANGESET_DATA No CHANGESET_NOTFOUND
+** CHANGESET_CONFLICT Yes CHANGESET_CONFLICT
+** CHANGESET_CONFLICT No CHANGESET_CONSTRAINT
+**
+** If pbReplace is not NULL, and a record with a matching PK is found, and
+** the conflict handler function returns SQLITE_CHANGESET_REPLACE, *pbReplace
+** is set to non-zero before returning SQLITE_OK.
+**
+** If the conflict handler returns SQLITE_CHANGESET_ABORT, SQLITE_ABORT is
** returned. Or, if the conflict handler returns an invalid value,
-** SQLITE_MISUSE. If the conflict handler returns SQLITE_CHANGESET_OMIT,
-** this function returns SQLITE_OK.
-*/
-static int sessionConflictHandler(
- int eType, /* Either CHANGESET_DATA or CONFLICT */
- SessionApplyCtx *p, /* changeset_apply() context */
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int(*xConflict)(void *, int, sqlite3_changeset_iter*),
- void *pCtx, /* First argument for conflict handler */
- int *pbReplace /* OUT: Set to true if PK row is found */
-){
- int res = 0; /* Value returned by conflict handler */
- int rc;
- int nCol;
- int op;
- const char *zDummy;
-
- sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
-
- assert( eType==SQLITE_CHANGESET_CONFLICT || eType==SQLITE_CHANGESET_DATA );
- assert( SQLITE_CHANGESET_CONFLICT+1==SQLITE_CHANGESET_CONSTRAINT );
- assert( SQLITE_CHANGESET_DATA+1==SQLITE_CHANGESET_NOTFOUND );
-
- /* Bind the new.* PRIMARY KEY values to the SELECT statement. */
- if( pbReplace ){
- rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
- }else{
- rc = SQLITE_OK;
- }
-
- if( rc==SQLITE_ROW ){
- /* There exists another row with the new.* primary key. */
- pIter->pConflict = p->pSelect;
- res = xConflict(pCtx, eType, pIter);
- pIter->pConflict = 0;
- rc = sqlite3_reset(p->pSelect);
- }else if( rc==SQLITE_OK ){
- if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){
- /* Instead of invoking the conflict handler, append the change blob
- ** to the SessionApplyCtx.constraints buffer. */
- u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
- int nBlob = pIter->in.iNext - pIter->in.iCurrent;
- sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
+** SQLITE_MISUSE. If the conflict handler returns SQLITE_CHANGESET_OMIT,
+** this function returns SQLITE_OK.
+*/
+static int sessionConflictHandler(
+ int eType, /* Either CHANGESET_DATA or CONFLICT */
+ SessionApplyCtx *p, /* changeset_apply() context */
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int(*xConflict)(void *, int, sqlite3_changeset_iter*),
+ void *pCtx, /* First argument for conflict handler */
+ int *pbReplace /* OUT: Set to true if PK row is found */
+){
+ int res = 0; /* Value returned by conflict handler */
+ int rc;
+ int nCol;
+ int op;
+ const char *zDummy;
+
+ sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
+
+ assert( eType==SQLITE_CHANGESET_CONFLICT || eType==SQLITE_CHANGESET_DATA );
+ assert( SQLITE_CHANGESET_CONFLICT+1==SQLITE_CHANGESET_CONSTRAINT );
+ assert( SQLITE_CHANGESET_DATA+1==SQLITE_CHANGESET_NOTFOUND );
+
+ /* Bind the new.* PRIMARY KEY values to the SELECT statement. */
+ if( pbReplace ){
+ rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
+ }else{
+ rc = SQLITE_OK;
+ }
+
+ if( rc==SQLITE_ROW ){
+ /* There exists another row with the new.* primary key. */
+ pIter->pConflict = p->pSelect;
+ res = xConflict(pCtx, eType, pIter);
+ pIter->pConflict = 0;
+ rc = sqlite3_reset(p->pSelect);
+ }else if( rc==SQLITE_OK ){
+ if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){
+ /* Instead of invoking the conflict handler, append the change blob
+ ** to the SessionApplyCtx.constraints buffer. */
+ u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
+ int nBlob = pIter->in.iNext - pIter->in.iCurrent;
+ sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
return SQLITE_OK;
- }else{
- /* No other row with the new.* primary key. */
- res = xConflict(pCtx, eType+1, pIter);
- if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE;
- }
- }
-
- if( rc==SQLITE_OK ){
- switch( res ){
- case SQLITE_CHANGESET_REPLACE:
- assert( pbReplace );
- *pbReplace = 1;
- break;
-
- case SQLITE_CHANGESET_OMIT:
- break;
-
- case SQLITE_CHANGESET_ABORT:
- rc = SQLITE_ABORT;
- break;
-
- default:
- rc = SQLITE_MISUSE;
- break;
- }
+ }else{
+ /* No other row with the new.* primary key. */
+ res = xConflict(pCtx, eType+1, pIter);
+ if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ switch( res ){
+ case SQLITE_CHANGESET_REPLACE:
+ assert( pbReplace );
+ *pbReplace = 1;
+ break;
+
+ case SQLITE_CHANGESET_OMIT:
+ break;
+
+ case SQLITE_CHANGESET_ABORT:
+ rc = SQLITE_ABORT;
+ break;
+
+ default:
+ rc = SQLITE_MISUSE;
+ break;
+ }
if( rc==SQLITE_OK ){
rc = sessionRebaseAdd(p, res, pIter);
}
- }
-
- return rc;
-}
-
-/*
-** Attempt to apply the change that the iterator passed as the first argument
-** currently points to to the database. If a conflict is encountered, invoke
-** the conflict handler callback.
-**
-** If argument pbRetry is NULL, then ignore any CHANGESET_DATA conflict. If
-** one is encountered, update or delete the row with the matching primary key
-** instead. Or, if pbRetry is not NULL and a CHANGESET_DATA conflict occurs,
-** invoke the conflict handler. If it returns CHANGESET_REPLACE, set *pbRetry
-** to true before returning. In this case the caller will invoke this function
-** again, this time with pbRetry set to NULL.
-**
+ }
+
+ return rc;
+}
+
+/*
+** Attempt to apply the change that the iterator passed as the first argument
+** currently points to to the database. If a conflict is encountered, invoke
+** the conflict handler callback.
+**
+** If argument pbRetry is NULL, then ignore any CHANGESET_DATA conflict. If
+** one is encountered, update or delete the row with the matching primary key
+** instead. Or, if pbRetry is not NULL and a CHANGESET_DATA conflict occurs,
+** invoke the conflict handler. If it returns CHANGESET_REPLACE, set *pbRetry
+** to true before returning. In this case the caller will invoke this function
+** again, this time with pbRetry set to NULL.
+**
** If argument pbReplace is NULL and a CHANGESET_CONFLICT conflict is
-** encountered invoke the conflict handler with CHANGESET_CONSTRAINT instead.
-** Or, if pbReplace is not NULL, invoke it with CHANGESET_CONFLICT. If such
-** an invocation returns SQLITE_CHANGESET_REPLACE, set *pbReplace to true
-** before retrying. In this case the caller attempts to remove the conflicting
+** encountered invoke the conflict handler with CHANGESET_CONSTRAINT instead.
+** Or, if pbReplace is not NULL, invoke it with CHANGESET_CONFLICT. If such
+** an invocation returns SQLITE_CHANGESET_REPLACE, set *pbReplace to true
+** before retrying. In this case the caller attempts to remove the conflicting
** row before invoking this function again, this time with pbReplace set
-** to NULL.
-**
-** If any conflict handler returns SQLITE_CHANGESET_ABORT, this function
+** to NULL.
+**
+** If any conflict handler returns SQLITE_CHANGESET_ABORT, this function
** returns SQLITE_ABORT. Otherwise, if no error occurs, SQLITE_OK is
-** returned.
-*/
-static int sessionApplyOneOp(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- SessionApplyCtx *p, /* changeset_apply() context */
- int(*xConflict)(void *, int, sqlite3_changeset_iter *),
- void *pCtx, /* First argument for the conflict handler */
- int *pbReplace, /* OUT: True to remove PK row and retry */
- int *pbRetry /* OUT: True to retry. */
-){
- const char *zDummy;
- int op;
- int nCol;
- int rc = SQLITE_OK;
-
+** returned.
+*/
+static int sessionApplyOneOp(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ SessionApplyCtx *p, /* changeset_apply() context */
+ int(*xConflict)(void *, int, sqlite3_changeset_iter *),
+ void *pCtx, /* First argument for the conflict handler */
+ int *pbReplace, /* OUT: True to remove PK row and retry */
+ int *pbRetry /* OUT: True to retry. */
+){
+ const char *zDummy;
+ int op;
+ int nCol;
+ int rc = SQLITE_OK;
+
assert( p->pDelete && p->pInsert && p->pSelect );
- assert( p->azCol && p->abPK );
- assert( !pbReplace || *pbReplace==0 );
-
- sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
-
- if( op==SQLITE_DELETE ){
-
- /* Bind values to the DELETE statement. If conflict handling is required,
- ** bind values for all columns and set bound variable (nCol+1) to true.
- ** Or, if conflict handling is not required, bind just the PK column
- ** values and, if it exists, set (nCol+1) to false. Conflict handling
- ** is not required if:
- **
- ** * this is a patchset, or
- ** * (pbRetry==0), or
- ** * all columns of the table are PK columns (in this case there is
- ** no (nCol+1) variable to bind to).
- */
- u8 *abPK = (pIter->bPatchset ? p->abPK : 0);
- rc = sessionBindRow(pIter, sqlite3changeset_old, nCol, abPK, p->pDelete);
- if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){
- rc = sqlite3_bind_int(p->pDelete, nCol+1, (pbRetry==0 || abPK));
- }
- if( rc!=SQLITE_OK ) return rc;
-
- sqlite3_step(p->pDelete);
- rc = sqlite3_reset(p->pDelete);
- if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
- rc = sessionConflictHandler(
- SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
- );
- }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
- rc = sessionConflictHandler(
- SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
- );
- }
-
- }else if( op==SQLITE_UPDATE ){
- int i;
+ assert( p->azCol && p->abPK );
+ assert( !pbReplace || *pbReplace==0 );
+
+ sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
+
+ if( op==SQLITE_DELETE ){
+
+ /* Bind values to the DELETE statement. If conflict handling is required,
+ ** bind values for all columns and set bound variable (nCol+1) to true.
+ ** Or, if conflict handling is not required, bind just the PK column
+ ** values and, if it exists, set (nCol+1) to false. Conflict handling
+ ** is not required if:
+ **
+ ** * this is a patchset, or
+ ** * (pbRetry==0), or
+ ** * all columns of the table are PK columns (in this case there is
+ ** no (nCol+1) variable to bind to).
+ */
+ u8 *abPK = (pIter->bPatchset ? p->abPK : 0);
+ rc = sessionBindRow(pIter, sqlite3changeset_old, nCol, abPK, p->pDelete);
+ if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){
+ rc = sqlite3_bind_int(p->pDelete, nCol+1, (pbRetry==0 || abPK));
+ }
+ if( rc!=SQLITE_OK ) return rc;
+
+ sqlite3_step(p->pDelete);
+ rc = sqlite3_reset(p->pDelete);
+ if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
+ rc = sessionConflictHandler(
+ SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
+ );
+ }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
+ rc = sessionConflictHandler(
+ SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
+ );
+ }
+
+ }else if( op==SQLITE_UPDATE ){
+ int i;
sqlite3_stmt *pUp = 0;
int bPatchset = (pbRetry==0 || pIter->bPatchset);
-
+
rc = sessionUpdateFind(pIter, p, bPatchset, &pUp);
- /* Bind values to the UPDATE statement. */
- for(i=0; rc==SQLITE_OK && i<nCol; i++){
- sqlite3_value *pOld = sessionChangesetOld(pIter, i);
- sqlite3_value *pNew = sessionChangesetNew(pIter, i);
+ /* Bind values to the UPDATE statement. */
+ for(i=0; rc==SQLITE_OK && i<nCol; i++){
+ sqlite3_value *pOld = sessionChangesetOld(pIter, i);
+ sqlite3_value *pNew = sessionChangesetNew(pIter, i);
if( p->abPK[i] || (bPatchset==0 && pOld) ){
rc = sessionBindValue(pUp, i*2+2, pOld);
- }
- if( rc==SQLITE_OK && pNew ){
+ }
+ if( rc==SQLITE_OK && pNew ){
rc = sessionBindValue(pUp, i*2+1, pNew);
- }
- }
- if( rc!=SQLITE_OK ) return rc;
-
- /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict,
- ** the result will be SQLITE_OK with 0 rows modified. */
+ }
+ }
+ if( rc!=SQLITE_OK ) return rc;
+
+ /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict,
+ ** the result will be SQLITE_OK with 0 rows modified. */
sqlite3_step(pUp);
rc = sqlite3_reset(pUp);
-
- if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
- /* A NOTFOUND or DATA error. Search the table to see if it contains
- ** a row with a matching primary key. If so, this is a DATA conflict.
- ** Otherwise, if there is no primary key match, it is a NOTFOUND. */
-
- rc = sessionConflictHandler(
- SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
- );
-
- }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
- /* This is always a CONSTRAINT conflict. */
- rc = sessionConflictHandler(
- SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
- );
- }
-
- }else{
- assert( op==SQLITE_INSERT );
- if( p->bStat1 ){
- /* Check if there is a conflicting row. For sqlite_stat1, this needs
+
+ if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
+ /* A NOTFOUND or DATA error. Search the table to see if it contains
+ ** a row with a matching primary key. If so, this is a DATA conflict.
+ ** Otherwise, if there is no primary key match, it is a NOTFOUND. */
+
+ rc = sessionConflictHandler(
+ SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
+ );
+
+ }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
+ /* This is always a CONSTRAINT conflict. */
+ rc = sessionConflictHandler(
+ SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
+ );
+ }
+
+ }else{
+ assert( op==SQLITE_INSERT );
+ if( p->bStat1 ){
+ /* Check if there is a conflicting row. For sqlite_stat1, this needs
** to be done using a SELECT, as there is no PRIMARY KEY in the
- ** database schema to throw an exception if a duplicate is inserted. */
- rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
- if( rc==SQLITE_ROW ){
- rc = SQLITE_CONSTRAINT;
- sqlite3_reset(p->pSelect);
- }
- }
-
- if( rc==SQLITE_OK ){
- rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
- if( rc!=SQLITE_OK ) return rc;
-
- sqlite3_step(p->pInsert);
- rc = sqlite3_reset(p->pInsert);
- }
-
- if( (rc&0xff)==SQLITE_CONSTRAINT ){
- rc = sessionConflictHandler(
- SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
- );
- }
- }
-
- return rc;
-}
-
-/*
-** Attempt to apply the change that the iterator passed as the first argument
-** currently points to to the database. If a conflict is encountered, invoke
-** the conflict handler callback.
-**
-** The difference between this function and sessionApplyOne() is that this
+ ** database schema to throw an exception if a duplicate is inserted. */
+ rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
+ if( rc==SQLITE_ROW ){
+ rc = SQLITE_CONSTRAINT;
+ sqlite3_reset(p->pSelect);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
+ if( rc!=SQLITE_OK ) return rc;
+
+ sqlite3_step(p->pInsert);
+ rc = sqlite3_reset(p->pInsert);
+ }
+
+ if( (rc&0xff)==SQLITE_CONSTRAINT ){
+ rc = sessionConflictHandler(
+ SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
+ );
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Attempt to apply the change that the iterator passed as the first argument
+** currently points to to the database. If a conflict is encountered, invoke
+** the conflict handler callback.
+**
+** The difference between this function and sessionApplyOne() is that this
** function handles the case where the conflict-handler is invoked and
-** returns SQLITE_CHANGESET_REPLACE - indicating that the change should be
-** retried in some manner.
-*/
-static int sessionApplyOneWithRetry(
- sqlite3 *db, /* Apply change to "main" db of this handle */
- sqlite3_changeset_iter *pIter, /* Changeset iterator to read change from */
- SessionApplyCtx *pApply, /* Apply context */
- int(*xConflict)(void*, int, sqlite3_changeset_iter*),
- void *pCtx /* First argument passed to xConflict */
-){
- int bReplace = 0;
- int bRetry = 0;
- int rc;
-
- rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry);
+** returns SQLITE_CHANGESET_REPLACE - indicating that the change should be
+** retried in some manner.
+*/
+static int sessionApplyOneWithRetry(
+ sqlite3 *db, /* Apply change to "main" db of this handle */
+ sqlite3_changeset_iter *pIter, /* Changeset iterator to read change from */
+ SessionApplyCtx *pApply, /* Apply context */
+ int(*xConflict)(void*, int, sqlite3_changeset_iter*),
+ void *pCtx /* First argument passed to xConflict */
+){
+ int bReplace = 0;
+ int bRetry = 0;
+ int rc;
+
+ rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry);
if( rc==SQLITE_OK ){
/* If the bRetry flag is set, the change has not been applied due to an
** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and
@@ -213005,8 +213005,8 @@ static int sessionApplyOneWithRetry(
** the SQLITE_CHANGESET_DATA problem. */
if( bRetry ){
assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE );
- rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
- }
+ rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
+ }
/* If the bReplace flag is set, the change is an INSERT that has not
** been performed because the database already contains a row with the
@@ -213031,128 +213031,128 @@ static int sessionApplyOneWithRetry(
if( rc==SQLITE_OK ){
rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0);
}
- }
- }
-
- return rc;
-}
-
-/*
-** Retry the changes accumulated in the pApply->constraints buffer.
-*/
-static int sessionRetryConstraints(
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Retry the changes accumulated in the pApply->constraints buffer.
+*/
+static int sessionRetryConstraints(
sqlite3 *db,
- int bPatchset,
- const char *zTab,
- SessionApplyCtx *pApply,
- int(*xConflict)(void*, int, sqlite3_changeset_iter*),
- void *pCtx /* First argument passed to xConflict */
-){
- int rc = SQLITE_OK;
-
- while( pApply->constraints.nBuf ){
- sqlite3_changeset_iter *pIter2 = 0;
- SessionBuffer cons = pApply->constraints;
- memset(&pApply->constraints, 0, sizeof(SessionBuffer));
-
+ int bPatchset,
+ const char *zTab,
+ SessionApplyCtx *pApply,
+ int(*xConflict)(void*, int, sqlite3_changeset_iter*),
+ void *pCtx /* First argument passed to xConflict */
+){
+ int rc = SQLITE_OK;
+
+ while( pApply->constraints.nBuf ){
+ sqlite3_changeset_iter *pIter2 = 0;
+ SessionBuffer cons = pApply->constraints;
+ memset(&pApply->constraints, 0, sizeof(SessionBuffer));
+
rc = sessionChangesetStart(
&pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints, 1
);
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
- int rc2;
- pIter2->bPatchset = bPatchset;
- pIter2->zTab = (char*)zTab;
- pIter2->nCol = pApply->nCol;
- pIter2->abPK = pApply->abPK;
- sessionBufferGrow(&pIter2->tblhdr, nByte, &rc);
- pIter2->apValue = (sqlite3_value**)pIter2->tblhdr.aBuf;
- if( rc==SQLITE_OK ) memset(pIter2->apValue, 0, nByte);
-
- while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter2) ){
- rc = sessionApplyOneWithRetry(db, pIter2, pApply, xConflict, pCtx);
- }
-
- rc2 = sqlite3changeset_finalize(pIter2);
- if( rc==SQLITE_OK ) rc = rc2;
- }
- assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 );
-
- sqlite3_free(cons.aBuf);
- if( rc!=SQLITE_OK ) break;
- if( pApply->constraints.nBuf>=cons.nBuf ){
- /* No progress was made on the last round. */
- pApply->bDeferConstraints = 0;
- }
- }
-
- return rc;
-}
-
-/*
-** Argument pIter is a changeset iterator that has been initialized, but
+ int rc2;
+ pIter2->bPatchset = bPatchset;
+ pIter2->zTab = (char*)zTab;
+ pIter2->nCol = pApply->nCol;
+ pIter2->abPK = pApply->abPK;
+ sessionBufferGrow(&pIter2->tblhdr, nByte, &rc);
+ pIter2->apValue = (sqlite3_value**)pIter2->tblhdr.aBuf;
+ if( rc==SQLITE_OK ) memset(pIter2->apValue, 0, nByte);
+
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter2) ){
+ rc = sessionApplyOneWithRetry(db, pIter2, pApply, xConflict, pCtx);
+ }
+
+ rc2 = sqlite3changeset_finalize(pIter2);
+ if( rc==SQLITE_OK ) rc = rc2;
+ }
+ assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 );
+
+ sqlite3_free(cons.aBuf);
+ if( rc!=SQLITE_OK ) break;
+ if( pApply->constraints.nBuf>=cons.nBuf ){
+ /* No progress was made on the last round. */
+ pApply->bDeferConstraints = 0;
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Argument pIter is a changeset iterator that has been initialized, but
** not yet passed to sqlite3changeset_next(). This function applies the
-** changeset to the main database attached to handle "db". The supplied
-** conflict handler callback is invoked to resolve any conflicts encountered
-** while applying the change.
-*/
-static int sessionChangesetApply(
- sqlite3 *db, /* Apply change to "main" db of this handle */
- sqlite3_changeset_iter *pIter, /* Changeset to apply */
- int(*xFilter)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- const char *zTab /* Table name */
- ),
- int(*xConflict)(
- void *pCtx, /* Copy of fifth arg to _apply() */
- int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
- sqlite3_changeset_iter *p /* Handle describing change and conflict */
- ),
+** changeset to the main database attached to handle "db". The supplied
+** conflict handler callback is invoked to resolve any conflicts encountered
+** while applying the change.
+*/
+static int sessionChangesetApply(
+ sqlite3 *db, /* Apply change to "main" db of this handle */
+ sqlite3_changeset_iter *pIter, /* Changeset to apply */
+ int(*xFilter)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ const char *zTab /* Table name */
+ ),
+ int(*xConflict)(
+ void *pCtx, /* Copy of fifth arg to _apply() */
+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
+ sqlite3_changeset_iter *p /* Handle describing change and conflict */
+ ),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase information */
int flags /* SESSION_APPLY_XXX flags */
-){
- int schemaMismatch = 0;
+){
+ int schemaMismatch = 0;
int rc = SQLITE_OK; /* Return code */
- const char *zTab = 0; /* Name of current table */
- int nTab = 0; /* Result of sqlite3Strlen30(zTab) */
- SessionApplyCtx sApply; /* changeset_apply() context object */
- int bPatchset;
-
- assert( xConflict!=0 );
-
- pIter->in.bNoDiscard = 1;
- memset(&sApply, 0, sizeof(sApply));
+ const char *zTab = 0; /* Name of current table */
+ int nTab = 0; /* Result of sqlite3Strlen30(zTab) */
+ SessionApplyCtx sApply; /* changeset_apply() context object */
+ int bPatchset;
+
+ assert( xConflict!=0 );
+
+ pIter->in.bNoDiscard = 1;
+ memset(&sApply, 0, sizeof(sApply));
sApply.bRebase = (ppRebase && pnRebase);
sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
- sqlite3_mutex_enter(sqlite3_db_mutex(db));
+ sqlite3_mutex_enter(sqlite3_db_mutex(db));
if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
}
- if( rc==SQLITE_OK ){
- rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0);
- }
- while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){
- int nCol;
- int op;
- const char *zNew;
-
- sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0);
-
- if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){
- u8 *abPK;
-
- rc = sessionRetryConstraints(
- db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx
- );
- if( rc!=SQLITE_OK ) break;
-
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0);
+ }
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){
+ int nCol;
+ int op;
+ const char *zNew;
+
+ sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0);
+
+ if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){
+ u8 *abPK;
+
+ rc = sessionRetryConstraints(
+ db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx
+ );
+ if( rc!=SQLITE_OK ) break;
+
sessionUpdateFree(&sApply);
- sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */
- sqlite3_finalize(sApply.pDelete);
- sqlite3_finalize(sApply.pInsert);
- sqlite3_finalize(sApply.pSelect);
- sApply.db = db;
+ sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */
+ sqlite3_finalize(sApply.pDelete);
+ sqlite3_finalize(sApply.pInsert);
+ sqlite3_finalize(sApply.pSelect);
+ sApply.db = db;
sApply.pDelete = 0;
sApply.pInsert = 0;
sApply.pSelect = 0;
@@ -213160,110 +213160,110 @@ static int sessionChangesetApply(
sApply.azCol = 0;
sApply.abPK = 0;
sApply.bStat1 = 0;
- sApply.bDeferConstraints = 1;
+ sApply.bDeferConstraints = 1;
sApply.bRebaseStarted = 0;
memset(&sApply.constraints, 0, sizeof(SessionBuffer));
-
+
/* If an xFilter() callback was specified, invoke it now. If the
- ** xFilter callback returns zero, skip this table. If it returns
- ** non-zero, proceed. */
- schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew)));
- if( schemaMismatch ){
- zTab = sqlite3_mprintf("%s", zNew);
- if( zTab==0 ){
- rc = SQLITE_NOMEM;
- break;
- }
- nTab = (int)strlen(zTab);
- sApply.azCol = (const char **)zTab;
- }else{
- int nMinCol = 0;
- int i;
-
- sqlite3changeset_pk(pIter, &abPK, 0);
+ ** xFilter callback returns zero, skip this table. If it returns
+ ** non-zero, proceed. */
+ schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew)));
+ if( schemaMismatch ){
+ zTab = sqlite3_mprintf("%s", zNew);
+ if( zTab==0 ){
+ rc = SQLITE_NOMEM;
+ break;
+ }
+ nTab = (int)strlen(zTab);
+ sApply.azCol = (const char **)zTab;
+ }else{
+ int nMinCol = 0;
+ int i;
+
+ sqlite3changeset_pk(pIter, &abPK, 0);
rc = sessionTableInfo(0,
- db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK
- );
- if( rc!=SQLITE_OK ) break;
- for(i=0; i<sApply.nCol; i++){
- if( sApply.abPK[i] ) nMinCol = i+1;
- }
-
- if( sApply.nCol==0 ){
- schemaMismatch = 1;
+ db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK
+ );
+ if( rc!=SQLITE_OK ) break;
+ for(i=0; i<sApply.nCol; i++){
+ if( sApply.abPK[i] ) nMinCol = i+1;
+ }
+
+ if( sApply.nCol==0 ){
+ schemaMismatch = 1;
sqlite3_log(SQLITE_SCHEMA,
- "sqlite3changeset_apply(): no such table: %s", zTab
- );
- }
- else if( sApply.nCol<nCol ){
- schemaMismatch = 1;
+ "sqlite3changeset_apply(): no such table: %s", zTab
+ );
+ }
+ else if( sApply.nCol<nCol ){
+ schemaMismatch = 1;
sqlite3_log(SQLITE_SCHEMA,
- "sqlite3changeset_apply(): table %s has %d columns, "
+ "sqlite3changeset_apply(): table %s has %d columns, "
"expected %d or more",
- zTab, sApply.nCol, nCol
- );
- }
- else if( nCol<nMinCol || memcmp(sApply.abPK, abPK, nCol)!=0 ){
- schemaMismatch = 1;
- sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): "
- "primary key mismatch for table %s", zTab
- );
- }
- else{
- sApply.nCol = nCol;
- if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){
- if( (rc = sessionStat1Sql(db, &sApply) ) ){
- break;
- }
- sApply.bStat1 = 1;
- }else{
+ zTab, sApply.nCol, nCol
+ );
+ }
+ else if( nCol<nMinCol || memcmp(sApply.abPK, abPK, nCol)!=0 ){
+ schemaMismatch = 1;
+ sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): "
+ "primary key mismatch for table %s", zTab
+ );
+ }
+ else{
+ sApply.nCol = nCol;
+ if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){
+ if( (rc = sessionStat1Sql(db, &sApply) ) ){
+ break;
+ }
+ sApply.bStat1 = 1;
+ }else{
if( (rc = sessionSelectRow(db, zTab, &sApply))
|| (rc = sessionDeleteRow(db, zTab, &sApply))
|| (rc = sessionInsertRow(db, zTab, &sApply))
){
- break;
- }
- sApply.bStat1 = 0;
- }
- }
- nTab = sqlite3Strlen30(zTab);
- }
- }
-
- /* If there is a schema mismatch on the current table, proceed to the
- ** next change. A log message has already been issued. */
- if( schemaMismatch ) continue;
-
- rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx);
- }
-
- bPatchset = pIter->bPatchset;
- if( rc==SQLITE_OK ){
- rc = sqlite3changeset_finalize(pIter);
- }else{
- sqlite3changeset_finalize(pIter);
- }
-
- if( rc==SQLITE_OK ){
- rc = sessionRetryConstraints(db, bPatchset, zTab, &sApply, xConflict, pCtx);
- }
-
- if( rc==SQLITE_OK ){
- int nFk, notUsed;
- sqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, &nFk, &notUsed, 0);
- if( nFk!=0 ){
- int res = SQLITE_CHANGESET_ABORT;
- sqlite3_changeset_iter sIter;
- memset(&sIter, 0, sizeof(sIter));
- sIter.nCol = nFk;
- res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter);
- if( res!=SQLITE_CHANGESET_OMIT ){
- rc = SQLITE_CONSTRAINT;
- }
- }
- }
- sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0);
-
+ break;
+ }
+ sApply.bStat1 = 0;
+ }
+ }
+ nTab = sqlite3Strlen30(zTab);
+ }
+ }
+
+ /* If there is a schema mismatch on the current table, proceed to the
+ ** next change. A log message has already been issued. */
+ if( schemaMismatch ) continue;
+
+ rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx);
+ }
+
+ bPatchset = pIter->bPatchset;
+ if( rc==SQLITE_OK ){
+ rc = sqlite3changeset_finalize(pIter);
+ }else{
+ sqlite3changeset_finalize(pIter);
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = sessionRetryConstraints(db, bPatchset, zTab, &sApply, xConflict, pCtx);
+ }
+
+ if( rc==SQLITE_OK ){
+ int nFk, notUsed;
+ sqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, &nFk, &notUsed, 0);
+ if( nFk!=0 ){
+ int res = SQLITE_CHANGESET_ABORT;
+ sqlite3_changeset_iter sIter;
+ memset(&sIter, 0, sizeof(sIter));
+ sIter.nCol = nFk;
+ res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter);
+ if( res!=SQLITE_CHANGESET_OMIT ){
+ rc = SQLITE_CONSTRAINT;
+ }
+ }
+ }
+ sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0);
+
if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
if( rc==SQLITE_OK ){
rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
@@ -213271,8 +213271,8 @@ static int sessionChangesetApply(
sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
}
- }
-
+ }
+
assert( sApply.bRebase || sApply.rebase.nBuf==0 );
if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
*ppRebase = (void*)sApply.rebase.aBuf;
@@ -213280,17 +213280,17 @@ static int sessionChangesetApply(
sApply.rebase.aBuf = 0;
}
sessionUpdateFree(&sApply);
- sqlite3_finalize(sApply.pInsert);
- sqlite3_finalize(sApply.pDelete);
- sqlite3_finalize(sApply.pSelect);
- sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */
- sqlite3_free((char*)sApply.constraints.aBuf);
+ sqlite3_finalize(sApply.pInsert);
+ sqlite3_finalize(sApply.pDelete);
+ sqlite3_finalize(sApply.pSelect);
+ sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */
+ sqlite3_free((char*)sApply.constraints.aBuf);
sqlite3_free((char*)sApply.rebase.aBuf);
- sqlite3_mutex_leave(sqlite3_db_mutex(db));
- return rc;
-}
-
-/*
+ sqlite3_mutex_leave(sqlite3_db_mutex(db));
+ return rc;
+}
+
+/*
** Apply the changeset passed via pChangeset/nChangeset to the main
** database attached to handle "db".
*/
@@ -213323,62 +213323,62 @@ SQLITE_API int sqlite3changeset_apply_v2(
}
/*
-** Apply the changeset passed via pChangeset/nChangeset to the main database
-** attached to handle "db". Invoke the supplied conflict handler callback
-** to resolve any conflicts encountered while applying the change.
-*/
-SQLITE_API int sqlite3changeset_apply(
- sqlite3 *db, /* Apply change to "main" db of this handle */
- int nChangeset, /* Size of changeset in bytes */
- void *pChangeset, /* Changeset blob */
- int(*xFilter)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- const char *zTab /* Table name */
- ),
- int(*xConflict)(
- void *pCtx, /* Copy of fifth arg to _apply() */
- int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
- sqlite3_changeset_iter *p /* Handle describing change and conflict */
- ),
- void *pCtx /* First argument passed to xConflict */
-){
+** Apply the changeset passed via pChangeset/nChangeset to the main database
+** attached to handle "db". Invoke the supplied conflict handler callback
+** to resolve any conflicts encountered while applying the change.
+*/
+SQLITE_API int sqlite3changeset_apply(
+ sqlite3 *db, /* Apply change to "main" db of this handle */
+ int nChangeset, /* Size of changeset in bytes */
+ void *pChangeset, /* Changeset blob */
+ int(*xFilter)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ const char *zTab /* Table name */
+ ),
+ int(*xConflict)(
+ void *pCtx, /* Copy of fifth arg to _apply() */
+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
+ sqlite3_changeset_iter *p /* Handle describing change and conflict */
+ ),
+ void *pCtx /* First argument passed to xConflict */
+){
return sqlite3changeset_apply_v2(
db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0, 0
);
-}
-
-/*
-** Apply the changeset passed via xInput/pIn to the main database
-** attached to handle "db". Invoke the supplied conflict handler callback
-** to resolve any conflicts encountered while applying the change.
-*/
+}
+
+/*
+** Apply the changeset passed via xInput/pIn to the main database
+** attached to handle "db". Invoke the supplied conflict handler callback
+** to resolve any conflicts encountered while applying the change.
+*/
SQLITE_API int sqlite3changeset_apply_v2_strm(
- sqlite3 *db, /* Apply change to "main" db of this handle */
- int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
- void *pIn, /* First arg for xInput */
- int(*xFilter)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- const char *zTab /* Table name */
- ),
- int(*xConflict)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
- sqlite3_changeset_iter *p /* Handle describing change and conflict */
- ),
+ sqlite3 *db, /* Apply change to "main" db of this handle */
+ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
+ void *pIn, /* First arg for xInput */
+ int(*xFilter)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ const char *zTab /* Table name */
+ ),
+ int(*xConflict)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
+ sqlite3_changeset_iter *p /* Handle describing change and conflict */
+ ),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
-){
+){
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse, 1);
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
rc = sessionChangesetApply(
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
);
- }
- return rc;
-}
+ }
+ return rc;
+}
SQLITE_API int sqlite3changeset_apply_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
@@ -213398,44 +213398,44 @@ SQLITE_API int sqlite3changeset_apply_strm(
db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0, 0
);
}
-
-/*
-** sqlite3_changegroup handle.
-*/
-struct sqlite3_changegroup {
- int rc; /* Error code */
- int bPatch; /* True to accumulate patchsets */
- SessionTable *pList; /* List of tables in current patch */
-};
-
-/*
-** This function is called to merge two changes to the same row together as
-** part of an sqlite3changeset_concat() operation. A new change object is
-** allocated and a pointer to it stored in *ppNew.
-*/
-static int sessionChangeMerge(
- SessionTable *pTab, /* Table structure */
+
+/*
+** sqlite3_changegroup handle.
+*/
+struct sqlite3_changegroup {
+ int rc; /* Error code */
+ int bPatch; /* True to accumulate patchsets */
+ SessionTable *pList; /* List of tables in current patch */
+};
+
+/*
+** This function is called to merge two changes to the same row together as
+** part of an sqlite3changeset_concat() operation. A new change object is
+** allocated and a pointer to it stored in *ppNew.
+*/
+static int sessionChangeMerge(
+ SessionTable *pTab, /* Table structure */
int bRebase, /* True for a rebase hash-table */
- int bPatchset, /* True for patchsets */
- SessionChange *pExist, /* Existing change */
- int op2, /* Second change operation */
- int bIndirect, /* True if second change is indirect */
- u8 *aRec, /* Second change record */
- int nRec, /* Number of bytes in aRec */
- SessionChange **ppNew /* OUT: Merged change */
-){
- SessionChange *pNew = 0;
+ int bPatchset, /* True for patchsets */
+ SessionChange *pExist, /* Existing change */
+ int op2, /* Second change operation */
+ int bIndirect, /* True if second change is indirect */
+ u8 *aRec, /* Second change record */
+ int nRec, /* Number of bytes in aRec */
+ SessionChange **ppNew /* OUT: Merged change */
+){
+ SessionChange *pNew = 0;
int rc = SQLITE_OK;
-
- if( !pExist ){
+
+ if( !pExist ){
pNew = (SessionChange *)sqlite3_malloc64(sizeof(SessionChange) + nRec);
- if( !pNew ){
- return SQLITE_NOMEM;
- }
- memset(pNew, 0, sizeof(SessionChange));
- pNew->op = op2;
- pNew->bIndirect = bIndirect;
- pNew->aRecord = (u8*)&pNew[1];
+ if( !pNew ){
+ return SQLITE_NOMEM;
+ }
+ memset(pNew, 0, sizeof(SessionChange));
+ pNew->op = op2;
+ pNew->bIndirect = bIndirect;
+ pNew->aRecord = (u8*)&pNew[1];
if( bIndirect==0 || bRebase==0 ){
pNew->nRecord = nRec;
memcpy(pNew->aRecord, aRec, nRec);
@@ -213495,439 +213495,439 @@ static int sessionChangeMerge(
}
sqlite3_free(pExist);
}
- }else{
- int op1 = pExist->op;
-
+ }else{
+ int op1 = pExist->op;
+
/*
- ** op1=INSERT, op2=INSERT -> Unsupported. Discard op2.
- ** op1=INSERT, op2=UPDATE -> INSERT.
- ** op1=INSERT, op2=DELETE -> (none)
- **
- ** op1=UPDATE, op2=INSERT -> Unsupported. Discard op2.
- ** op1=UPDATE, op2=UPDATE -> UPDATE.
- ** op1=UPDATE, op2=DELETE -> DELETE.
- **
- ** op1=DELETE, op2=INSERT -> UPDATE.
- ** op1=DELETE, op2=UPDATE -> Unsupported. Discard op2.
- ** op1=DELETE, op2=DELETE -> Unsupported. Discard op2.
+ ** op1=INSERT, op2=INSERT -> Unsupported. Discard op2.
+ ** op1=INSERT, op2=UPDATE -> INSERT.
+ ** op1=INSERT, op2=DELETE -> (none)
+ **
+ ** op1=UPDATE, op2=INSERT -> Unsupported. Discard op2.
+ ** op1=UPDATE, op2=UPDATE -> UPDATE.
+ ** op1=UPDATE, op2=DELETE -> DELETE.
+ **
+ ** op1=DELETE, op2=INSERT -> UPDATE.
+ ** op1=DELETE, op2=UPDATE -> Unsupported. Discard op2.
+ ** op1=DELETE, op2=DELETE -> Unsupported. Discard op2.
*/
- if( (op1==SQLITE_INSERT && op2==SQLITE_INSERT)
- || (op1==SQLITE_UPDATE && op2==SQLITE_INSERT)
- || (op1==SQLITE_DELETE && op2==SQLITE_UPDATE)
- || (op1==SQLITE_DELETE && op2==SQLITE_DELETE)
- ){
- pNew = pExist;
- }else if( op1==SQLITE_INSERT && op2==SQLITE_DELETE ){
- sqlite3_free(pExist);
- assert( pNew==0 );
- }else{
- u8 *aExist = pExist->aRecord;
+ if( (op1==SQLITE_INSERT && op2==SQLITE_INSERT)
+ || (op1==SQLITE_UPDATE && op2==SQLITE_INSERT)
+ || (op1==SQLITE_DELETE && op2==SQLITE_UPDATE)
+ || (op1==SQLITE_DELETE && op2==SQLITE_DELETE)
+ ){
+ pNew = pExist;
+ }else if( op1==SQLITE_INSERT && op2==SQLITE_DELETE ){
+ sqlite3_free(pExist);
+ assert( pNew==0 );
+ }else{
+ u8 *aExist = pExist->aRecord;
sqlite3_int64 nByte;
- u8 *aCsr;
-
- /* Allocate a new SessionChange object. Ensure that the aRecord[]
- ** buffer of the new object is large enough to hold any record that
- ** may be generated by combining the input records. */
- nByte = sizeof(SessionChange) + pExist->nRecord + nRec;
+ u8 *aCsr;
+
+ /* Allocate a new SessionChange object. Ensure that the aRecord[]
+ ** buffer of the new object is large enough to hold any record that
+ ** may be generated by combining the input records. */
+ nByte = sizeof(SessionChange) + pExist->nRecord + nRec;
pNew = (SessionChange *)sqlite3_malloc64(nByte);
- if( !pNew ){
- sqlite3_free(pExist);
- return SQLITE_NOMEM;
- }
- memset(pNew, 0, sizeof(SessionChange));
- pNew->bIndirect = (bIndirect && pExist->bIndirect);
- aCsr = pNew->aRecord = (u8 *)&pNew[1];
-
- if( op1==SQLITE_INSERT ){ /* INSERT + UPDATE */
- u8 *a1 = aRec;
- assert( op2==SQLITE_UPDATE );
- pNew->op = SQLITE_INSERT;
- if( bPatchset==0 ) sessionSkipRecord(&a1, pTab->nCol);
- sessionMergeRecord(&aCsr, pTab->nCol, aExist, a1);
- }else if( op1==SQLITE_DELETE ){ /* DELETE + INSERT */
- assert( op2==SQLITE_INSERT );
- pNew->op = SQLITE_UPDATE;
- if( bPatchset ){
- memcpy(aCsr, aRec, nRec);
- aCsr += nRec;
- }else{
- if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0,aRec,0) ){
- sqlite3_free(pNew);
- pNew = 0;
- }
- }
- }else if( op2==SQLITE_UPDATE ){ /* UPDATE + UPDATE */
- u8 *a1 = aExist;
- u8 *a2 = aRec;
- assert( op1==SQLITE_UPDATE );
- if( bPatchset==0 ){
- sessionSkipRecord(&a1, pTab->nCol);
- sessionSkipRecord(&a2, pTab->nCol);
- }
- pNew->op = SQLITE_UPDATE;
- if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aRec, aExist,a1,a2) ){
- sqlite3_free(pNew);
- pNew = 0;
- }
- }else{ /* UPDATE + DELETE */
- assert( op1==SQLITE_UPDATE && op2==SQLITE_DELETE );
- pNew->op = SQLITE_DELETE;
- if( bPatchset ){
- memcpy(aCsr, aRec, nRec);
- aCsr += nRec;
- }else{
- sessionMergeRecord(&aCsr, pTab->nCol, aRec, aExist);
- }
- }
-
- if( pNew ){
- pNew->nRecord = (int)(aCsr - pNew->aRecord);
- }
- sqlite3_free(pExist);
- }
- }
-
- *ppNew = pNew;
- return rc;
-}
-
-/*
-** Add all changes in the changeset traversed by the iterator passed as
-** the first argument to the changegroup hash tables.
-*/
-static int sessionChangesetToHash(
- sqlite3_changeset_iter *pIter, /* Iterator to read from */
+ if( !pNew ){
+ sqlite3_free(pExist);
+ return SQLITE_NOMEM;
+ }
+ memset(pNew, 0, sizeof(SessionChange));
+ pNew->bIndirect = (bIndirect && pExist->bIndirect);
+ aCsr = pNew->aRecord = (u8 *)&pNew[1];
+
+ if( op1==SQLITE_INSERT ){ /* INSERT + UPDATE */
+ u8 *a1 = aRec;
+ assert( op2==SQLITE_UPDATE );
+ pNew->op = SQLITE_INSERT;
+ if( bPatchset==0 ) sessionSkipRecord(&a1, pTab->nCol);
+ sessionMergeRecord(&aCsr, pTab->nCol, aExist, a1);
+ }else if( op1==SQLITE_DELETE ){ /* DELETE + INSERT */
+ assert( op2==SQLITE_INSERT );
+ pNew->op = SQLITE_UPDATE;
+ if( bPatchset ){
+ memcpy(aCsr, aRec, nRec);
+ aCsr += nRec;
+ }else{
+ if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0,aRec,0) ){
+ sqlite3_free(pNew);
+ pNew = 0;
+ }
+ }
+ }else if( op2==SQLITE_UPDATE ){ /* UPDATE + UPDATE */
+ u8 *a1 = aExist;
+ u8 *a2 = aRec;
+ assert( op1==SQLITE_UPDATE );
+ if( bPatchset==0 ){
+ sessionSkipRecord(&a1, pTab->nCol);
+ sessionSkipRecord(&a2, pTab->nCol);
+ }
+ pNew->op = SQLITE_UPDATE;
+ if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aRec, aExist,a1,a2) ){
+ sqlite3_free(pNew);
+ pNew = 0;
+ }
+ }else{ /* UPDATE + DELETE */
+ assert( op1==SQLITE_UPDATE && op2==SQLITE_DELETE );
+ pNew->op = SQLITE_DELETE;
+ if( bPatchset ){
+ memcpy(aCsr, aRec, nRec);
+ aCsr += nRec;
+ }else{
+ sessionMergeRecord(&aCsr, pTab->nCol, aRec, aExist);
+ }
+ }
+
+ if( pNew ){
+ pNew->nRecord = (int)(aCsr - pNew->aRecord);
+ }
+ sqlite3_free(pExist);
+ }
+ }
+
+ *ppNew = pNew;
+ return rc;
+}
+
+/*
+** Add all changes in the changeset traversed by the iterator passed as
+** the first argument to the changegroup hash tables.
+*/
+static int sessionChangesetToHash(
+ sqlite3_changeset_iter *pIter, /* Iterator to read from */
sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */
int bRebase /* True if hash table is for rebasing */
-){
- u8 *aRec;
- int nRec;
- int rc = SQLITE_OK;
- SessionTable *pTab = 0;
-
+){
+ u8 *aRec;
+ int nRec;
+ int rc = SQLITE_OK;
+ SessionTable *pTab = 0;
+
while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){
- const char *zNew;
- int nCol;
- int op;
- int iHash;
- int bIndirect;
- SessionChange *pChange;
- SessionChange *pExist = 0;
- SessionChange **pp;
-
- if( pGrp->pList==0 ){
- pGrp->bPatch = pIter->bPatchset;
- }else if( pIter->bPatchset!=pGrp->bPatch ){
- rc = SQLITE_ERROR;
- break;
- }
-
- sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect);
- if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){
- /* Search the list for a matching table */
- int nNew = (int)strlen(zNew);
- u8 *abPK;
-
- sqlite3changeset_pk(pIter, &abPK, 0);
- for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){
- if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break;
- }
- if( !pTab ){
- SessionTable **ppTab;
-
+ const char *zNew;
+ int nCol;
+ int op;
+ int iHash;
+ int bIndirect;
+ SessionChange *pChange;
+ SessionChange *pExist = 0;
+ SessionChange **pp;
+
+ if( pGrp->pList==0 ){
+ pGrp->bPatch = pIter->bPatchset;
+ }else if( pIter->bPatchset!=pGrp->bPatch ){
+ rc = SQLITE_ERROR;
+ break;
+ }
+
+ sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect);
+ if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){
+ /* Search the list for a matching table */
+ int nNew = (int)strlen(zNew);
+ u8 *abPK;
+
+ sqlite3changeset_pk(pIter, &abPK, 0);
+ for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){
+ if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break;
+ }
+ if( !pTab ){
+ SessionTable **ppTab;
+
pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1);
- if( !pTab ){
- rc = SQLITE_NOMEM;
- break;
- }
- memset(pTab, 0, sizeof(SessionTable));
- pTab->nCol = nCol;
- pTab->abPK = (u8*)&pTab[1];
- memcpy(pTab->abPK, abPK, nCol);
- pTab->zName = (char*)&pTab->abPK[nCol];
- memcpy(pTab->zName, zNew, nNew+1);
-
- /* The new object must be linked on to the end of the list, not
- ** simply added to the start of it. This is to ensure that the
+ if( !pTab ){
+ rc = SQLITE_NOMEM;
+ break;
+ }
+ memset(pTab, 0, sizeof(SessionTable));
+ pTab->nCol = nCol;
+ pTab->abPK = (u8*)&pTab[1];
+ memcpy(pTab->abPK, abPK, nCol);
+ pTab->zName = (char*)&pTab->abPK[nCol];
+ memcpy(pTab->zName, zNew, nNew+1);
+
+ /* The new object must be linked on to the end of the list, not
+ ** simply added to the start of it. This is to ensure that the
** tables within the output of sqlite3changegroup_output() are in
- ** the right order. */
- for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext);
- *ppTab = pTab;
- }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){
- rc = SQLITE_SCHEMA;
- break;
- }
- }
-
+ ** the right order. */
+ for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext);
+ *ppTab = pTab;
+ }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){
+ rc = SQLITE_SCHEMA;
+ break;
+ }
+ }
+
if( sessionGrowHash(0, pIter->bPatchset, pTab) ){
- rc = SQLITE_NOMEM;
- break;
- }
- iHash = sessionChangeHash(
- pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange
- );
-
+ rc = SQLITE_NOMEM;
+ break;
+ }
+ iHash = sessionChangeHash(
+ pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange
+ );
+
/* Search for existing entry. If found, remove it from the hash table.
- ** Code below may link it back in.
- */
- for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){
- int bPkOnly1 = 0;
- int bPkOnly2 = 0;
- if( pIter->bPatchset ){
- bPkOnly1 = (*pp)->op==SQLITE_DELETE;
- bPkOnly2 = op==SQLITE_DELETE;
- }
- if( sessionChangeEqual(pTab, bPkOnly1, (*pp)->aRecord, bPkOnly2, aRec) ){
- pExist = *pp;
- *pp = (*pp)->pNext;
- pTab->nEntry--;
- break;
- }
- }
-
+ ** Code below may link it back in.
+ */
+ for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){
+ int bPkOnly1 = 0;
+ int bPkOnly2 = 0;
+ if( pIter->bPatchset ){
+ bPkOnly1 = (*pp)->op==SQLITE_DELETE;
+ bPkOnly2 = op==SQLITE_DELETE;
+ }
+ if( sessionChangeEqual(pTab, bPkOnly1, (*pp)->aRecord, bPkOnly2, aRec) ){
+ pExist = *pp;
+ *pp = (*pp)->pNext;
+ pTab->nEntry--;
+ break;
+ }
+ }
+
rc = sessionChangeMerge(pTab, bRebase,
- pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange
- );
- if( rc ) break;
- if( pChange ){
- pChange->pNext = pTab->apChange[iHash];
- pTab->apChange[iHash] = pChange;
- pTab->nEntry++;
- }
- }
-
- if( rc==SQLITE_OK ) rc = pIter->rc;
- return rc;
-}
-
-/*
-** Serialize a changeset (or patchset) based on all changesets (or patchsets)
-** added to the changegroup object passed as the first argument.
-**
-** If xOutput is not NULL, then the changeset/patchset is returned to the
-** user via one or more calls to xOutput, as with the other streaming
+ pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange
+ );
+ if( rc ) break;
+ if( pChange ){
+ pChange->pNext = pTab->apChange[iHash];
+ pTab->apChange[iHash] = pChange;
+ pTab->nEntry++;
+ }
+ }
+
+ if( rc==SQLITE_OK ) rc = pIter->rc;
+ return rc;
+}
+
+/*
+** Serialize a changeset (or patchset) based on all changesets (or patchsets)
+** added to the changegroup object passed as the first argument.
+**
+** If xOutput is not NULL, then the changeset/patchset is returned to the
+** user via one or more calls to xOutput, as with the other streaming
** interfaces.
-**
-** Or, if xOutput is NULL, then (*ppOut) is populated with a pointer to a
-** buffer containing the output changeset before this function returns. In
-** this case (*pnOut) is set to the size of the output buffer in bytes. It
-** is the responsibility of the caller to free the output buffer using
-** sqlite3_free() when it is no longer required.
-**
-** If successful, SQLITE_OK is returned. Or, if an error occurs, an SQLite
-** error code. If an error occurs and xOutput is NULL, (*ppOut) and (*pnOut)
-** are both set to 0 before returning.
-*/
-static int sessionChangegroupOutput(
- sqlite3_changegroup *pGrp,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut,
- int *pnOut,
- void **ppOut
-){
- int rc = SQLITE_OK;
- SessionBuffer buf = {0, 0, 0};
- SessionTable *pTab;
- assert( xOutput==0 || (ppOut==0 && pnOut==0) );
-
- /* Create the serialized output changeset based on the contents of the
+**
+** Or, if xOutput is NULL, then (*ppOut) is populated with a pointer to a
+** buffer containing the output changeset before this function returns. In
+** this case (*pnOut) is set to the size of the output buffer in bytes. It
+** is the responsibility of the caller to free the output buffer using
+** sqlite3_free() when it is no longer required.
+**
+** If successful, SQLITE_OK is returned. Or, if an error occurs, an SQLite
+** error code. If an error occurs and xOutput is NULL, (*ppOut) and (*pnOut)
+** are both set to 0 before returning.
+*/
+static int sessionChangegroupOutput(
+ sqlite3_changegroup *pGrp,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut,
+ int *pnOut,
+ void **ppOut
+){
+ int rc = SQLITE_OK;
+ SessionBuffer buf = {0, 0, 0};
+ SessionTable *pTab;
+ assert( xOutput==0 || (ppOut==0 && pnOut==0) );
+
+ /* Create the serialized output changeset based on the contents of the
** hash tables attached to the SessionTable objects in list p->pList.
- */
- for(pTab=pGrp->pList; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
- int i;
- if( pTab->nEntry==0 ) continue;
-
- sessionAppendTableHdr(&buf, pGrp->bPatch, pTab, &rc);
- for(i=0; i<pTab->nChange; i++){
- SessionChange *p;
- for(p=pTab->apChange[i]; p; p=p->pNext){
- sessionAppendByte(&buf, p->op, &rc);
- sessionAppendByte(&buf, p->bIndirect, &rc);
- sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
+ */
+ for(pTab=pGrp->pList; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
+ int i;
+ if( pTab->nEntry==0 ) continue;
+
+ sessionAppendTableHdr(&buf, pGrp->bPatch, pTab, &rc);
+ for(i=0; i<pTab->nChange; i++){
+ SessionChange *p;
+ for(p=pTab->apChange[i]; p; p=p->pNext){
+ sessionAppendByte(&buf, p->op, &rc);
+ sessionAppendByte(&buf, p->bIndirect, &rc);
+ sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){
rc = xOutput(pOut, buf.aBuf, buf.nBuf);
buf.nBuf = 0;
}
- }
- }
- }
-
- if( rc==SQLITE_OK ){
- if( xOutput ){
- if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ if( xOutput ){
+ if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
}else if( ppOut ){
- *ppOut = buf.aBuf;
+ *ppOut = buf.aBuf;
if( pnOut ) *pnOut = buf.nBuf;
- buf.aBuf = 0;
- }
- }
- sqlite3_free(buf.aBuf);
-
- return rc;
-}
-
-/*
-** Allocate a new, empty, sqlite3_changegroup.
-*/
-SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp){
- int rc = SQLITE_OK; /* Return code */
- sqlite3_changegroup *p; /* New object */
- p = (sqlite3_changegroup*)sqlite3_malloc(sizeof(sqlite3_changegroup));
- if( p==0 ){
- rc = SQLITE_NOMEM;
- }else{
- memset(p, 0, sizeof(sqlite3_changegroup));
- }
- *pp = p;
- return rc;
-}
-
-/*
-** Add the changeset currently stored in buffer pData, size nData bytes,
-** to changeset-group p.
-*/
-SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){
- sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */
- int rc; /* Return code */
-
- rc = sqlite3changeset_start(&pIter, nData, pData);
- if( rc==SQLITE_OK ){
+ buf.aBuf = 0;
+ }
+ }
+ sqlite3_free(buf.aBuf);
+
+ return rc;
+}
+
+/*
+** Allocate a new, empty, sqlite3_changegroup.
+*/
+SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp){
+ int rc = SQLITE_OK; /* Return code */
+ sqlite3_changegroup *p; /* New object */
+ p = (sqlite3_changegroup*)sqlite3_malloc(sizeof(sqlite3_changegroup));
+ if( p==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(p, 0, sizeof(sqlite3_changegroup));
+ }
+ *pp = p;
+ return rc;
+}
+
+/*
+** Add the changeset currently stored in buffer pData, size nData bytes,
+** to changeset-group p.
+*/
+SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){
+ sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */
+ int rc; /* Return code */
+
+ rc = sqlite3changeset_start(&pIter, nData, pData);
+ if( rc==SQLITE_OK ){
rc = sessionChangesetToHash(pIter, pGrp, 0);
- }
- sqlite3changeset_finalize(pIter);
- return rc;
-}
-
-/*
-** Obtain a buffer containing a changeset representing the concatenation
-** of all changesets added to the group so far.
-*/
-SQLITE_API int sqlite3changegroup_output(
- sqlite3_changegroup *pGrp,
- int *pnData,
- void **ppData
-){
- return sessionChangegroupOutput(pGrp, 0, 0, pnData, ppData);
-}
-
-/*
-** Streaming versions of changegroup_add().
-*/
-SQLITE_API int sqlite3changegroup_add_strm(
- sqlite3_changegroup *pGrp,
- int (*xInput)(void *pIn, void *pData, int *pnData),
- void *pIn
-){
- sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */
- int rc; /* Return code */
-
- rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
- if( rc==SQLITE_OK ){
+ }
+ sqlite3changeset_finalize(pIter);
+ return rc;
+}
+
+/*
+** Obtain a buffer containing a changeset representing the concatenation
+** of all changesets added to the group so far.
+*/
+SQLITE_API int sqlite3changegroup_output(
+ sqlite3_changegroup *pGrp,
+ int *pnData,
+ void **ppData
+){
+ return sessionChangegroupOutput(pGrp, 0, 0, pnData, ppData);
+}
+
+/*
+** Streaming versions of changegroup_add().
+*/
+SQLITE_API int sqlite3changegroup_add_strm(
+ sqlite3_changegroup *pGrp,
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn
+){
+ sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */
+ int rc; /* Return code */
+
+ rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
+ if( rc==SQLITE_OK ){
rc = sessionChangesetToHash(pIter, pGrp, 0);
- }
- sqlite3changeset_finalize(pIter);
- return rc;
-}
-
-/*
-** Streaming versions of changegroup_output().
-*/
-SQLITE_API int sqlite3changegroup_output_strm(
- sqlite3_changegroup *pGrp,
+ }
+ sqlite3changeset_finalize(pIter);
+ return rc;
+}
+
+/*
+** Streaming versions of changegroup_output().
+*/
+SQLITE_API int sqlite3changegroup_output_strm(
+ sqlite3_changegroup *pGrp,
int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-){
- return sessionChangegroupOutput(pGrp, xOutput, pOut, 0, 0);
-}
-
-/*
-** Delete a changegroup object.
-*/
-SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
- if( pGrp ){
+ void *pOut
+){
+ return sessionChangegroupOutput(pGrp, xOutput, pOut, 0, 0);
+}
+
+/*
+** Delete a changegroup object.
+*/
+SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
+ if( pGrp ){
sessionDeleteTable(0, pGrp->pList);
- sqlite3_free(pGrp);
- }
-}
-
-/*
-** Combine two changesets together.
-*/
-SQLITE_API int sqlite3changeset_concat(
- int nLeft, /* Number of bytes in lhs input */
- void *pLeft, /* Lhs input changeset */
- int nRight /* Number of bytes in rhs input */,
- void *pRight, /* Rhs input changeset */
- int *pnOut, /* OUT: Number of bytes in output changeset */
- void **ppOut /* OUT: changeset (left <concat> right) */
-){
- sqlite3_changegroup *pGrp;
- int rc;
-
- rc = sqlite3changegroup_new(&pGrp);
- if( rc==SQLITE_OK ){
- rc = sqlite3changegroup_add(pGrp, nLeft, pLeft);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3changegroup_add(pGrp, nRight, pRight);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
- }
- sqlite3changegroup_delete(pGrp);
-
- return rc;
-}
-
-/*
-** Streaming version of sqlite3changeset_concat().
-*/
-SQLITE_API int sqlite3changeset_concat_strm(
- int (*xInputA)(void *pIn, void *pData, int *pnData),
- void *pInA,
- int (*xInputB)(void *pIn, void *pData, int *pnData),
- void *pInB,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-){
- sqlite3_changegroup *pGrp;
- int rc;
-
- rc = sqlite3changegroup_new(&pGrp);
- if( rc==SQLITE_OK ){
- rc = sqlite3changegroup_add_strm(pGrp, xInputA, pInA);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3changegroup_add_strm(pGrp, xInputB, pInB);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3changegroup_output_strm(pGrp, xOutput, pOut);
- }
- sqlite3changegroup_delete(pGrp);
-
- return rc;
-}
-
-/*
+ sqlite3_free(pGrp);
+ }
+}
+
+/*
+** Combine two changesets together.
+*/
+SQLITE_API int sqlite3changeset_concat(
+ int nLeft, /* Number of bytes in lhs input */
+ void *pLeft, /* Lhs input changeset */
+ int nRight /* Number of bytes in rhs input */,
+ void *pRight, /* Rhs input changeset */
+ int *pnOut, /* OUT: Number of bytes in output changeset */
+ void **ppOut /* OUT: changeset (left <concat> right) */
+){
+ sqlite3_changegroup *pGrp;
+ int rc;
+
+ rc = sqlite3changegroup_new(&pGrp);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3changegroup_add(pGrp, nLeft, pLeft);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3changegroup_add(pGrp, nRight, pRight);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
+ }
+ sqlite3changegroup_delete(pGrp);
+
+ return rc;
+}
+
+/*
+** Streaming version of sqlite3changeset_concat().
+*/
+SQLITE_API int sqlite3changeset_concat_strm(
+ int (*xInputA)(void *pIn, void *pData, int *pnData),
+ void *pInA,
+ int (*xInputB)(void *pIn, void *pData, int *pnData),
+ void *pInB,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+){
+ sqlite3_changegroup *pGrp;
+ int rc;
+
+ rc = sqlite3changegroup_new(&pGrp);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3changegroup_add_strm(pGrp, xInputA, pInA);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3changegroup_add_strm(pGrp, xInputB, pInB);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3changegroup_output_strm(pGrp, xOutput, pOut);
+ }
+ sqlite3changegroup_delete(pGrp);
+
+ return rc;
+}
+
+/*
** Changeset rebaser handle.
-*/
+*/
struct sqlite3_rebaser {
sqlite3_changegroup grp; /* Hash table */
-};
-
-/*
+};
+
+/*
** Buffers a1 and a2 must both contain a sessions module record nCol
** fields in size. This function appends an nCol sessions module
** record to buffer pBuf that is a copy of a1, except that for
** each field that is undefined in a1[], swap in the field from a2[].
-*/
+*/
static void sessionAppendRecordMerge(
SessionBuffer *pBuf, /* Buffer to append to */
int nCol, /* Number of columns in each record */
u8 *a1, int n1, /* Record 1 */
u8 *a2, int n2, /* Record 2 */
int *pRc /* IN/OUT: error code */
-){
+){
sessionBufferGrow(pBuf, n1+n2, pRc);
if( *pRc==SQLITE_OK ){
int i;
@@ -213938,26 +213938,26 @@ static void sessionAppendRecordMerge(
if( *a1==0 || *a1==0xFF ){
memcpy(pOut, a2, nn2);
pOut += nn2;
- }else{
+ }else{
memcpy(pOut, a1, nn1);
pOut += nn1;
- }
+ }
a1 += nn1;
a2 += nn2;
- }
-
+ }
+
pBuf->nBuf = pOut-pBuf->aBuf;
assert( pBuf->nBuf<=pBuf->nAlloc );
- }
-}
-
-/*
+ }
+}
+
+/*
** This function is called when rebasing a local UPDATE change against one
** or more remote UPDATE changes. The aRec/nRec buffer contains the current
** old.* and new.* records for the change. The rebase buffer (a single
** record) is in aChange/nChange. The rebased change is appended to buffer
** pBuf.
-**
+**
** Rebasing the UPDATE involves:
**
** * Removing any changes to fields for which the corresponding field
@@ -213969,14 +213969,14 @@ static void sessionAppendRecordMerge(
** corresponding field in the rebase buffer is not "undefined" (0x00)
** or "replaced" (0xFF), the old.* value is replaced by the value
** in the rebase buffer.
-*/
+*/
static void sessionAppendPartialUpdate(
SessionBuffer *pBuf, /* Append record here */
sqlite3_changeset_iter *pIter, /* Iterator pointed at local change */
u8 *aRec, int nRec, /* Local change */
u8 *aChange, int nChange, /* Record to rebase against */
int *pRc /* IN/OUT: Return Code */
-){
+){
sessionBufferGrow(pBuf, 2+nRec+nChange, pRc);
if( *pRc==SQLITE_OK ){
int bData = 0;
@@ -213984,7 +213984,7 @@ static void sessionAppendPartialUpdate(
int i;
u8 *a1 = aRec;
u8 *a2 = aChange;
-
+
*pOut++ = SQLITE_UPDATE;
*pOut++ = pIter->bIndirect;
for(i=0; i<pIter->nCol; i++){
@@ -214000,10 +214000,10 @@ static void sessionAppendPartialUpdate(
pOut += n2;
}else{
*pOut++ = '\0';
- }
+ }
a1 += n1;
a2 += n2;
- }
+ }
if( bData ){
a2 = aChange;
for(i=0; i<pIter->nCol; i++){
@@ -214014,16 +214014,16 @@ static void sessionAppendPartialUpdate(
pOut += n1;
}else{
*pOut++ = '\0';
- }
+ }
a1 += n1;
a2 += n2;
- }
+ }
pBuf->nBuf = (pOut - pBuf->aBuf);
- }
- }
-}
-
-/*
+ }
+ }
+}
+
+/*
** pIter is configured to iterate through a changeset. This function rebases
** that changeset according to the current configuration of the rebaser
** object passed as the first argument. If no error occurs and argument xOutput
@@ -214037,7 +214037,7 @@ static void sessionAppendPartialUpdate(
** If an error occurs, an SQLite error code is returned. If ppOut and
** pnOut are not NULL, then the two output parameters are set to 0 before
** returning.
-*/
+*/
static int sessionRebase(
sqlite3_rebaser *p, /* Rebaser hash table */
sqlite3_changeset_iter *pIter, /* Input data */
@@ -214045,47 +214045,47 @@ static int sessionRebase(
void *pOut, /* Context for xOutput callback */
int *pnOut, /* OUT: Number of bytes in output changeset */
void **ppOut /* OUT: Inverse of pChangeset */
-){
+){
int rc = SQLITE_OK;
u8 *aRec = 0;
int nRec = 0;
int bNew = 0;
SessionTable *pTab = 0;
SessionBuffer sOut = {0,0,0};
-
+
while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, &bNew) ){
SessionChange *pChange = 0;
int bDone = 0;
-
+
if( bNew ){
const char *zTab = pIter->zTab;
for(pTab=p->grp.pList; pTab; pTab=pTab->pNext){
if( 0==sqlite3_stricmp(pTab->zName, zTab) ) break;
- }
+ }
bNew = 0;
-
+
/* A patchset may not be rebased */
if( pIter->bPatchset ){
rc = SQLITE_ERROR;
- }
-
+ }
+
/* Append a table header to the output for this new table */
sessionAppendByte(&sOut, pIter->bPatchset ? 'P' : 'T', &rc);
sessionAppendVarint(&sOut, pIter->nCol, &rc);
sessionAppendBlob(&sOut, pIter->abPK, pIter->nCol, &rc);
sessionAppendBlob(&sOut,(u8*)pIter->zTab,(int)strlen(pIter->zTab)+1,&rc);
- }
-
+ }
+
if( pTab && rc==SQLITE_OK ){
int iHash = sessionChangeHash(pTab, 0, aRec, pTab->nChange);
-
+
for(pChange=pTab->apChange[iHash]; pChange; pChange=pChange->pNext){
if( sessionChangeEqual(pTab, 0, aRec, 0, pChange->aRecord) ){
break;
- }
- }
- }
-
+ }
+ }
+ }
+
if( pChange ){
assert( pChange->op==SQLITE_DELETE || pChange->op==SQLITE_INSERT );
switch( pIter->op ){
@@ -214100,7 +214100,7 @@ static int sessionRebase(
}
}
break;
-
+
case SQLITE_UPDATE:
bDone = 1;
if( pChange->op==SQLITE_DELETE ){
@@ -214120,7 +214120,7 @@ static int sessionRebase(
);
}
break;
-
+
default:
assert( pIter->op==SQLITE_DELETE );
bDone = 1;
@@ -214133,114 +214133,114 @@ static int sessionRebase(
}
break;
}
- }
-
+ }
+
if( bDone==0 ){
sessionAppendByte(&sOut, pIter->op, &rc);
sessionAppendByte(&sOut, pIter->bIndirect, &rc);
sessionAppendBlob(&sOut, aRec, nRec, &rc);
- }
+ }
if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
sOut.nBuf = 0;
- }
+ }
if( rc ) break;
- }
-
+ }
+
if( rc!=SQLITE_OK ){
sqlite3_free(sOut.aBuf);
memset(&sOut, 0, sizeof(sOut));
- }
-
+ }
+
if( rc==SQLITE_OK ){
if( xOutput ){
if( sOut.nBuf>0 ){
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
- }
+ }
}else if( ppOut ){
*ppOut = (void*)sOut.aBuf;
*pnOut = sOut.nBuf;
sOut.aBuf = 0;
- }
- }
+ }
+ }
sqlite3_free(sOut.aBuf);
return rc;
-}
-
+}
+
/*
** Create a new rebaser object.
-*/
+*/
SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew){
int rc = SQLITE_OK;
sqlite3_rebaser *pNew;
-
+
pNew = sqlite3_malloc(sizeof(sqlite3_rebaser));
if( pNew==0 ){
rc = SQLITE_NOMEM;
- }else{
+ }else{
memset(pNew, 0, sizeof(sqlite3_rebaser));
- }
+ }
*ppNew = pNew;
return rc;
-}
-
+}
+
/*
** Call this one or more times to configure a rebaser.
-*/
+*/
SQLITE_API int sqlite3rebaser_configure(
sqlite3_rebaser *p,
int nRebase, const void *pRebase
-){
+){
sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
int rc; /* Return code */
rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase);
if( rc==SQLITE_OK ){
rc = sessionChangesetToHash(pIter, &p->grp, 1);
- }
+ }
sqlite3changeset_finalize(pIter);
return rc;
-}
-
+}
+
/*
** Rebase a changeset according to current rebaser configuration
-*/
+*/
SQLITE_API int sqlite3rebaser_rebase(
sqlite3_rebaser *p,
int nIn, const void *pIn,
int *pnOut, void **ppOut
-){
+){
sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */
int rc = sqlite3changeset_start(&pIter, nIn, (void*)pIn);
-
+
if( rc==SQLITE_OK ){
rc = sessionRebase(p, pIter, 0, 0, pnOut, ppOut);
sqlite3changeset_finalize(pIter);
- }
-
+ }
+
return rc;
-}
-
+}
+
/*
** Rebase a changeset according to current rebaser configuration
-*/
+*/
SQLITE_API int sqlite3rebaser_rebase_strm(
sqlite3_rebaser *p,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
-){
+){
sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */
int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
-
- if( rc==SQLITE_OK ){
+
+ if( rc==SQLITE_OK ){
rc = sessionRebase(p, pIter, xOutput, pOut, 0, 0);
sqlite3changeset_finalize(pIter);
- }
-
- return rc;
-}
-
+ }
+
+ return rc;
+}
+
/*
** Destroy a rebaser object
*/
@@ -214248,12 +214248,12 @@ SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){
if( p ){
sessionDeleteTable(0, p->grp.pList);
sqlite3_free(p);
- }
-}
-
+ }
+}
+
/*
** Global configuration
-*/
+*/
SQLITE_API int sqlite3session_config(int op, void *pArg){
int rc = SQLITE_OK;
switch( op ){
@@ -214261,646 +214261,646 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){
int *pInt = (int*)pArg;
if( *pInt>0 ){
sessions_strm_chunk_size = *pInt;
- }
+ }
*pInt = sessions_strm_chunk_size;
- break;
- }
+ break;
+ }
default:
rc = SQLITE_MISUSE;
- break;
- }
- return rc;
-}
-
+ break;
+ }
+ return rc;
+}
+
#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
-
+
/************** End of sqlite3session.c **************************************/
-/************** Begin file fts5.c ********************************************/
-
-
+/************** Begin file fts5.c ********************************************/
+
+
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5)
-
+
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
-# define NDEBUG 1
-#endif
-#if defined(NDEBUG) && defined(SQLITE_DEBUG)
-# undef NDEBUG
-#endif
-
-/*
-** 2014 May 31
-**
-** 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.
-**
-******************************************************************************
-**
+# define NDEBUG 1
+#endif
+#if defined(NDEBUG) && defined(SQLITE_DEBUG)
+# undef NDEBUG
+#endif
+
+/*
+** 2014 May 31
+**
+** 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.
+**
+******************************************************************************
+**
** Interfaces to extend FTS5. Using the interfaces defined in this file,
-** FTS5 may be extended with:
-**
-** * custom tokenizers, and
-** * custom auxiliary functions.
-*/
-
-
-#ifndef _FTS5_H
-#define _FTS5_H
-
-/* #include "sqlite3.h" */
-
-#if 0
-extern "C" {
-#endif
-
-/*************************************************************************
-** CUSTOM AUXILIARY FUNCTIONS
-**
-** Virtual table implementations may overload SQL functions by implementing
-** the sqlite3_module.xFindFunction() method.
-*/
-
-typedef struct Fts5ExtensionApi Fts5ExtensionApi;
-typedef struct Fts5Context Fts5Context;
-typedef struct Fts5PhraseIter Fts5PhraseIter;
-
-typedef void (*fts5_extension_function)(
- const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
- Fts5Context *pFts, /* First arg to pass to pApi functions */
- sqlite3_context *pCtx, /* Context for returning result/error */
- int nVal, /* Number of values in apVal[] array */
- sqlite3_value **apVal /* Array of trailing arguments */
-);
-
-struct Fts5PhraseIter {
- const unsigned char *a;
- const unsigned char *b;
-};
-
-/*
-** EXTENSION API FUNCTIONS
-**
-** xUserData(pFts):
+** FTS5 may be extended with:
+**
+** * custom tokenizers, and
+** * custom auxiliary functions.
+*/
+
+
+#ifndef _FTS5_H
+#define _FTS5_H
+
+/* #include "sqlite3.h" */
+
+#if 0
+extern "C" {
+#endif
+
+/*************************************************************************
+** CUSTOM AUXILIARY FUNCTIONS
+**
+** Virtual table implementations may overload SQL functions by implementing
+** the sqlite3_module.xFindFunction() method.
+*/
+
+typedef struct Fts5ExtensionApi Fts5ExtensionApi;
+typedef struct Fts5Context Fts5Context;
+typedef struct Fts5PhraseIter Fts5PhraseIter;
+
+typedef void (*fts5_extension_function)(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+);
+
+struct Fts5PhraseIter {
+ const unsigned char *a;
+ const unsigned char *b;
+};
+
+/*
+** EXTENSION API FUNCTIONS
+**
+** xUserData(pFts):
** Return a copy of the context pointer the extension function was
-** registered with.
-**
-** xColumnTotalSize(pFts, iCol, pnToken):
-** If parameter iCol is less than zero, set output variable *pnToken
-** to the total number of tokens in the FTS5 table. Or, if iCol is
-** non-negative but less than the number of columns in the table, return
+** registered with.
+**
+** xColumnTotalSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the FTS5 table. Or, if iCol is
+** non-negative but less than the number of columns in the table, return
** the total number of tokens in column iCol, considering all rows in
-** the FTS5 table.
-**
-** If parameter iCol is greater than or equal to the number of columns
-** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** the FTS5 table.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
** an OOM condition or IO error), an appropriate SQLite error code is
-** returned.
-**
-** xColumnCount(pFts):
-** Return the number of columns in the table.
-**
-** xColumnSize(pFts, iCol, pnToken):
-** If parameter iCol is less than zero, set output variable *pnToken
-** to the total number of tokens in the current row. Or, if iCol is
-** non-negative but less than the number of columns in the table, set
-** *pnToken to the number of tokens in column iCol of the current row.
-**
-** If parameter iCol is greater than or equal to the number of columns
-** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** returned.
+**
+** xColumnCount(pFts):
+** Return the number of columns in the table.
+**
+** xColumnSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the current row. Or, if iCol is
+** non-negative but less than the number of columns in the table, set
+** *pnToken to the number of tokens in column iCol of the current row.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
** an OOM condition or IO error), an appropriate SQLite error code is
-** returned.
-**
-** This function may be quite inefficient if used with an FTS5 table
-** created with the "columnsize=0" option.
-**
-** xColumnText:
-** This function attempts to retrieve the text of column iCol of the
-** current document. If successful, (*pz) is set to point to a buffer
-** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
-** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
-** if an error occurs, an SQLite error code is returned and the final values
-** of (*pz) and (*pn) are undefined.
-**
-** xPhraseCount:
-** Returns the number of phrases in the current query expression.
-**
-** xPhraseSize:
-** Returns the number of tokens in phrase iPhrase of the query. Phrases
-** are numbered starting from zero.
-**
-** xInstCount:
-** Set *pnInst to the total number of occurrences of all phrases within
-** the query within the current row. Return SQLITE_OK if successful, or
-** an error code (i.e. SQLITE_NOMEM) if an error occurs.
-**
-** This API can be quite slow if used with an FTS5 table created with the
+** returned.
+**
+** This function may be quite inefficient if used with an FTS5 table
+** created with the "columnsize=0" option.
+**
+** xColumnText:
+** This function attempts to retrieve the text of column iCol of the
+** current document. If successful, (*pz) is set to point to a buffer
+** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
+** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
+** if an error occurs, an SQLite error code is returned and the final values
+** of (*pz) and (*pn) are undefined.
+**
+** xPhraseCount:
+** Returns the number of phrases in the current query expression.
+**
+** xPhraseSize:
+** Returns the number of tokens in phrase iPhrase of the query. Phrases
+** are numbered starting from zero.
+**
+** xInstCount:
+** Set *pnInst to the total number of occurrences of all phrases within
+** the query within the current row. Return SQLITE_OK if successful, or
+** an error code (i.e. SQLITE_NOMEM) if an error occurs.
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option. If the FTS5 table is created
** with either "detail=none" or "detail=column" and "content=" option
-** (i.e. if it is a contentless table), then this API always returns 0.
-**
-** xInst:
-** Query for the details of phrase match iIdx within the current row.
-** Phrase matches are numbered starting from zero, so the iIdx argument
-** should be greater than or equal to zero and smaller than the value
-** output by xInstCount().
-**
-** Usually, output parameter *piPhrase is set to the phrase number, *piCol
-** to the column in which it occurs and *piOff the token offset of the
+** (i.e. if it is a contentless table), then this API always returns 0.
+**
+** xInst:
+** Query for the details of phrase match iIdx within the current row.
+** Phrase matches are numbered starting from zero, so the iIdx argument
+** should be greater than or equal to zero and smaller than the value
+** output by xInstCount().
+**
+** Usually, output parameter *piPhrase is set to the phrase number, *piCol
+** to the column in which it occurs and *piOff the token offset of the
** first token of the phrase. Returns SQLITE_OK if successful, or an error
** code (i.e. SQLITE_NOMEM) if an error occurs.
-**
-** This API can be quite slow if used with an FTS5 table created with the
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
-**
-** xRowid:
-** Returns the rowid of the current row.
-**
-** xTokenize:
-** Tokenize text using the tokenizer belonging to the FTS5 table.
-**
-** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
-** This API function is used to query the FTS table for phrase iPhrase
-** of the current query. Specifically, a query equivalent to:
-**
-** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
-**
-** with $p set to a phrase equivalent to the phrase iPhrase of the
-** current query is executed. Any column filter that applies to
+**
+** xRowid:
+** Returns the rowid of the current row.
+**
+** xTokenize:
+** Tokenize text using the tokenizer belonging to the FTS5 table.
+**
+** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
+** This API function is used to query the FTS table for phrase iPhrase
+** of the current query. Specifically, a query equivalent to:
+**
+** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
+**
+** with $p set to a phrase equivalent to the phrase iPhrase of the
+** current query is executed. Any column filter that applies to
** phrase iPhrase of the current query is included in $p. For each
** row visited, the callback function passed as the fourth argument
** is invoked. The context and API objects passed to the callback
-** function may be used to access the properties of each matched row.
+** function may be used to access the properties of each matched row.
** Invoking Api.xUserData() returns a copy of the pointer passed as
-** the third argument to pUserData.
-**
-** If the callback function returns any value other than SQLITE_OK, the
-** query is abandoned and the xQueryPhrase function returns immediately.
-** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
-** Otherwise, the error code is propagated upwards.
-**
-** If the query runs to completion without incident, SQLITE_OK is returned.
-** Or, if some error occurs before the query completes or is aborted by
-** the callback, an SQLite error code is returned.
-**
-**
-** xSetAuxdata(pFts5, pAux, xDelete)
-**
+** the third argument to pUserData.
+**
+** If the callback function returns any value other than SQLITE_OK, the
+** query is abandoned and the xQueryPhrase function returns immediately.
+** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
+** Otherwise, the error code is propagated upwards.
+**
+** If the query runs to completion without incident, SQLITE_OK is returned.
+** Or, if some error occurs before the query completes or is aborted by
+** the callback, an SQLite error code is returned.
+**
+**
+** xSetAuxdata(pFts5, pAux, xDelete)
+**
** Save the pointer passed as the second argument as the extension function's
-** "auxiliary data". The pointer may then be retrieved by the current or any
-** future invocation of the same fts5 extension function made as part of
+** "auxiliary data". The pointer may then be retrieved by the current or any
+** future invocation of the same fts5 extension function made as part of
** the same MATCH query using the xGetAuxdata() API.
-**
-** Each extension function is allocated a single auxiliary data slot for
+**
+** Each extension function is allocated a single auxiliary data slot for
** each FTS query (MATCH expression). If the extension function is invoked
** more than once for a single FTS query, then all invocations share a
-** single auxiliary data context.
-**
-** If there is already an auxiliary data pointer when this function is
-** invoked, then it is replaced by the new pointer. If an xDelete callback
-** was specified along with the original pointer, it is invoked at this
-** point.
-**
-** The xDelete callback, if one is specified, is also invoked on the
-** auxiliary data pointer after the FTS5 query has finished.
-**
+** single auxiliary data context.
+**
+** If there is already an auxiliary data pointer when this function is
+** invoked, then it is replaced by the new pointer. If an xDelete callback
+** was specified along with the original pointer, it is invoked at this
+** point.
+**
+** The xDelete callback, if one is specified, is also invoked on the
+** auxiliary data pointer after the FTS5 query has finished.
+**
** If an error (e.g. an OOM condition) occurs within this function,
-** the auxiliary data is set to NULL and an error code returned. If the
-** xDelete parameter was not NULL, it is invoked on the auxiliary data
-** pointer before returning.
-**
-**
-** xGetAuxdata(pFts5, bClear)
-**
+** the auxiliary data is set to NULL and an error code returned. If the
+** xDelete parameter was not NULL, it is invoked on the auxiliary data
+** pointer before returning.
+**
+**
+** xGetAuxdata(pFts5, bClear)
+**
** Returns the current auxiliary data pointer for the fts5 extension
-** function. See the xSetAuxdata() method for details.
-**
-** If the bClear argument is non-zero, then the auxiliary data is cleared
-** (set to NULL) before this function returns. In this case the xDelete,
-** if any, is not invoked.
-**
-**
-** xRowCount(pFts5, pnRow)
-**
-** This function is used to retrieve the total number of rows in the table.
-** In other words, the same value that would be returned by:
-**
-** SELECT count(*) FROM ftstable;
-**
-** xPhraseFirst()
-** This function is used, along with type Fts5PhraseIter and the xPhraseNext
-** method, to iterate through all instances of a single query phrase within
-** the current row. This is the same information as is accessible via the
-** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
+** function. See the xSetAuxdata() method for details.
+**
+** If the bClear argument is non-zero, then the auxiliary data is cleared
+** (set to NULL) before this function returns. In this case the xDelete,
+** if any, is not invoked.
+**
+**
+** xRowCount(pFts5, pnRow)
+**
+** This function is used to retrieve the total number of rows in the table.
+** In other words, the same value that would be returned by:
+**
+** SELECT count(*) FROM ftstable;
+**
+** xPhraseFirst()
+** This function is used, along with type Fts5PhraseIter and the xPhraseNext
+** method, to iterate through all instances of a single query phrase within
+** the current row. This is the same information as is accessible via the
+** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
** to use, this API may be faster under some circumstances. To iterate
-** through instances of phrase iPhrase, use the following code:
-**
-** Fts5PhraseIter iter;
-** int iCol, iOff;
-** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
-** iCol>=0;
-** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
-** ){
-** // An instance of phrase iPhrase at offset iOff of column iCol
-** }
-**
-** The Fts5PhraseIter structure is defined above. Applications should not
-** modify this structure directly - it should only be used as shown above
-** with the xPhraseFirst() and xPhraseNext() API methods (and by
-** xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
-**
-** This API can be quite slow if used with an FTS5 table created with the
+** through instances of phrase iPhrase, use the following code:
+**
+** Fts5PhraseIter iter;
+** int iCol, iOff;
+** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
+** iCol>=0;
+** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
+** ){
+** // An instance of phrase iPhrase at offset iOff of column iCol
+** }
+**
+** The Fts5PhraseIter structure is defined above. Applications should not
+** modify this structure directly - it should only be used as shown above
+** with the xPhraseFirst() and xPhraseNext() API methods (and by
+** xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option. If the FTS5 table is created
** with either "detail=none" or "detail=column" and "content=" option
-** (i.e. if it is a contentless table), then this API always iterates
-** through an empty set (all calls to xPhraseFirst() set iCol to -1).
-**
-** xPhraseNext()
-** See xPhraseFirst above.
-**
-** xPhraseFirstColumn()
-** This function and xPhraseNextColumn() are similar to the xPhraseFirst()
-** and xPhraseNext() APIs described above. The difference is that instead
-** of iterating through all instances of a phrase in the current row, these
-** APIs are used to iterate through the set of columns in the current row
-** that contain one or more instances of a specified phrase. For example:
-**
-** Fts5PhraseIter iter;
-** int iCol;
-** for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
-** iCol>=0;
-** pApi->xPhraseNextColumn(pFts, &iter, &iCol)
-** ){
-** // Column iCol contains at least one instance of phrase iPhrase
-** }
-**
-** This API can be quite slow if used with an FTS5 table created with the
+** (i.e. if it is a contentless table), then this API always iterates
+** through an empty set (all calls to xPhraseFirst() set iCol to -1).
+**
+** xPhraseNext()
+** See xPhraseFirst above.
+**
+** xPhraseFirstColumn()
+** This function and xPhraseNextColumn() are similar to the xPhraseFirst()
+** and xPhraseNext() APIs described above. The difference is that instead
+** of iterating through all instances of a phrase in the current row, these
+** APIs are used to iterate through the set of columns in the current row
+** that contain one or more instances of a specified phrase. For example:
+**
+** Fts5PhraseIter iter;
+** int iCol;
+** for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
+** iCol>=0;
+** pApi->xPhraseNextColumn(pFts, &iter, &iCol)
+** ){
+** // Column iCol contains at least one instance of phrase iPhrase
+** }
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" option. If the FTS5 table is created with either
** "detail=none" "content=" option (i.e. if it is a contentless table),
** then this API always iterates through an empty set (all calls to
-** xPhraseFirstColumn() set iCol to -1).
-**
-** The information accessed using this API and its companion
-** xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
-** (or xInst/xInstCount). The chief advantage of this API is that it is
-** significantly more efficient than those alternatives when used with
+** xPhraseFirstColumn() set iCol to -1).
+**
+** The information accessed using this API and its companion
+** xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
+** (or xInst/xInstCount). The chief advantage of this API is that it is
+** significantly more efficient than those alternatives when used with
** "detail=column" tables.
-**
-** xPhraseNextColumn()
-** See xPhraseFirstColumn above.
-*/
-struct Fts5ExtensionApi {
- int iVersion; /* Currently always set to 3 */
-
- void *(*xUserData)(Fts5Context*);
-
- int (*xColumnCount)(Fts5Context*);
- int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
- int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
-
+**
+** xPhraseNextColumn()
+** See xPhraseFirstColumn above.
+*/
+struct Fts5ExtensionApi {
+ int iVersion; /* Currently always set to 3 */
+
+ void *(*xUserData)(Fts5Context*);
+
+ int (*xColumnCount)(Fts5Context*);
+ int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
+ int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
+
int (*xTokenize)(Fts5Context*,
- const char *pText, int nText, /* Text to tokenize */
- void *pCtx, /* Context passed to xToken() */
- int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
- );
-
- int (*xPhraseCount)(Fts5Context*);
- int (*xPhraseSize)(Fts5Context*, int iPhrase);
-
- int (*xInstCount)(Fts5Context*, int *pnInst);
- int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
-
- sqlite3_int64 (*xRowid)(Fts5Context*);
- int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
- int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
-
- int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
- int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
- );
- int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
- void *(*xGetAuxdata)(Fts5Context*, int bClear);
-
- int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
- void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
-
- int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
- void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
-};
-
-/*
-** CUSTOM AUXILIARY FUNCTIONS
-*************************************************************************/
-
-/*************************************************************************
-** CUSTOM TOKENIZERS
-**
+ const char *pText, int nText, /* Text to tokenize */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+ );
+
+ int (*xPhraseCount)(Fts5Context*);
+ int (*xPhraseSize)(Fts5Context*, int iPhrase);
+
+ int (*xInstCount)(Fts5Context*, int *pnInst);
+ int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
+
+ sqlite3_int64 (*xRowid)(Fts5Context*);
+ int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
+ int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
+
+ int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
+ int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
+ );
+ int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
+ void *(*xGetAuxdata)(Fts5Context*, int bClear);
+
+ int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
+ void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
+
+ int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
+ void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
+};
+
+/*
+** CUSTOM AUXILIARY FUNCTIONS
+*************************************************************************/
+
+/*************************************************************************
+** CUSTOM TOKENIZERS
+**
** Applications may also register custom tokenizer types. A tokenizer
** is registered by providing fts5 with a populated instance of the
-** following structure. All structure methods must be defined, setting
-** any member of the fts5_tokenizer struct to NULL leads to undefined
-** behaviour. The structure methods are expected to function as follows:
-**
-** xCreate:
-** This function is used to allocate and initialize a tokenizer instance.
-** A tokenizer instance is required to actually tokenize text.
-**
-** The first argument passed to this function is a copy of the (void*)
-** pointer provided by the application when the fts5_tokenizer object
+** following structure. All structure methods must be defined, setting
+** any member of the fts5_tokenizer struct to NULL leads to undefined
+** behaviour. The structure methods are expected to function as follows:
+**
+** xCreate:
+** This function is used to allocate and initialize a tokenizer instance.
+** A tokenizer instance is required to actually tokenize text.
+**
+** The first argument passed to this function is a copy of the (void*)
+** pointer provided by the application when the fts5_tokenizer object
** was registered with FTS5 (the third argument to xCreateTokenizer()).
-** The second and third arguments are an array of nul-terminated strings
-** containing the tokenizer arguments, if any, specified following the
-** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
-** to create the FTS5 table.
-**
+** The second and third arguments are an array of nul-terminated strings
+** containing the tokenizer arguments, if any, specified following the
+** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
+** to create the FTS5 table.
+**
** The final argument is an output variable. If successful, (*ppOut)
-** should be set to point to the new tokenizer handle and SQLITE_OK
-** returned. If an error occurs, some value other than SQLITE_OK should
+** should be set to point to the new tokenizer handle and SQLITE_OK
+** returned. If an error occurs, some value other than SQLITE_OK should
** be returned. In this case, fts5 assumes that the final value of *ppOut
-** is undefined.
-**
-** xDelete:
-** This function is invoked to delete a tokenizer handle previously
-** allocated using xCreate(). Fts5 guarantees that this function will
-** be invoked exactly once for each successful call to xCreate().
-**
-** xTokenize:
+** is undefined.
+**
+** xDelete:
+** This function is invoked to delete a tokenizer handle previously
+** allocated using xCreate(). Fts5 guarantees that this function will
+** be invoked exactly once for each successful call to xCreate().
+**
+** xTokenize:
** This function is expected to tokenize the nText byte string indicated
-** by argument pText. pText may or may not be nul-terminated. The first
-** argument passed to this function is a pointer to an Fts5Tokenizer object
-** returned by an earlier call to xCreate().
-**
-** The second argument indicates the reason that FTS5 is requesting
-** tokenization of the supplied text. This is always one of the following
-** four values:
-**
-** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
-** or removed from the FTS table. The tokenizer is being invoked to
-** determine the set of tokens to add to (or delete from) the
-** FTS index.
-**
+** by argument pText. pText may or may not be nul-terminated. The first
+** argument passed to this function is a pointer to an Fts5Tokenizer object
+** returned by an earlier call to xCreate().
+**
+** The second argument indicates the reason that FTS5 is requesting
+** tokenization of the supplied text. This is always one of the following
+** four values:
+**
+** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
+** or removed from the FTS table. The tokenizer is being invoked to
+** determine the set of tokens to add to (or delete from) the
+** FTS index.
+**
** <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed
** against the FTS index. The tokenizer is being called to tokenize
-** a bareword or quoted string specified as part of the query.
-**
-** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
-** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
-** followed by a "*" character, indicating that the last token
-** returned by the tokenizer will be treated as a token prefix.
-**
+** a bareword or quoted string specified as part of the query.
+**
+** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
+** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
+** followed by a "*" character, indicating that the last token
+** returned by the tokenizer will be treated as a token prefix.
+**
** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
-** satisfy an fts5_api.xTokenize() request made by an auxiliary
-** function. Or an fts5_api.xColumnSize() request made by the same
+** satisfy an fts5_api.xTokenize() request made by an auxiliary
+** function. Or an fts5_api.xColumnSize() request made by the same
** on a columnsize=0 database.
-** </ul>
-**
-** For each token in the input string, the supplied callback xToken() must
-** be invoked. The first argument to it should be a copy of the pointer
-** passed as the second argument to xTokenize(). The third and fourth
-** arguments are a pointer to a buffer containing the token text, and the
-** size of the token in bytes. The 4th and 5th arguments are the byte offsets
-** of the first byte of and first byte immediately following the text from
-** which the token is derived within the input.
-**
-** The second argument passed to the xToken() callback ("tflags") should
+** </ul>
+**
+** For each token in the input string, the supplied callback xToken() must
+** be invoked. The first argument to it should be a copy of the pointer
+** passed as the second argument to xTokenize(). The third and fourth
+** arguments are a pointer to a buffer containing the token text, and the
+** size of the token in bytes. The 4th and 5th arguments are the byte offsets
+** of the first byte of and first byte immediately following the text from
+** which the token is derived within the input.
+**
+** The second argument passed to the xToken() callback ("tflags") should
** normally be set to 0. The exception is if the tokenizer supports
-** synonyms. In this case see the discussion below for details.
-**
+** synonyms. In this case see the discussion below for details.
+**
** FTS5 assumes the xToken() callback is invoked for each token in the
-** order that they occur within the input text.
-**
-** If an xToken() callback returns any value other than SQLITE_OK, then
-** the tokenization should be abandoned and the xTokenize() method should
-** immediately return a copy of the xToken() return value. Or, if the
-** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
-** if an error occurs with the xTokenize() implementation itself, it
-** may abandon the tokenization and return any error code other than
-** SQLITE_OK or SQLITE_DONE.
-**
-** SYNONYM SUPPORT
-**
-** Custom tokenizers may also support synonyms. Consider a case in which a
+** order that they occur within the input text.
+**
+** If an xToken() callback returns any value other than SQLITE_OK, then
+** the tokenization should be abandoned and the xTokenize() method should
+** immediately return a copy of the xToken() return value. Or, if the
+** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
+** if an error occurs with the xTokenize() implementation itself, it
+** may abandon the tokenization and return any error code other than
+** SQLITE_OK or SQLITE_DONE.
+**
+** SYNONYM SUPPORT
+**
+** Custom tokenizers may also support synonyms. Consider a case in which a
** user wishes to query for a phrase such as "first place". Using the
-** built-in tokenizers, the FTS5 query 'first + place' will match instances
-** of "first place" within the document set, but not alternative forms
-** such as "1st place". In some applications, it would be better to match
-** all instances of "first place" or "1st place" regardless of which form
-** the user specified in the MATCH query text.
-**
-** There are several ways to approach this in FTS5:
-**
+** built-in tokenizers, the FTS5 query 'first + place' will match instances
+** of "first place" within the document set, but not alternative forms
+** such as "1st place". In some applications, it would be better to match
+** all instances of "first place" or "1st place" regardless of which form
+** the user specified in the MATCH query text.
+**
+** There are several ways to approach this in FTS5:
+**
** <ol><li> By mapping all synonyms to a single token. In this case, using
** the above example, this means that the tokenizer returns the
-** same token for inputs "first" and "1st". Say that token is in
-** fact "first", so that when the user inserts the document "I won
-** 1st place" entries are added to the index for tokens "i", "won",
-** "first" and "place". If the user then queries for '1st + place',
-** the tokenizer substitutes "first" for "1st" and the query works
-** as expected.
-**
+** same token for inputs "first" and "1st". Say that token is in
+** fact "first", so that when the user inserts the document "I won
+** 1st place" entries are added to the index for tokens "i", "won",
+** "first" and "place". If the user then queries for '1st + place',
+** the tokenizer substitutes "first" for "1st" and the query works
+** as expected.
+**
** <li> By querying the index for all synonyms of each query term
** separately. In this case, when tokenizing query text, the
** tokenizer may provide multiple synonyms for a single term
** within the document. FTS5 then queries the index for each
** synonym individually. For example, faced with the query:
-**
-** <codeblock>
-** ... MATCH 'first place'</codeblock>
-**
-** the tokenizer offers both "1st" and "first" as synonyms for the
+**
+** <codeblock>
+** ... MATCH 'first place'</codeblock>
+**
+** the tokenizer offers both "1st" and "first" as synonyms for the
** first token in the MATCH query and FTS5 effectively runs a query
-** similar to:
-**
-** <codeblock>
-** ... MATCH '(first OR 1st) place'</codeblock>
-**
-** except that, for the purposes of auxiliary functions, the query
+** similar to:
+**
+** <codeblock>
+** ... MATCH '(first OR 1st) place'</codeblock>
+**
+** except that, for the purposes of auxiliary functions, the query
** still appears to contain just two phrases - "(first OR 1st)"
-** being treated as a single phrase.
-**
-** <li> By adding multiple synonyms for a single term to the FTS index.
-** Using this method, when tokenizing document text, the tokenizer
+** being treated as a single phrase.
+**
+** <li> By adding multiple synonyms for a single term to the FTS index.
+** Using this method, when tokenizing document text, the tokenizer
** provides multiple synonyms for each token. So that when a
-** document such as "I won first place" is tokenized, entries are
-** added to the FTS index for "i", "won", "first", "1st" and
-** "place".
-**
-** This way, even if the tokenizer does not provide synonyms
+** document such as "I won first place" is tokenized, entries are
+** added to the FTS index for "i", "won", "first", "1st" and
+** "place".
+**
+** This way, even if the tokenizer does not provide synonyms
** when tokenizing query text (it should not - to do so would be
** inefficient), it doesn't matter if the user queries for
** 'first + place' or '1st + place', as there are entries in the
-** FTS index corresponding to both forms of the first token.
-** </ol>
-**
-** Whether it is parsing document or query text, any call to xToken that
-** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
-** is considered to supply a synonym for the previous token. For example,
-** when parsing the document "I won first place", a tokenizer that supports
-** synonyms would call xToken() 5 times, as follows:
-**
-** <codeblock>
-** xToken(pCtx, 0, "i", 1, 0, 1);
-** xToken(pCtx, 0, "won", 3, 2, 5);
-** xToken(pCtx, 0, "first", 5, 6, 11);
-** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
-** xToken(pCtx, 0, "place", 5, 12, 17);
-**</codeblock>
-**
-** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
-** xToken() is called. Multiple synonyms may be specified for a single token
+** FTS index corresponding to both forms of the first token.
+** </ol>
+**
+** Whether it is parsing document or query text, any call to xToken that
+** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
+** is considered to supply a synonym for the previous token. For example,
+** when parsing the document "I won first place", a tokenizer that supports
+** synonyms would call xToken() 5 times, as follows:
+**
+** <codeblock>
+** xToken(pCtx, 0, "i", 1, 0, 1);
+** xToken(pCtx, 0, "won", 3, 2, 5);
+** xToken(pCtx, 0, "first", 5, 6, 11);
+** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
+** xToken(pCtx, 0, "place", 5, 12, 17);
+**</codeblock>
+**
+** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
+** xToken() is called. Multiple synonyms may be specified for a single token
** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence.
-** There is no limit to the number of synonyms that may be provided for a
-** single token.
-**
+** There is no limit to the number of synonyms that may be provided for a
+** single token.
+**
** In many cases, method (1) above is the best approach. It does not add
-** extra data to the FTS index or require FTS5 to query for multiple terms,
-** so it is efficient in terms of disk space and query speed. However, it
-** does not support prefix queries very well. If, as suggested above, the
+** extra data to the FTS index or require FTS5 to query for multiple terms,
+** so it is efficient in terms of disk space and query speed. However, it
+** does not support prefix queries very well. If, as suggested above, the
** token "first" is substituted for "1st" by the tokenizer, then the query:
-**
-** <codeblock>
-** ... MATCH '1s*'</codeblock>
-**
-** will not match documents that contain the token "1st" (as the tokenizer
-** will probably not map "1s" to any prefix of "first").
-**
+**
+** <codeblock>
+** ... MATCH '1s*'</codeblock>
+**
+** will not match documents that contain the token "1st" (as the tokenizer
+** will probably not map "1s" to any prefix of "first").
+**
** For full prefix support, method (3) may be preferred. In this case,
-** because the index contains entries for both "first" and "1st", prefix
-** queries such as 'fi*' or '1s*' will match correctly. However, because
-** extra entries are added to the FTS index, this method uses more space
-** within the database.
-**
-** Method (2) offers a midpoint between (1) and (3). Using this method,
+** because the index contains entries for both "first" and "1st", prefix
+** queries such as 'fi*' or '1s*' will match correctly. However, because
+** extra entries are added to the FTS index, this method uses more space
+** within the database.
+**
+** Method (2) offers a midpoint between (1) and (3). Using this method,
** a query such as '1s*' will match documents that contain the literal
-** token "1st", but not "first" (assuming the tokenizer is not able to
-** provide synonyms for prefixes). However, a non-prefix query like '1st'
-** will match against "1st" and "first". This method does not require
+** token "1st", but not "first" (assuming the tokenizer is not able to
+** provide synonyms for prefixes). However, a non-prefix query like '1st'
+** will match against "1st" and "first". This method does not require
** extra disk space, as no extra entries are added to the FTS index.
-** On the other hand, it may require more CPU cycles to run MATCH queries,
-** as separate queries of the FTS index are required for each synonym.
-**
-** When using methods (2) or (3), it is important that the tokenizer only
-** provide synonyms when tokenizing document text (method (2)) or query
-** text (method (3)), not both. Doing so will not cause any errors, but is
-** inefficient.
-*/
-typedef struct Fts5Tokenizer Fts5Tokenizer;
-typedef struct fts5_tokenizer fts5_tokenizer;
-struct fts5_tokenizer {
- int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
- void (*xDelete)(Fts5Tokenizer*);
+** On the other hand, it may require more CPU cycles to run MATCH queries,
+** as separate queries of the FTS index are required for each synonym.
+**
+** When using methods (2) or (3), it is important that the tokenizer only
+** provide synonyms when tokenizing document text (method (2)) or query
+** text (method (3)), not both. Doing so will not cause any errors, but is
+** inefficient.
+*/
+typedef struct Fts5Tokenizer Fts5Tokenizer;
+typedef struct fts5_tokenizer fts5_tokenizer;
+struct fts5_tokenizer {
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
+ void (*xDelete)(Fts5Tokenizer*);
int (*xTokenize)(Fts5Tokenizer*,
- void *pCtx,
- int flags, /* Mask of FTS5_TOKENIZE_* flags */
+ void *pCtx,
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
const char *pText, int nText,
- int (*xToken)(
- void *pCtx, /* Copy of 2nd argument to xTokenize() */
- int tflags, /* Mask of FTS5_TOKEN_* flags */
- const char *pToken, /* Pointer to buffer containing token */
- int nToken, /* Size of token in bytes */
- int iStart, /* Byte offset of token within input text */
- int iEnd /* Byte offset of end of token within input text */
- )
- );
-};
-
-/* Flags that may be passed as the third argument to xTokenize() */
-#define FTS5_TOKENIZE_QUERY 0x0001
-#define FTS5_TOKENIZE_PREFIX 0x0002
-#define FTS5_TOKENIZE_DOCUMENT 0x0004
-#define FTS5_TOKENIZE_AUX 0x0008
-
-/* Flags that may be passed by the tokenizer implementation back to FTS5
-** as the third argument to the supplied xToken callback. */
-#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
-
-/*
-** END OF CUSTOM TOKENIZERS
-*************************************************************************/
-
-/*************************************************************************
-** FTS5 EXTENSION REGISTRATION API
-*/
-typedef struct fts5_api fts5_api;
-struct fts5_api {
- int iVersion; /* Currently always set to 2 */
-
- /* Create a new tokenizer */
- int (*xCreateTokenizer)(
- fts5_api *pApi,
- const char *zName,
- void *pContext,
- fts5_tokenizer *pTokenizer,
- void (*xDestroy)(void*)
- );
-
- /* Find an existing tokenizer */
- int (*xFindTokenizer)(
- fts5_api *pApi,
- const char *zName,
- void **ppContext,
- fts5_tokenizer *pTokenizer
- );
-
- /* Create a new auxiliary function */
- int (*xCreateFunction)(
- fts5_api *pApi,
- const char *zName,
- void *pContext,
- fts5_extension_function xFunction,
- void (*xDestroy)(void*)
- );
-};
-
-/*
-** END OF REGISTRATION API
-*************************************************************************/
-
-#if 0
-} /* end of the 'extern "C"' block */
-#endif
-
-#endif /* _FTS5_H */
-
-/*
-** 2014 May 31
-**
-** 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.
-**
-******************************************************************************
-**
-*/
-#ifndef _FTS5INT_H
-#define _FTS5INT_H
-
-/* #include "fts5.h" */
-/* #include "sqlite3ext.h" */
-SQLITE_EXTENSION_INIT1
-
-/* #include <string.h> */
-/* #include <assert.h> */
-
-#ifndef SQLITE_AMALGAMATION
-
-typedef unsigned char u8;
-typedef unsigned int u32;
-typedef unsigned short u16;
-typedef short i16;
-typedef sqlite3_int64 i64;
-typedef sqlite3_uint64 u64;
-
-#ifndef ArraySize
-# define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
-#endif
-
-#define testcase(x)
-
+ int (*xToken)(
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Pointer to buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Byte offset of token within input text */
+ int iEnd /* Byte offset of end of token within input text */
+ )
+ );
+};
+
+/* Flags that may be passed as the third argument to xTokenize() */
+#define FTS5_TOKENIZE_QUERY 0x0001
+#define FTS5_TOKENIZE_PREFIX 0x0002
+#define FTS5_TOKENIZE_DOCUMENT 0x0004
+#define FTS5_TOKENIZE_AUX 0x0008
+
+/* Flags that may be passed by the tokenizer implementation back to FTS5
+** as the third argument to the supplied xToken callback. */
+#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
+
+/*
+** END OF CUSTOM TOKENIZERS
+*************************************************************************/
+
+/*************************************************************************
+** FTS5 EXTENSION REGISTRATION API
+*/
+typedef struct fts5_api fts5_api;
+struct fts5_api {
+ int iVersion; /* Currently always set to 2 */
+
+ /* Create a new tokenizer */
+ int (*xCreateTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_tokenizer *pTokenizer,
+ void (*xDestroy)(void*)
+ );
+
+ /* Find an existing tokenizer */
+ int (*xFindTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void **ppContext,
+ fts5_tokenizer *pTokenizer
+ );
+
+ /* Create a new auxiliary function */
+ int (*xCreateFunction)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_extension_function xFunction,
+ void (*xDestroy)(void*)
+ );
+};
+
+/*
+** END OF REGISTRATION API
+*************************************************************************/
+
+#if 0
+} /* end of the 'extern "C"' block */
+#endif
+
+#endif /* _FTS5_H */
+
+/*
+** 2014 May 31
+**
+** 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.
+**
+******************************************************************************
+**
+*/
+#ifndef _FTS5INT_H
+#define _FTS5INT_H
+
+/* #include "fts5.h" */
+/* #include "sqlite3ext.h" */
+SQLITE_EXTENSION_INIT1
+
+/* #include <string.h> */
+/* #include <assert.h> */
+
+#ifndef SQLITE_AMALGAMATION
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+typedef unsigned short u16;
+typedef short i16;
+typedef sqlite3_int64 i64;
+typedef sqlite3_uint64 u64;
+
+#ifndef ArraySize
+# define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
+#endif
+
+#define testcase(x)
+
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
#endif
@@ -214915,514 +214915,514 @@ typedef sqlite3_uint64 u64;
# define NEVER(X) (X)
#endif
-#define MIN(x,y) (((x) < (y)) ? (x) : (y))
-#define MAX(x,y) (((x) > (y)) ? (x) : (y))
-
-/*
-** Constants for the largest and smallest possible 64-bit signed integers.
-*/
-# define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
-# define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
-
-#endif
-
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+#define MAX(x,y) (((x) > (y)) ? (x) : (y))
+
+/*
+** Constants for the largest and smallest possible 64-bit signed integers.
+*/
+# define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
+# define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
+
+#endif
+
/* Truncate very long tokens to this many bytes. Hard limit is
-** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
-** field that occurs at the start of each leaf page (see fts5_index.c). */
-#define FTS5_MAX_TOKEN_SIZE 32768
-
-/*
-** Maximum number of prefix indexes on single FTS5 table. This must be
-** less than 32. If it is set to anything large than that, an #error
-** directive in fts5_index.c will cause the build to fail.
-*/
-#define FTS5_MAX_PREFIX_INDEXES 31
-
+** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
+** field that occurs at the start of each leaf page (see fts5_index.c). */
+#define FTS5_MAX_TOKEN_SIZE 32768
+
+/*
+** Maximum number of prefix indexes on single FTS5 table. This must be
+** less than 32. If it is set to anything large than that, an #error
+** directive in fts5_index.c will cause the build to fail.
+*/
+#define FTS5_MAX_PREFIX_INDEXES 31
+
/*
** Maximum segments permitted in a single index
*/
#define FTS5_MAX_SEGMENT 2000
-#define FTS5_DEFAULT_NEARDIST 10
-#define FTS5_DEFAULT_RANK "bm25"
-
-/* Name of rank and rowid columns */
-#define FTS5_RANK_NAME "rank"
-#define FTS5_ROWID_NAME "rowid"
-
-#ifdef SQLITE_DEBUG
-# define FTS5_CORRUPT sqlite3Fts5Corrupt()
-static int sqlite3Fts5Corrupt(void);
-#else
-# define FTS5_CORRUPT SQLITE_CORRUPT_VTAB
-#endif
-
-/*
-** The assert_nc() macro is similar to the assert() macro, except that it
+#define FTS5_DEFAULT_NEARDIST 10
+#define FTS5_DEFAULT_RANK "bm25"
+
+/* Name of rank and rowid columns */
+#define FTS5_RANK_NAME "rank"
+#define FTS5_ROWID_NAME "rowid"
+
+#ifdef SQLITE_DEBUG
+# define FTS5_CORRUPT sqlite3Fts5Corrupt()
+static int sqlite3Fts5Corrupt(void);
+#else
+# define FTS5_CORRUPT SQLITE_CORRUPT_VTAB
+#endif
+
+/*
+** The assert_nc() macro is similar to the assert() macro, except that it
** is used for assert() conditions that are true only if it can be
-** guranteed that the database is not corrupt.
-*/
-#ifdef SQLITE_DEBUG
-SQLITE_API extern int sqlite3_fts5_may_be_corrupt;
-# define assert_nc(x) assert(sqlite3_fts5_may_be_corrupt || (x))
-#else
-# define assert_nc(x) assert(x)
-#endif
-
+** guranteed that the database is not corrupt.
+*/
+#ifdef SQLITE_DEBUG
+SQLITE_API extern int sqlite3_fts5_may_be_corrupt;
+# define assert_nc(x) assert(sqlite3_fts5_may_be_corrupt || (x))
+#else
+# define assert_nc(x) assert(x)
+#endif
+
/*
** A version of memcmp() that does not cause asan errors if one of the pointer
** parameters is NULL and the number of bytes to compare is zero.
*/
#define fts5Memcmp(s1, s2, n) ((n)<=0 ? 0 : memcmp((s1), (s2), (n)))
-/* Mark a function parameter as unused, to suppress nuisance compiler
-** warnings. */
-#ifndef UNUSED_PARAM
-# define UNUSED_PARAM(X) (void)(X)
-#endif
-
-#ifndef UNUSED_PARAM2
-# define UNUSED_PARAM2(X, Y) (void)(X), (void)(Y)
-#endif
-
-typedef struct Fts5Global Fts5Global;
-typedef struct Fts5Colset Fts5Colset;
-
+/* Mark a function parameter as unused, to suppress nuisance compiler
+** warnings. */
+#ifndef UNUSED_PARAM
+# define UNUSED_PARAM(X) (void)(X)
+#endif
+
+#ifndef UNUSED_PARAM2
+# define UNUSED_PARAM2(X, Y) (void)(X), (void)(Y)
+#endif
+
+typedef struct Fts5Global Fts5Global;
+typedef struct Fts5Colset Fts5Colset;
+
/* If a NEAR() clump or phrase may only match a specific set of columns,
-** then an object of the following type is used to record the set of columns.
-** Each entry in the aiCol[] array is a column that may be matched.
-**
-** This object is used by fts5_expr.c and fts5_index.c.
-*/
-struct Fts5Colset {
- int nCol;
- int aiCol[1];
-};
-
-
-
-/**************************************************************************
-** Interface to code in fts5_config.c. fts5_config.c contains contains code
-** to parse the arguments passed to the CREATE VIRTUAL TABLE statement.
-*/
-
-typedef struct Fts5Config Fts5Config;
-
-/*
-** An instance of the following structure encodes all information that can
-** be gleaned from the CREATE VIRTUAL TABLE statement.
-**
-** And all information loaded from the %_config table.
-**
-** nAutomerge:
-** The minimum number of segments that an auto-merge operation should
+** then an object of the following type is used to record the set of columns.
+** Each entry in the aiCol[] array is a column that may be matched.
+**
+** This object is used by fts5_expr.c and fts5_index.c.
+*/
+struct Fts5Colset {
+ int nCol;
+ int aiCol[1];
+};
+
+
+
+/**************************************************************************
+** Interface to code in fts5_config.c. fts5_config.c contains contains code
+** to parse the arguments passed to the CREATE VIRTUAL TABLE statement.
+*/
+
+typedef struct Fts5Config Fts5Config;
+
+/*
+** An instance of the following structure encodes all information that can
+** be gleaned from the CREATE VIRTUAL TABLE statement.
+**
+** And all information loaded from the %_config table.
+**
+** nAutomerge:
+** The minimum number of segments that an auto-merge operation should
** attempt to merge together. A value of 1 sets the object to use the
-** compile time default. Zero disables auto-merge altogether.
-**
-** zContent:
-**
-** zContentRowid:
+** compile time default. Zero disables auto-merge altogether.
+**
+** zContent:
+**
+** zContentRowid:
** The value of the content_rowid= option, if one was specified. Or
-** the string "rowid" otherwise. This text is not quoted - if it is
-** used as part of an SQL statement it needs to be quoted appropriately.
-**
-** zContentExprlist:
-**
-** pzErrmsg:
+** the string "rowid" otherwise. This text is not quoted - if it is
+** used as part of an SQL statement it needs to be quoted appropriately.
+**
+** zContentExprlist:
+**
+** pzErrmsg:
** This exists in order to allow the fts5_index.c module to return a
-** decent error message if it encounters a file-format version it does
-** not understand.
-**
-** bColumnsize:
-** True if the %_docsize table is created.
-**
-** bPrefixIndex:
-** This is only used for debugging. If set to false, any prefix indexes
-** are ignored. This value is configured using:
-**
-** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex);
-**
-*/
-struct Fts5Config {
- sqlite3 *db; /* Database handle */
- char *zDb; /* Database holding FTS index (e.g. "main") */
- char *zName; /* Name of FTS index */
- int nCol; /* Number of columns */
- char **azCol; /* Column names */
- u8 *abUnindexed; /* True for unindexed columns */
- int nPrefix; /* Number of prefix indexes */
- int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */
- int eContent; /* An FTS5_CONTENT value */
+** decent error message if it encounters a file-format version it does
+** not understand.
+**
+** bColumnsize:
+** True if the %_docsize table is created.
+**
+** bPrefixIndex:
+** This is only used for debugging. If set to false, any prefix indexes
+** are ignored. This value is configured using:
+**
+** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex);
+**
+*/
+struct Fts5Config {
+ sqlite3 *db; /* Database handle */
+ char *zDb; /* Database holding FTS index (e.g. "main") */
+ char *zName; /* Name of FTS index */
+ int nCol; /* Number of columns */
+ char **azCol; /* Column names */
+ u8 *abUnindexed; /* True for unindexed columns */
+ int nPrefix; /* Number of prefix indexes */
+ int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */
+ int eContent; /* An FTS5_CONTENT value */
char *zContent; /* content table */
char *zContentRowid; /* "content_rowid=" option value */
- int bColumnsize; /* "columnsize=" option value (dflt==1) */
- int eDetail; /* FTS5_DETAIL_XXX value */
- char *zContentExprlist;
- Fts5Tokenizer *pTok;
- fts5_tokenizer *pTokApi;
+ int bColumnsize; /* "columnsize=" option value (dflt==1) */
+ int eDetail; /* FTS5_DETAIL_XXX value */
+ char *zContentExprlist;
+ Fts5Tokenizer *pTok;
+ fts5_tokenizer *pTokApi;
int bLock; /* True when table is preparing statement */
int ePattern; /* FTS_PATTERN_XXX constant */
-
- /* Values loaded from the %_config table */
- int iCookie; /* Incremented when %_config is modified */
- int pgsz; /* Approximate page size used in %_data */
- int nAutomerge; /* 'automerge' setting */
- int nCrisisMerge; /* Maximum allowed segments per level */
- int nUsermerge; /* 'usermerge' setting */
- int nHashSize; /* Bytes of memory for in-memory hash */
- char *zRank; /* Name of rank function */
- char *zRankArgs; /* Arguments to rank function */
-
- /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
- char **pzErrmsg;
-
-#ifdef SQLITE_DEBUG
- int bPrefixIndex; /* True to use prefix-indexes */
-#endif
-};
-
-/* Current expected value of %_config table 'version' field */
+
+ /* Values loaded from the %_config table */
+ int iCookie; /* Incremented when %_config is modified */
+ int pgsz; /* Approximate page size used in %_data */
+ int nAutomerge; /* 'automerge' setting */
+ int nCrisisMerge; /* Maximum allowed segments per level */
+ int nUsermerge; /* 'usermerge' setting */
+ int nHashSize; /* Bytes of memory for in-memory hash */
+ char *zRank; /* Name of rank function */
+ char *zRankArgs; /* Arguments to rank function */
+
+ /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
+ char **pzErrmsg;
+
+#ifdef SQLITE_DEBUG
+ int bPrefixIndex; /* True to use prefix-indexes */
+#endif
+};
+
+/* Current expected value of %_config table 'version' field */
#define FTS5_CURRENT_VERSION 4
-
-#define FTS5_CONTENT_NORMAL 0
-#define FTS5_CONTENT_NONE 1
-#define FTS5_CONTENT_EXTERNAL 2
-
+
+#define FTS5_CONTENT_NORMAL 0
+#define FTS5_CONTENT_NONE 1
+#define FTS5_CONTENT_EXTERNAL 2
+
#define FTS5_DETAIL_FULL 0
#define FTS5_DETAIL_NONE 1
#define FTS5_DETAIL_COLUMNS 2
-
+
#define FTS5_PATTERN_NONE 0
#define FTS5_PATTERN_LIKE 65 /* matches SQLITE_INDEX_CONSTRAINT_LIKE */
#define FTS5_PATTERN_GLOB 66 /* matches SQLITE_INDEX_CONSTRAINT_GLOB */
-
-static int sqlite3Fts5ConfigParse(
- Fts5Global*, sqlite3*, int, const char **, Fts5Config**, char**
-);
-static void sqlite3Fts5ConfigFree(Fts5Config*);
-
-static int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig);
-
-static int sqlite3Fts5Tokenize(
- Fts5Config *pConfig, /* FTS5 Configuration object */
- int flags, /* FTS5_TOKENIZE_* flags */
- const char *pText, int nText, /* Text to tokenize */
- void *pCtx, /* Context passed to xToken() */
- int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
-);
-
-static void sqlite3Fts5Dequote(char *z);
-
-/* Load the contents of the %_config table */
-static int sqlite3Fts5ConfigLoad(Fts5Config*, int);
-
-/* Set the value of a single config attribute */
-static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, int*);
-
-static int sqlite3Fts5ConfigParseRank(const char*, char**, char**);
-
-/*
-** End of interface to code in fts5_config.c.
-**************************************************************************/
-
-/**************************************************************************
-** Interface to code in fts5_buffer.c.
-*/
-
-/*
-** Buffer object for the incremental building of string data.
-*/
-typedef struct Fts5Buffer Fts5Buffer;
-struct Fts5Buffer {
- u8 *p;
- int n;
- int nSpace;
-};
-
-static int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32);
-static void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64);
-static void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, u32, const u8*);
-static void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*);
-static void sqlite3Fts5BufferFree(Fts5Buffer*);
-static void sqlite3Fts5BufferZero(Fts5Buffer*);
-static void sqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*);
-static void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...);
-
-static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
-
-#define fts5BufferZero(x) sqlite3Fts5BufferZero(x)
-#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c)
-#define fts5BufferFree(a) sqlite3Fts5BufferFree(a)
-#define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d)
-#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d)
-
-#define fts5BufferGrow(pRc,pBuf,nn) ( \
- (u32)((pBuf)->n) + (u32)(nn) <= (u32)((pBuf)->nSpace) ? 0 : \
- sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \
-)
-
-/* Write and decode big-endian 32-bit integer values */
-static void sqlite3Fts5Put32(u8*, int);
-static int sqlite3Fts5Get32(const u8*);
-
-#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
+
+static int sqlite3Fts5ConfigParse(
+ Fts5Global*, sqlite3*, int, const char **, Fts5Config**, char**
+);
+static void sqlite3Fts5ConfigFree(Fts5Config*);
+
+static int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig);
+
+static int sqlite3Fts5Tokenize(
+ Fts5Config *pConfig, /* FTS5 Configuration object */
+ int flags, /* FTS5_TOKENIZE_* flags */
+ const char *pText, int nText, /* Text to tokenize */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+);
+
+static void sqlite3Fts5Dequote(char *z);
+
+/* Load the contents of the %_config table */
+static int sqlite3Fts5ConfigLoad(Fts5Config*, int);
+
+/* Set the value of a single config attribute */
+static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, int*);
+
+static int sqlite3Fts5ConfigParseRank(const char*, char**, char**);
+
+/*
+** End of interface to code in fts5_config.c.
+**************************************************************************/
+
+/**************************************************************************
+** Interface to code in fts5_buffer.c.
+*/
+
+/*
+** Buffer object for the incremental building of string data.
+*/
+typedef struct Fts5Buffer Fts5Buffer;
+struct Fts5Buffer {
+ u8 *p;
+ int n;
+ int nSpace;
+};
+
+static int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32);
+static void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64);
+static void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, u32, const u8*);
+static void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*);
+static void sqlite3Fts5BufferFree(Fts5Buffer*);
+static void sqlite3Fts5BufferZero(Fts5Buffer*);
+static void sqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*);
+static void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...);
+
+static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
+
+#define fts5BufferZero(x) sqlite3Fts5BufferZero(x)
+#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c)
+#define fts5BufferFree(a) sqlite3Fts5BufferFree(a)
+#define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d)
+#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d)
+
+#define fts5BufferGrow(pRc,pBuf,nn) ( \
+ (u32)((pBuf)->n) + (u32)(nn) <= (u32)((pBuf)->nSpace) ? 0 : \
+ sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \
+)
+
+/* Write and decode big-endian 32-bit integer values */
+static void sqlite3Fts5Put32(u8*, int);
+static int sqlite3Fts5Get32(const u8*);
+
+#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF)
-
-typedef struct Fts5PoslistReader Fts5PoslistReader;
-struct Fts5PoslistReader {
- /* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
- const u8 *a; /* Position list to iterate through */
- int n; /* Size of buffer at a[] in bytes */
- int i; /* Current offset in a[] */
-
- u8 bFlag; /* For client use (any custom purpose) */
-
- /* Output variables */
- u8 bEof; /* Set to true at EOF */
- i64 iPos; /* (iCol<<32) + iPos */
-};
-static int sqlite3Fts5PoslistReaderInit(
- const u8 *a, int n, /* Poslist buffer to iterate through */
- Fts5PoslistReader *pIter /* Iterator object to initialize */
-);
-static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader*);
-
-typedef struct Fts5PoslistWriter Fts5PoslistWriter;
-struct Fts5PoslistWriter {
- i64 iPrev;
-};
-static int sqlite3Fts5PoslistWriterAppend(Fts5Buffer*, Fts5PoslistWriter*, i64);
-static void sqlite3Fts5PoslistSafeAppend(Fts5Buffer*, i64*, i64);
-
-static int sqlite3Fts5PoslistNext64(
- const u8 *a, int n, /* Buffer containing poslist */
- int *pi, /* IN/OUT: Offset within a[] */
- i64 *piOff /* IN/OUT: Current offset */
-);
-
-/* Malloc utility */
+
+typedef struct Fts5PoslistReader Fts5PoslistReader;
+struct Fts5PoslistReader {
+ /* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
+ const u8 *a; /* Position list to iterate through */
+ int n; /* Size of buffer at a[] in bytes */
+ int i; /* Current offset in a[] */
+
+ u8 bFlag; /* For client use (any custom purpose) */
+
+ /* Output variables */
+ u8 bEof; /* Set to true at EOF */
+ i64 iPos; /* (iCol<<32) + iPos */
+};
+static int sqlite3Fts5PoslistReaderInit(
+ const u8 *a, int n, /* Poslist buffer to iterate through */
+ Fts5PoslistReader *pIter /* Iterator object to initialize */
+);
+static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader*);
+
+typedef struct Fts5PoslistWriter Fts5PoslistWriter;
+struct Fts5PoslistWriter {
+ i64 iPrev;
+};
+static int sqlite3Fts5PoslistWriterAppend(Fts5Buffer*, Fts5PoslistWriter*, i64);
+static void sqlite3Fts5PoslistSafeAppend(Fts5Buffer*, i64*, i64);
+
+static int sqlite3Fts5PoslistNext64(
+ const u8 *a, int n, /* Buffer containing poslist */
+ int *pi, /* IN/OUT: Offset within a[] */
+ i64 *piOff /* IN/OUT: Current offset */
+);
+
+/* Malloc utility */
static void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte);
-static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn);
-
-/* Character set tests (like isspace(), isalpha() etc.) */
-static int sqlite3Fts5IsBareword(char t);
-
-
-/* Bucket of terms object used by the integrity-check in offsets=0 mode. */
-typedef struct Fts5Termset Fts5Termset;
-static int sqlite3Fts5TermsetNew(Fts5Termset**);
-static int sqlite3Fts5TermsetAdd(Fts5Termset*, int, const char*, int, int *pbPresent);
-static void sqlite3Fts5TermsetFree(Fts5Termset*);
-
-/*
-** End of interface to code in fts5_buffer.c.
-**************************************************************************/
-
-/**************************************************************************
-** Interface to code in fts5_index.c. fts5_index.c contains contains code
-** to access the data stored in the %_data table.
-*/
-
-typedef struct Fts5Index Fts5Index;
-typedef struct Fts5IndexIter Fts5IndexIter;
-
-struct Fts5IndexIter {
- i64 iRowid;
- const u8 *pData;
- int nData;
- u8 bEof;
-};
-
-#define sqlite3Fts5IterEof(x) ((x)->bEof)
-
-/*
-** Values used as part of the flags argument passed to IndexQuery().
-*/
-#define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */
-#define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */
-#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */
-#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */
-
-/* The following are used internally by the fts5_index.c module. They are
-** defined here only to make it easier to avoid clashes with the flags
-** above. */
-#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010
-#define FTS5INDEX_QUERY_NOOUTPUT 0x0020
-
-/*
-** Create/destroy an Fts5Index object.
-*/
-static int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**);
-static int sqlite3Fts5IndexClose(Fts5Index *p);
-
-/*
-** Return a simple checksum value based on the arguments.
-*/
-static u64 sqlite3Fts5IndexEntryCksum(
+static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn);
+
+/* Character set tests (like isspace(), isalpha() etc.) */
+static int sqlite3Fts5IsBareword(char t);
+
+
+/* Bucket of terms object used by the integrity-check in offsets=0 mode. */
+typedef struct Fts5Termset Fts5Termset;
+static int sqlite3Fts5TermsetNew(Fts5Termset**);
+static int sqlite3Fts5TermsetAdd(Fts5Termset*, int, const char*, int, int *pbPresent);
+static void sqlite3Fts5TermsetFree(Fts5Termset*);
+
+/*
+** End of interface to code in fts5_buffer.c.
+**************************************************************************/
+
+/**************************************************************************
+** Interface to code in fts5_index.c. fts5_index.c contains contains code
+** to access the data stored in the %_data table.
+*/
+
+typedef struct Fts5Index Fts5Index;
+typedef struct Fts5IndexIter Fts5IndexIter;
+
+struct Fts5IndexIter {
+ i64 iRowid;
+ const u8 *pData;
+ int nData;
+ u8 bEof;
+};
+
+#define sqlite3Fts5IterEof(x) ((x)->bEof)
+
+/*
+** Values used as part of the flags argument passed to IndexQuery().
+*/
+#define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */
+#define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */
+#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */
+#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */
+
+/* The following are used internally by the fts5_index.c module. They are
+** defined here only to make it easier to avoid clashes with the flags
+** above. */
+#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010
+#define FTS5INDEX_QUERY_NOOUTPUT 0x0020
+
+/*
+** Create/destroy an Fts5Index object.
+*/
+static int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**);
+static int sqlite3Fts5IndexClose(Fts5Index *p);
+
+/*
+** Return a simple checksum value based on the arguments.
+*/
+static u64 sqlite3Fts5IndexEntryCksum(
i64 iRowid,
int iCol,
int iPos,
- int iIdx,
- const char *pTerm,
- int nTerm
-);
-
-/*
+ int iIdx,
+ const char *pTerm,
+ int nTerm
+);
+
+/*
** Argument p points to a buffer containing utf-8 text that is n bytes in
-** size. Return the number of bytes in the nChar character prefix of the
-** buffer, or 0 if there are less than nChar characters in total.
-*/
-static int sqlite3Fts5IndexCharlenToBytelen(
+** size. Return the number of bytes in the nChar character prefix of the
+** buffer, or 0 if there are less than nChar characters in total.
+*/
+static int sqlite3Fts5IndexCharlenToBytelen(
const char *p,
int nByte,
- int nChar
-);
-
-/*
+ int nChar
+);
+
+/*
** Open a new iterator to iterate though all rowids that match the
-** specified token or token prefix.
-*/
-static int sqlite3Fts5IndexQuery(
- Fts5Index *p, /* FTS index to query */
- const char *pToken, int nToken, /* Token (or prefix) to query for */
- int flags, /* Mask of FTS5INDEX_QUERY_X flags */
- Fts5Colset *pColset, /* Match these columns only */
- Fts5IndexIter **ppIter /* OUT: New iterator object */
-);
-
-/*
-** The various operations on open token or token prefix iterators opened
-** using sqlite3Fts5IndexQuery().
-*/
-static int sqlite3Fts5IterNext(Fts5IndexIter*);
-static int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
-
-/*
-** Close an iterator opened by sqlite3Fts5IndexQuery().
-*/
-static void sqlite3Fts5IterClose(Fts5IndexIter*);
-
-/*
+** specified token or token prefix.
+*/
+static int sqlite3Fts5IndexQuery(
+ Fts5Index *p, /* FTS index to query */
+ const char *pToken, int nToken, /* Token (or prefix) to query for */
+ int flags, /* Mask of FTS5INDEX_QUERY_X flags */
+ Fts5Colset *pColset, /* Match these columns only */
+ Fts5IndexIter **ppIter /* OUT: New iterator object */
+);
+
+/*
+** The various operations on open token or token prefix iterators opened
+** using sqlite3Fts5IndexQuery().
+*/
+static int sqlite3Fts5IterNext(Fts5IndexIter*);
+static int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
+
+/*
+** Close an iterator opened by sqlite3Fts5IndexQuery().
+*/
+static void sqlite3Fts5IterClose(Fts5IndexIter*);
+
+/*
** Close the reader blob handle, if it is open.
*/
static void sqlite3Fts5IndexCloseReader(Fts5Index*);
/*
-** This interface is used by the fts5vocab module.
-*/
-static const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*);
-static int sqlite3Fts5IterNextScan(Fts5IndexIter*);
+** This interface is used by the fts5vocab module.
+*/
+static const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*);
+static int sqlite3Fts5IterNextScan(Fts5IndexIter*);
static void *sqlite3Fts5StructureRef(Fts5Index*);
static void sqlite3Fts5StructureRelease(void*);
static int sqlite3Fts5StructureTest(Fts5Index*, void*);
-
-
-/*
+
+
+/*
** Insert or remove data to or from the index. Each time a document is
-** added to or removed from the index, this function is called one or more
-** times.
-**
-** For an insert, it must be called once for each token in the new document.
-** If the operation is a delete, it must be called (at least) once for each
-** unique token in the document with an iCol value less than zero. The iPos
-** argument is ignored for a delete.
-*/
-static int sqlite3Fts5IndexWrite(
- Fts5Index *p, /* Index to write to */
- int iCol, /* Column token appears in (-ve -> delete) */
- int iPos, /* Position of token within column */
- const char *pToken, int nToken /* Token to add or remove to or from index */
-);
-
-/*
-** Indicate that subsequent calls to sqlite3Fts5IndexWrite() pertain to
-** document iDocid.
-*/
-static int sqlite3Fts5IndexBeginWrite(
- Fts5Index *p, /* Index to write to */
- int bDelete, /* True if current operation is a delete */
- i64 iDocid /* Docid to add or remove data from */
-);
-
-/*
-** Flush any data stored in the in-memory hash tables to the database.
-** Also close any open blob handles.
-*/
-static int sqlite3Fts5IndexSync(Fts5Index *p);
-
-/*
-** Discard any data stored in the in-memory hash tables. Do not write it
-** to the database. Additionally, assume that the contents of the %_data
+** added to or removed from the index, this function is called one or more
+** times.
+**
+** For an insert, it must be called once for each token in the new document.
+** If the operation is a delete, it must be called (at least) once for each
+** unique token in the document with an iCol value less than zero. The iPos
+** argument is ignored for a delete.
+*/
+static int sqlite3Fts5IndexWrite(
+ Fts5Index *p, /* Index to write to */
+ int iCol, /* Column token appears in (-ve -> delete) */
+ int iPos, /* Position of token within column */
+ const char *pToken, int nToken /* Token to add or remove to or from index */
+);
+
+/*
+** Indicate that subsequent calls to sqlite3Fts5IndexWrite() pertain to
+** document iDocid.
+*/
+static int sqlite3Fts5IndexBeginWrite(
+ Fts5Index *p, /* Index to write to */
+ int bDelete, /* True if current operation is a delete */
+ i64 iDocid /* Docid to add or remove data from */
+);
+
+/*
+** Flush any data stored in the in-memory hash tables to the database.
+** Also close any open blob handles.
+*/
+static int sqlite3Fts5IndexSync(Fts5Index *p);
+
+/*
+** Discard any data stored in the in-memory hash tables. Do not write it
+** to the database. Additionally, assume that the contents of the %_data
** table may have changed on disk. So any in-memory caches of %_data
-** records must be invalidated.
-*/
-static int sqlite3Fts5IndexRollback(Fts5Index *p);
-
-/*
-** Get or set the "averages" values.
-*/
-static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize);
-static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int);
-
-/*
-** Functions called by the storage module as part of integrity-check.
-*/
+** records must be invalidated.
+*/
+static int sqlite3Fts5IndexRollback(Fts5Index *p);
+
+/*
+** Get or set the "averages" values.
+*/
+static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize);
+static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int);
+
+/*
+** Functions called by the storage module as part of integrity-check.
+*/
static int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum, int bUseCksum);
-
+
/*
** Called during virtual module initialization to register UDF
** fts5_decode() with SQLite
-*/
-static int sqlite3Fts5IndexInit(sqlite3*);
-
-static int sqlite3Fts5IndexSetCookie(Fts5Index*, int);
-
-/*
+*/
+static int sqlite3Fts5IndexInit(sqlite3*);
+
+static int sqlite3Fts5IndexSetCookie(Fts5Index*, int);
+
+/*
** Return the total number of entries read from the %_data table by
-** this connection since it was created.
-*/
-static int sqlite3Fts5IndexReads(Fts5Index *p);
-
-static int sqlite3Fts5IndexReinit(Fts5Index *p);
-static int sqlite3Fts5IndexOptimize(Fts5Index *p);
-static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
-static int sqlite3Fts5IndexReset(Fts5Index *p);
-
-static int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
-
-/*
-** End of interface to code in fts5_index.c.
-**************************************************************************/
-
-/**************************************************************************
+** this connection since it was created.
+*/
+static int sqlite3Fts5IndexReads(Fts5Index *p);
+
+static int sqlite3Fts5IndexReinit(Fts5Index *p);
+static int sqlite3Fts5IndexOptimize(Fts5Index *p);
+static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
+static int sqlite3Fts5IndexReset(Fts5Index *p);
+
+static int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
+
+/*
+** End of interface to code in fts5_index.c.
+**************************************************************************/
+
+/**************************************************************************
** Interface to code in fts5_varint.c.
-*/
-static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v);
-static int sqlite3Fts5GetVarintLen(u32 iVal);
-static u8 sqlite3Fts5GetVarint(const unsigned char*, u64*);
-static int sqlite3Fts5PutVarint(unsigned char *p, u64 v);
-
-#define fts5GetVarint32(a,b) sqlite3Fts5GetVarint32(a,(u32*)&b)
-#define fts5GetVarint sqlite3Fts5GetVarint
-
-#define fts5FastGetVarint32(a, iOff, nVal) { \
- nVal = (a)[iOff++]; \
- if( nVal & 0x80 ){ \
- iOff--; \
- iOff += fts5GetVarint32(&(a)[iOff], nVal); \
- } \
-}
-
-
-/*
-** End of interface to code in fts5_varint.c.
-**************************************************************************/
-
-
-/**************************************************************************
+*/
+static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v);
+static int sqlite3Fts5GetVarintLen(u32 iVal);
+static u8 sqlite3Fts5GetVarint(const unsigned char*, u64*);
+static int sqlite3Fts5PutVarint(unsigned char *p, u64 v);
+
+#define fts5GetVarint32(a,b) sqlite3Fts5GetVarint32(a,(u32*)&b)
+#define fts5GetVarint sqlite3Fts5GetVarint
+
+#define fts5FastGetVarint32(a, iOff, nVal) { \
+ nVal = (a)[iOff++]; \
+ if( nVal & 0x80 ){ \
+ iOff--; \
+ iOff += fts5GetVarint32(&(a)[iOff], nVal); \
+ } \
+}
+
+
+/*
+** End of interface to code in fts5_varint.c.
+**************************************************************************/
+
+
+/**************************************************************************
** Interface to code in fts5_main.c.
-*/
-
+*/
+
/*
** Virtual-table object.
*/
@@ -215433,145 +215433,145 @@ struct Fts5Table {
Fts5Index *pIndex; /* Full-text index */
};
-static int sqlite3Fts5GetTokenizer(
+static int sqlite3Fts5GetTokenizer(
Fts5Global*,
- const char **azArg,
- int nArg,
+ const char **azArg,
+ int nArg,
Fts5Config*,
- char **pzErr
-);
-
+ char **pzErr
+);
+
static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
-
+
static int sqlite3Fts5FlushToDisk(Fts5Table*);
-/*
-** End of interface to code in fts5.c.
-**************************************************************************/
-
-/**************************************************************************
+/*
+** End of interface to code in fts5.c.
+**************************************************************************/
+
+/**************************************************************************
** Interface to code in fts5_hash.c.
-*/
-typedef struct Fts5Hash Fts5Hash;
-
-/*
-** Create a hash table, free a hash table.
-*/
-static int sqlite3Fts5HashNew(Fts5Config*, Fts5Hash**, int *pnSize);
-static void sqlite3Fts5HashFree(Fts5Hash*);
-
-static int sqlite3Fts5HashWrite(
- Fts5Hash*,
- i64 iRowid, /* Rowid for this entry */
- int iCol, /* Column token appears in (-ve -> delete) */
- int iPos, /* Position of token within column */
- char bByte,
- const char *pToken, int nToken /* Token to add or remove to or from index */
-);
-
-/*
-** Empty (but do not delete) a hash table.
-*/
-static void sqlite3Fts5HashClear(Fts5Hash*);
-
-static int sqlite3Fts5HashQuery(
- Fts5Hash*, /* Hash table to query */
+*/
+typedef struct Fts5Hash Fts5Hash;
+
+/*
+** Create a hash table, free a hash table.
+*/
+static int sqlite3Fts5HashNew(Fts5Config*, Fts5Hash**, int *pnSize);
+static void sqlite3Fts5HashFree(Fts5Hash*);
+
+static int sqlite3Fts5HashWrite(
+ Fts5Hash*,
+ i64 iRowid, /* Rowid for this entry */
+ int iCol, /* Column token appears in (-ve -> delete) */
+ int iPos, /* Position of token within column */
+ char bByte,
+ const char *pToken, int nToken /* Token to add or remove to or from index */
+);
+
+/*
+** Empty (but do not delete) a hash table.
+*/
+static void sqlite3Fts5HashClear(Fts5Hash*);
+
+static int sqlite3Fts5HashQuery(
+ Fts5Hash*, /* Hash table to query */
int nPre,
- const char *pTerm, int nTerm, /* Query term */
+ const char *pTerm, int nTerm, /* Query term */
void **ppObj, /* OUT: Pointer to doclist for pTerm */
- int *pnDoclist /* OUT: Size of doclist in bytes */
-);
-
-static int sqlite3Fts5HashScanInit(
- Fts5Hash*, /* Hash table to query */
- const char *pTerm, int nTerm /* Query prefix */
-);
-static void sqlite3Fts5HashScanNext(Fts5Hash*);
-static int sqlite3Fts5HashScanEof(Fts5Hash*);
-static void sqlite3Fts5HashScanEntry(Fts5Hash *,
- const char **pzTerm, /* OUT: term (nul-terminated) */
- const u8 **ppDoclist, /* OUT: pointer to doclist */
- int *pnDoclist /* OUT: size of doclist in bytes */
-);
-
-
-/*
-** End of interface to code in fts5_hash.c.
-**************************************************************************/
-
-/**************************************************************************
+ int *pnDoclist /* OUT: Size of doclist in bytes */
+);
+
+static int sqlite3Fts5HashScanInit(
+ Fts5Hash*, /* Hash table to query */
+ const char *pTerm, int nTerm /* Query prefix */
+);
+static void sqlite3Fts5HashScanNext(Fts5Hash*);
+static int sqlite3Fts5HashScanEof(Fts5Hash*);
+static void sqlite3Fts5HashScanEntry(Fts5Hash *,
+ const char **pzTerm, /* OUT: term (nul-terminated) */
+ const u8 **ppDoclist, /* OUT: pointer to doclist */
+ int *pnDoclist /* OUT: size of doclist in bytes */
+);
+
+
+/*
+** End of interface to code in fts5_hash.c.
+**************************************************************************/
+
+/**************************************************************************
** Interface to code in fts5_storage.c. fts5_storage.c contains contains
-** code to access the data stored in the %_content and %_docsize tables.
-*/
-
-#define FTS5_STMT_SCAN_ASC 0 /* SELECT rowid, * FROM ... ORDER BY 1 ASC */
-#define FTS5_STMT_SCAN_DESC 1 /* SELECT rowid, * FROM ... ORDER BY 1 DESC */
-#define FTS5_STMT_LOOKUP 2 /* SELECT rowid, * FROM ... WHERE rowid=? */
-
-typedef struct Fts5Storage Fts5Storage;
-
-static int sqlite3Fts5StorageOpen(Fts5Config*, Fts5Index*, int, Fts5Storage**, char**);
-static int sqlite3Fts5StorageClose(Fts5Storage *p);
-static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName);
-
-static int sqlite3Fts5DropAll(Fts5Config*);
-static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);
-
-static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**);
-static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
-static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
-
+** code to access the data stored in the %_content and %_docsize tables.
+*/
+
+#define FTS5_STMT_SCAN_ASC 0 /* SELECT rowid, * FROM ... ORDER BY 1 ASC */
+#define FTS5_STMT_SCAN_DESC 1 /* SELECT rowid, * FROM ... ORDER BY 1 DESC */
+#define FTS5_STMT_LOOKUP 2 /* SELECT rowid, * FROM ... WHERE rowid=? */
+
+typedef struct Fts5Storage Fts5Storage;
+
+static int sqlite3Fts5StorageOpen(Fts5Config*, Fts5Index*, int, Fts5Storage**, char**);
+static int sqlite3Fts5StorageClose(Fts5Storage *p);
+static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName);
+
+static int sqlite3Fts5DropAll(Fts5Config*);
+static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);
+
+static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**);
+static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
+static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
+
static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg);
-
-static int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**);
-static void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*);
-
-static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
-static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg);
-static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow);
-
-static int sqlite3Fts5StorageSync(Fts5Storage *p);
-static int sqlite3Fts5StorageRollback(Fts5Storage *p);
-
-static int sqlite3Fts5StorageConfigValue(
- Fts5Storage *p, const char*, sqlite3_value*, int
-);
-
-static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p);
-static int sqlite3Fts5StorageRebuild(Fts5Storage *p);
-static int sqlite3Fts5StorageOptimize(Fts5Storage *p);
-static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge);
-static int sqlite3Fts5StorageReset(Fts5Storage *p);
-
-/*
-** End of interface to code in fts5_storage.c.
-**************************************************************************/
-
-
-/**************************************************************************
+
+static int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**);
+static void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*);
+
+static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
+static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg);
+static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow);
+
+static int sqlite3Fts5StorageSync(Fts5Storage *p);
+static int sqlite3Fts5StorageRollback(Fts5Storage *p);
+
+static int sqlite3Fts5StorageConfigValue(
+ Fts5Storage *p, const char*, sqlite3_value*, int
+);
+
+static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p);
+static int sqlite3Fts5StorageRebuild(Fts5Storage *p);
+static int sqlite3Fts5StorageOptimize(Fts5Storage *p);
+static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge);
+static int sqlite3Fts5StorageReset(Fts5Storage *p);
+
+/*
+** End of interface to code in fts5_storage.c.
+**************************************************************************/
+
+
+/**************************************************************************
** Interface to code in fts5_expr.c.
-*/
-typedef struct Fts5Expr Fts5Expr;
-typedef struct Fts5ExprNode Fts5ExprNode;
-typedef struct Fts5Parse Fts5Parse;
-typedef struct Fts5Token Fts5Token;
-typedef struct Fts5ExprPhrase Fts5ExprPhrase;
-typedef struct Fts5ExprNearset Fts5ExprNearset;
-
-struct Fts5Token {
- const char *p; /* Token text (not NULL terminated) */
- int n; /* Size of buffer p in bytes */
-};
-
-/* Parse a MATCH expression. */
-static int sqlite3Fts5ExprNew(
+*/
+typedef struct Fts5Expr Fts5Expr;
+typedef struct Fts5ExprNode Fts5ExprNode;
+typedef struct Fts5Parse Fts5Parse;
+typedef struct Fts5Token Fts5Token;
+typedef struct Fts5ExprPhrase Fts5ExprPhrase;
+typedef struct Fts5ExprNearset Fts5ExprNearset;
+
+struct Fts5Token {
+ const char *p; /* Token text (not NULL terminated) */
+ int n; /* Size of buffer p in bytes */
+};
+
+/* Parse a MATCH expression. */
+static int sqlite3Fts5ExprNew(
Fts5Config *pConfig,
int bPhraseToAnd,
- int iCol, /* Column on LHS of MATCH operator */
- const char *zExpr,
+ int iCol, /* Column on LHS of MATCH operator */
+ const char *zExpr,
Fts5Expr **ppNew,
- char **pzErr
-);
+ char **pzErr
+);
static int sqlite3Fts5ExprPattern(
Fts5Config *pConfig,
int bGlob,
@@ -215579,219 +215579,219 @@ static int sqlite3Fts5ExprPattern(
const char *zText,
Fts5Expr **pp
);
-
-/*
-** for(rc = sqlite3Fts5ExprFirst(pExpr, pIdx, bDesc);
-** rc==SQLITE_OK && 0==sqlite3Fts5ExprEof(pExpr);
-** rc = sqlite3Fts5ExprNext(pExpr)
-** ){
-** // The document with rowid iRowid matches the expression!
-** i64 iRowid = sqlite3Fts5ExprRowid(pExpr);
-** }
-*/
-static int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc);
-static int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax);
-static int sqlite3Fts5ExprEof(Fts5Expr*);
-static i64 sqlite3Fts5ExprRowid(Fts5Expr*);
-
-static void sqlite3Fts5ExprFree(Fts5Expr*);
+
+/*
+** for(rc = sqlite3Fts5ExprFirst(pExpr, pIdx, bDesc);
+** rc==SQLITE_OK && 0==sqlite3Fts5ExprEof(pExpr);
+** rc = sqlite3Fts5ExprNext(pExpr)
+** ){
+** // The document with rowid iRowid matches the expression!
+** i64 iRowid = sqlite3Fts5ExprRowid(pExpr);
+** }
+*/
+static int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc);
+static int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax);
+static int sqlite3Fts5ExprEof(Fts5Expr*);
+static i64 sqlite3Fts5ExprRowid(Fts5Expr*);
+
+static void sqlite3Fts5ExprFree(Fts5Expr*);
static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2);
-
-/* Called during startup to register a UDF with SQLite */
-static int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*);
-
-static int sqlite3Fts5ExprPhraseCount(Fts5Expr*);
-static int sqlite3Fts5ExprPhraseSize(Fts5Expr*, int iPhrase);
-static int sqlite3Fts5ExprPoslist(Fts5Expr*, int, const u8 **);
-
-typedef struct Fts5PoslistPopulator Fts5PoslistPopulator;
-static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr*, int);
-static int sqlite3Fts5ExprPopulatePoslists(
- Fts5Config*, Fts5Expr*, Fts5PoslistPopulator*, int, const char*, int
-);
-static void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64);
-
-static int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**);
-
-static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *);
-
-/*******************************************
-** The fts5_expr.c API above this point is used by the other hand-written
-** C code in this module. The interfaces below this point are called by
-** the parser code in fts5parse.y. */
-
-static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...);
-
-static Fts5ExprNode *sqlite3Fts5ParseNode(
- Fts5Parse *pParse,
- int eType,
- Fts5ExprNode *pLeft,
- Fts5ExprNode *pRight,
- Fts5ExprNearset *pNear
-);
-
-static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
- Fts5Parse *pParse,
- Fts5ExprNode *pLeft,
- Fts5ExprNode *pRight
-);
-
-static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
+
+/* Called during startup to register a UDF with SQLite */
+static int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*);
+
+static int sqlite3Fts5ExprPhraseCount(Fts5Expr*);
+static int sqlite3Fts5ExprPhraseSize(Fts5Expr*, int iPhrase);
+static int sqlite3Fts5ExprPoslist(Fts5Expr*, int, const u8 **);
+
+typedef struct Fts5PoslistPopulator Fts5PoslistPopulator;
+static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr*, int);
+static int sqlite3Fts5ExprPopulatePoslists(
+ Fts5Config*, Fts5Expr*, Fts5PoslistPopulator*, int, const char*, int
+);
+static void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64);
+
+static int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**);
+
+static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *);
+
+/*******************************************
+** The fts5_expr.c API above this point is used by the other hand-written
+** C code in this module. The interfaces below this point are called by
+** the parser code in fts5parse.y. */
+
+static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...);
+
+static Fts5ExprNode *sqlite3Fts5ParseNode(
+ Fts5Parse *pParse,
+ int eType,
+ Fts5ExprNode *pLeft,
+ Fts5ExprNode *pRight,
+ Fts5ExprNearset *pNear
+);
+
+static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
+ Fts5Parse *pParse,
+ Fts5ExprNode *pLeft,
+ Fts5ExprNode *pRight
+);
+
+static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
Fts5Parse *pParse,
Fts5ExprPhrase *pPhrase,
- Fts5Token *pToken,
- int bPrefix
-);
-
-static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase*);
-
-static Fts5ExprNearset *sqlite3Fts5ParseNearset(
+ Fts5Token *pToken,
+ int bPrefix
+);
+
+static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase*);
+
+static Fts5ExprNearset *sqlite3Fts5ParseNearset(
Fts5Parse*,
- Fts5ExprNearset*,
+ Fts5ExprNearset*,
Fts5ExprPhrase*
-);
-
-static Fts5Colset *sqlite3Fts5ParseColset(
+);
+
+static Fts5Colset *sqlite3Fts5ParseColset(
Fts5Parse*,
Fts5Colset*,
- Fts5Token *
-);
-
-static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*);
-static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*);
-static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
-
-static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
-static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*);
-static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*);
-static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
-static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
-
-/*
-** End of interface to code in fts5_expr.c.
-**************************************************************************/
-
-
-
-/**************************************************************************
+ Fts5Token *
+);
+
+static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*);
+static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*);
+static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
+
+static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
+static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*);
+static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*);
+static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
+static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
+
+/*
+** End of interface to code in fts5_expr.c.
+**************************************************************************/
+
+
+
+/**************************************************************************
** Interface to code in fts5_aux.c.
-*/
-
-static int sqlite3Fts5AuxInit(fts5_api*);
-/*
-** End of interface to code in fts5_aux.c.
-**************************************************************************/
-
-/**************************************************************************
+*/
+
+static int sqlite3Fts5AuxInit(fts5_api*);
+/*
+** End of interface to code in fts5_aux.c.
+**************************************************************************/
+
+/**************************************************************************
** Interface to code in fts5_tokenizer.c.
-*/
-
-static int sqlite3Fts5TokenizerInit(fts5_api*);
+*/
+
+static int sqlite3Fts5TokenizerInit(fts5_api*);
static int sqlite3Fts5TokenizerPattern(
int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
Fts5Tokenizer *pTok
);
-/*
-** End of interface to code in fts5_tokenizer.c.
-**************************************************************************/
-
-/**************************************************************************
+/*
+** End of interface to code in fts5_tokenizer.c.
+**************************************************************************/
+
+/**************************************************************************
** Interface to code in fts5_vocab.c.
-*/
-
-static int sqlite3Fts5VocabInit(Fts5Global*, sqlite3*);
-
-/*
-** End of interface to code in fts5_vocab.c.
-**************************************************************************/
-
-
-/**************************************************************************
+*/
+
+static int sqlite3Fts5VocabInit(Fts5Global*, sqlite3*);
+
+/*
+** End of interface to code in fts5_vocab.c.
+**************************************************************************/
+
+
+/**************************************************************************
** Interface to automatically generated code in fts5_unicode2.c.
-*/
-static int sqlite3Fts5UnicodeIsdiacritic(int c);
-static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
+*/
+static int sqlite3Fts5UnicodeIsdiacritic(int c);
+static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
static int sqlite3Fts5UnicodeCatParse(const char*, u8*);
static int sqlite3Fts5UnicodeCategory(u32 iCode);
static void sqlite3Fts5UnicodeAscii(u8*, u8*);
-/*
-** End of interface to code in fts5_unicode2.c.
-**************************************************************************/
-
-#endif
-
-#define FTS5_OR 1
-#define FTS5_AND 2
-#define FTS5_NOT 3
-#define FTS5_TERM 4
-#define FTS5_COLON 5
-#define FTS5_MINUS 6
-#define FTS5_LCP 7
-#define FTS5_RCP 8
-#define FTS5_STRING 9
-#define FTS5_LP 10
-#define FTS5_RP 11
-#define FTS5_CARET 12
-#define FTS5_COMMA 13
-#define FTS5_PLUS 14
-#define FTS5_STAR 15
-
+/*
+** End of interface to code in fts5_unicode2.c.
+**************************************************************************/
+
+#endif
+
+#define FTS5_OR 1
+#define FTS5_AND 2
+#define FTS5_NOT 3
+#define FTS5_TERM 4
+#define FTS5_COLON 5
+#define FTS5_MINUS 6
+#define FTS5_LCP 7
+#define FTS5_RCP 8
+#define FTS5_STRING 9
+#define FTS5_LP 10
+#define FTS5_RP 11
+#define FTS5_CARET 12
+#define FTS5_COMMA 13
+#define FTS5_PLUS 14
+#define FTS5_STAR 15
+
/* This file is automatically generated by Lemon from input grammar
** source file "fts5parse.y". */
-/*
-** 2000-05-29
-**
-** 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.
-**
-*************************************************************************
-** Driver template for the LEMON parser generator.
-**
-** The "lemon" program processes an LALR(1) input grammar file, then uses
-** this template to construct a parser. The "lemon" program inserts text
-** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the
-** interstitial "-" characters) contained in this template is changed into
-** the value of the %name directive from the grammar. Otherwise, the content
-** of this template is copied straight through into the generate parser
-** source file.
-**
-** The following is the concatenation of all %include directives from the
-** input grammar file:
-*/
-/************ Begin %include sections from the grammar ************************/
-
-/* #include "fts5Int.h" */
-/* #include "fts5parse.h" */
-
-/*
-** Disable all error recovery processing in the parser push-down
-** automaton.
-*/
-#define fts5YYNOERRORRECOVERY 1
-
-/*
-** Make fts5yytestcase() the same as testcase()
-*/
-#define fts5yytestcase(X) testcase(X)
-
-/*
-** Indicate that sqlite3ParserFree() will never be called with a null
-** pointer.
-*/
-#define fts5YYPARSEFREENOTNULL 1
-
-/*
-** Alternative datatype for the argument to the malloc() routine passed
-** into sqlite3ParserAlloc(). The default is size_t.
-*/
-#define fts5YYMALLOCARGTYPE u64
-
-/**************** End of %include directives **********************************/
+/*
+** 2000-05-29
+**
+** 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.
+**
+*************************************************************************
+** Driver template for the LEMON parser generator.
+**
+** The "lemon" program processes an LALR(1) input grammar file, then uses
+** this template to construct a parser. The "lemon" program inserts text
+** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the
+** interstitial "-" characters) contained in this template is changed into
+** the value of the %name directive from the grammar. Otherwise, the content
+** of this template is copied straight through into the generate parser
+** source file.
+**
+** The following is the concatenation of all %include directives from the
+** input grammar file:
+*/
+/************ Begin %include sections from the grammar ************************/
+
+/* #include "fts5Int.h" */
+/* #include "fts5parse.h" */
+
+/*
+** Disable all error recovery processing in the parser push-down
+** automaton.
+*/
+#define fts5YYNOERRORRECOVERY 1
+
+/*
+** Make fts5yytestcase() the same as testcase()
+*/
+#define fts5yytestcase(X) testcase(X)
+
+/*
+** Indicate that sqlite3ParserFree() will never be called with a null
+** pointer.
+*/
+#define fts5YYPARSEFREENOTNULL 1
+
+/*
+** Alternative datatype for the argument to the malloc() routine passed
+** into sqlite3ParserAlloc(). The default is size_t.
+*/
+#define fts5YYMALLOCARGTYPE u64
+
+/**************** End of %include directives **********************************/
/* These constants specify the various numeric values for terminal symbols.
***************** Begin token definitions *************************************/
#ifndef FTS5_OR
@@ -215812,80 +215812,80 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*);
#define FTS5_STAR 15
#endif
/**************** End token definitions ***************************************/
-
-/* The next sections is a series of control #defines.
-** various aspects of the generated parser.
-** fts5YYCODETYPE is the data type used to store the integer codes
-** that represent terminal and non-terminal symbols.
-** "unsigned char" is used if there are fewer than
-** 256 symbols. Larger types otherwise.
-** fts5YYNOCODE is a number of type fts5YYCODETYPE that is not used for
-** any terminal or nonterminal symbol.
-** fts5YYFALLBACK If defined, this indicates that one or more tokens
-** (also known as: "terminal symbols") have fall-back
-** values which should be used if the original symbol
-** would not parse. This permits keywords to sometimes
-** be used as identifiers, for example.
-** fts5YYACTIONTYPE is the data type used for "action codes" - numbers
-** that indicate what to do in response to the next
-** token.
-** sqlite3Fts5ParserFTS5TOKENTYPE is the data type used for minor type for terminal
-** symbols. Background: A "minor type" is a semantic
-** value associated with a terminal or non-terminal
-** symbols. For example, for an "ID" terminal symbol,
-** the minor type might be the name of the identifier.
-** Each non-terminal can have a different minor type.
-** Terminal symbols all have the same minor type, though.
+
+/* The next sections is a series of control #defines.
+** various aspects of the generated parser.
+** fts5YYCODETYPE is the data type used to store the integer codes
+** that represent terminal and non-terminal symbols.
+** "unsigned char" is used if there are fewer than
+** 256 symbols. Larger types otherwise.
+** fts5YYNOCODE is a number of type fts5YYCODETYPE that is not used for
+** any terminal or nonterminal symbol.
+** fts5YYFALLBACK If defined, this indicates that one or more tokens
+** (also known as: "terminal symbols") have fall-back
+** values which should be used if the original symbol
+** would not parse. This permits keywords to sometimes
+** be used as identifiers, for example.
+** fts5YYACTIONTYPE is the data type used for "action codes" - numbers
+** that indicate what to do in response to the next
+** token.
+** sqlite3Fts5ParserFTS5TOKENTYPE is the data type used for minor type for terminal
+** symbols. Background: A "minor type" is a semantic
+** value associated with a terminal or non-terminal
+** symbols. For example, for an "ID" terminal symbol,
+** the minor type might be the name of the identifier.
+** Each non-terminal can have a different minor type.
+** Terminal symbols all have the same minor type, though.
** This macros defines the minor type for terminal
-** symbols.
-** fts5YYMINORTYPE is the data type used for all minor types.
-** This is typically a union of many types, one of
-** which is sqlite3Fts5ParserFTS5TOKENTYPE. The entry in the union
-** for terminal symbols is called "fts5yy0".
-** fts5YYSTACKDEPTH is the maximum depth of the parser's stack. If
-** zero the stack is dynamically sized using realloc()
-** sqlite3Fts5ParserARG_SDECL A static variable declaration for the %extra_argument
-** sqlite3Fts5ParserARG_PDECL A parameter declaration for the %extra_argument
+** symbols.
+** fts5YYMINORTYPE is the data type used for all minor types.
+** This is typically a union of many types, one of
+** which is sqlite3Fts5ParserFTS5TOKENTYPE. The entry in the union
+** for terminal symbols is called "fts5yy0".
+** fts5YYSTACKDEPTH is the maximum depth of the parser's stack. If
+** zero the stack is dynamically sized using realloc()
+** sqlite3Fts5ParserARG_SDECL A static variable declaration for the %extra_argument
+** sqlite3Fts5ParserARG_PDECL A parameter declaration for the %extra_argument
** sqlite3Fts5ParserARG_PARAM Code to pass %extra_argument as a subroutine parameter
-** sqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser
-** sqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser
+** sqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser
+** sqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser
** sqlite3Fts5ParserCTX_* As sqlite3Fts5ParserARG_ except for %extra_context
-** fts5YYERRORSYMBOL is the code number of the error symbol. If not
-** defined, then do no error processing.
-** fts5YYNSTATE the combined number of states.
-** fts5YYNRULE the number of rules in the grammar
-** fts5YYNFTS5TOKEN Number of terminal symbols
-** fts5YY_MAX_SHIFT Maximum value for shift actions
-** fts5YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
-** fts5YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
-** fts5YY_ERROR_ACTION The fts5yy_action[] code for syntax error
-** fts5YY_ACCEPT_ACTION The fts5yy_action[] code for accept
-** fts5YY_NO_ACTION The fts5yy_action[] code for no-op
-** fts5YY_MIN_REDUCE Minimum value for reduce actions
-** fts5YY_MAX_REDUCE Maximum value for reduce actions
-*/
-#ifndef INTERFACE
-# define INTERFACE 1
-#endif
-/************* Begin control #defines *****************************************/
-#define fts5YYCODETYPE unsigned char
+** fts5YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
+** fts5YYNSTATE the combined number of states.
+** fts5YYNRULE the number of rules in the grammar
+** fts5YYNFTS5TOKEN Number of terminal symbols
+** fts5YY_MAX_SHIFT Maximum value for shift actions
+** fts5YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
+** fts5YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
+** fts5YY_ERROR_ACTION The fts5yy_action[] code for syntax error
+** fts5YY_ACCEPT_ACTION The fts5yy_action[] code for accept
+** fts5YY_NO_ACTION The fts5yy_action[] code for no-op
+** fts5YY_MIN_REDUCE Minimum value for reduce actions
+** fts5YY_MAX_REDUCE Maximum value for reduce actions
+*/
+#ifndef INTERFACE
+# define INTERFACE 1
+#endif
+/************* Begin control #defines *****************************************/
+#define fts5YYCODETYPE unsigned char
#define fts5YYNOCODE 27
-#define fts5YYACTIONTYPE unsigned char
-#define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token
-typedef union {
- int fts5yyinit;
- sqlite3Fts5ParserFTS5TOKENTYPE fts5yy0;
- int fts5yy4;
+#define fts5YYACTIONTYPE unsigned char
+#define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token
+typedef union {
+ int fts5yyinit;
+ sqlite3Fts5ParserFTS5TOKENTYPE fts5yy0;
+ int fts5yy4;
Fts5Colset* fts5yy11;
Fts5ExprNode* fts5yy24;
Fts5ExprNearset* fts5yy46;
Fts5ExprPhrase* fts5yy53;
-} fts5YYMINORTYPE;
-#ifndef fts5YYSTACKDEPTH
-#define fts5YYSTACKDEPTH 100
-#endif
-#define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
-#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
+} fts5YYMINORTYPE;
+#ifndef fts5YYSTACKDEPTH
+#define fts5YYSTACKDEPTH 100
+#endif
+#define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
+#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
#define sqlite3Fts5ParserARG_PARAM ,pParse
#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse;
#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse;
@@ -215894,88 +215894,88 @@ typedef union {
#define sqlite3Fts5ParserCTX_PARAM
#define sqlite3Fts5ParserCTX_FETCH
#define sqlite3Fts5ParserCTX_STORE
-#define fts5YYNSTATE 35
-#define fts5YYNRULE 28
+#define fts5YYNSTATE 35
+#define fts5YYNRULE 28
#define fts5YYNRULE_WITH_ACTION 28
-#define fts5YYNFTS5TOKEN 16
-#define fts5YY_MAX_SHIFT 34
-#define fts5YY_MIN_SHIFTREDUCE 52
-#define fts5YY_MAX_SHIFTREDUCE 79
-#define fts5YY_ERROR_ACTION 80
-#define fts5YY_ACCEPT_ACTION 81
-#define fts5YY_NO_ACTION 82
-#define fts5YY_MIN_REDUCE 83
-#define fts5YY_MAX_REDUCE 110
-/************* End control #defines *******************************************/
+#define fts5YYNFTS5TOKEN 16
+#define fts5YY_MAX_SHIFT 34
+#define fts5YY_MIN_SHIFTREDUCE 52
+#define fts5YY_MAX_SHIFTREDUCE 79
+#define fts5YY_ERROR_ACTION 80
+#define fts5YY_ACCEPT_ACTION 81
+#define fts5YY_NO_ACTION 82
+#define fts5YY_MIN_REDUCE 83
+#define fts5YY_MAX_REDUCE 110
+/************* End control #defines *******************************************/
#define fts5YY_NLOOKAHEAD ((int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0])))
-
-/* Define the fts5yytestcase() macro to be a no-op if is not already defined
-** otherwise.
-**
-** Applications can choose to define fts5yytestcase() in the %include section
-** to a macro that can assist in verifying code coverage. For production
-** code the fts5yytestcase() macro should be turned off. But it is useful
-** for testing.
-*/
-#ifndef fts5yytestcase
-# define fts5yytestcase(X)
-#endif
-
-
-/* Next are the 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
+
+/* Define the fts5yytestcase() macro to be a no-op if is not already defined
+** otherwise.
+**
+** Applications can choose to define fts5yytestcase() in the %include section
+** to a macro that can assist in verifying code coverage. For production
+** code the fts5yytestcase() macro should be turned off. But it is useful
+** for testing.
+*/
+#ifndef fts5yytestcase
+# define fts5yytestcase(X)
+#endif
+
+
+/* Next are the 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
** action integer.
-**
-** Suppose the action integer is N. Then the action is determined as
-** follows
-**
-** 0 <= N <= fts5YY_MAX_SHIFT Shift N. That is, push the lookahead
-** token onto the stack and goto state N.
-**
-** N between fts5YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
-** and fts5YY_MAX_SHIFTREDUCE reduce by rule N-fts5YY_MIN_SHIFTREDUCE.
-**
-** N == fts5YY_ERROR_ACTION A syntax error has occurred.
-**
-** N == fts5YY_ACCEPT_ACTION The parser accepts its input.
-**
-** N == fts5YY_NO_ACTION No such action. Denotes unused
-** slots in the fts5yy_action[] table.
-**
-** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE
-** and fts5YY_MAX_REDUCE
-**
-** The action table is constructed as a single large table named fts5yy_action[].
-** Given state S and lookahead X, the action is computed as either:
-**
-** (A) N = fts5yy_action[ fts5yy_shift_ofst[S] + X ]
-** (B) N = fts5yy_default[S]
-**
-** The (A) formula is preferred. The B formula is used instead if
-** fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X.
-**
-** The formulas above are for computing the action when the lookahead is
-** a terminal symbol. If the lookahead is a non-terminal (as occurs after
-** a reduce action) then the fts5yy_reduce_ofst[] array is used in place of
-** the fts5yy_shift_ofst[] array.
-**
-** The following are the tables generated in this section:
-**
-** fts5yy_action[] A single table containing all actions.
-** fts5yy_lookahead[] A table containing the lookahead for each entry in
-** fts5yy_action. Used to detect hash collisions.
-** fts5yy_shift_ofst[] For each state, the offset into fts5yy_action for
-** shifting terminals.
-** fts5yy_reduce_ofst[] For each state, the offset into fts5yy_action for
-** shifting non-terminals after a reduce.
-** fts5yy_default[] Default action for each state.
-**
-*********** Begin parsing tables **********************************************/
-#define fts5YY_ACTTAB_COUNT (105)
-static const fts5YYACTIONTYPE fts5yy_action[] = {
- /* 0 */ 81, 20, 96, 6, 28, 99, 98, 26, 26, 18,
- /* 10 */ 96, 6, 28, 17, 98, 56, 26, 19, 96, 6,
+**
+** Suppose the action integer is N. Then the action is determined as
+** follows
+**
+** 0 <= N <= fts5YY_MAX_SHIFT Shift N. That is, push the lookahead
+** token onto the stack and goto state N.
+**
+** N between fts5YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
+** and fts5YY_MAX_SHIFTREDUCE reduce by rule N-fts5YY_MIN_SHIFTREDUCE.
+**
+** N == fts5YY_ERROR_ACTION A syntax error has occurred.
+**
+** N == fts5YY_ACCEPT_ACTION The parser accepts its input.
+**
+** N == fts5YY_NO_ACTION No such action. Denotes unused
+** slots in the fts5yy_action[] table.
+**
+** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE
+** and fts5YY_MAX_REDUCE
+**
+** The action table is constructed as a single large table named fts5yy_action[].
+** Given state S and lookahead X, the action is computed as either:
+**
+** (A) N = fts5yy_action[ fts5yy_shift_ofst[S] + X ]
+** (B) N = fts5yy_default[S]
+**
+** The (A) formula is preferred. The B formula is used instead if
+** fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X.
+**
+** The formulas above are for computing the action when the lookahead is
+** a terminal symbol. If the lookahead is a non-terminal (as occurs after
+** a reduce action) then the fts5yy_reduce_ofst[] array is used in place of
+** the fts5yy_shift_ofst[] array.
+**
+** The following are the tables generated in this section:
+**
+** fts5yy_action[] A single table containing all actions.
+** fts5yy_lookahead[] A table containing the lookahead for each entry in
+** fts5yy_action. Used to detect hash collisions.
+** fts5yy_shift_ofst[] For each state, the offset into fts5yy_action for
+** shifting terminals.
+** fts5yy_reduce_ofst[] For each state, the offset into fts5yy_action for
+** shifting non-terminals after a reduce.
+** fts5yy_default[] Default action for each state.
+**
+*********** Begin parsing tables **********************************************/
+#define fts5YY_ACTTAB_COUNT (105)
+static const fts5YYACTIONTYPE fts5yy_action[] = {
+ /* 0 */ 81, 20, 96, 6, 28, 99, 98, 26, 26, 18,
+ /* 10 */ 96, 6, 28, 17, 98, 56, 26, 19, 96, 6,
/* 20 */ 28, 14, 98, 14, 26, 31, 92, 96, 6, 28,
/* 30 */ 108, 98, 25, 26, 21, 96, 6, 28, 78, 98,
/* 40 */ 58, 26, 29, 96, 6, 28, 107, 98, 22, 26,
@@ -215985,8 +215985,8 @@ static const fts5YYACTIONTYPE fts5yy_action[] = {
/* 80 */ 5, 3, 63, 5, 3, 62, 12, 2, 86, 13,
/* 90 */ 9, 30, 10, 10, 54, 57, 75, 78, 78, 53,
/* 100 */ 57, 15, 82, 82, 71,
-};
-static const fts5YYCODETYPE fts5yy_lookahead[] = {
+};
+static const fts5YYCODETYPE fts5yy_lookahead[] = {
/* 0 */ 16, 17, 18, 19, 20, 22, 22, 24, 24, 17,
/* 10 */ 18, 19, 20, 7, 22, 9, 24, 17, 18, 19,
/* 20 */ 20, 9, 22, 9, 24, 13, 17, 18, 19, 20,
@@ -216000,151 +216000,151 @@ static const fts5YYCODETYPE fts5yy_lookahead[] = {
/* 100 */ 9, 9, 27, 27, 11, 27, 27, 27, 27, 27,
/* 110 */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 120 */ 27,
-};
-#define fts5YY_SHIFT_COUNT (34)
-#define fts5YY_SHIFT_MIN (0)
+};
+#define fts5YY_SHIFT_COUNT (34)
+#define fts5YY_SHIFT_MIN (0)
#define fts5YY_SHIFT_MAX (93)
-static const unsigned char fts5yy_shift_ofst[] = {
+static const unsigned char fts5yy_shift_ofst[] = {
/* 0 */ 44, 44, 44, 44, 44, 44, 51, 77, 43, 12,
/* 10 */ 14, 83, 82, 14, 23, 23, 31, 31, 71, 74,
/* 20 */ 78, 81, 86, 91, 6, 53, 53, 60, 64, 68,
/* 30 */ 53, 87, 92, 53, 93,
-};
-#define fts5YY_REDUCE_COUNT (17)
+};
+#define fts5YY_REDUCE_COUNT (17)
#define fts5YY_REDUCE_MIN (-17)
#define fts5YY_REDUCE_MAX (67)
-static const signed char fts5yy_reduce_ofst[] = {
+static const signed char fts5yy_reduce_ofst[] = {
/* 0 */ -16, -8, 0, 9, 17, 25, 46, -17, -17, 37,
/* 10 */ 67, 4, 4, 8, 4, 20, 27, 38,
-};
-static const fts5YYACTIONTYPE fts5yy_default[] = {
- /* 0 */ 80, 80, 80, 80, 80, 80, 95, 80, 80, 105,
- /* 10 */ 80, 110, 110, 80, 110, 110, 80, 80, 80, 80,
- /* 20 */ 80, 91, 80, 80, 80, 101, 100, 80, 80, 90,
- /* 30 */ 103, 80, 80, 104, 80,
-};
-/********** End of lemon-generated parsing tables *****************************/
-
+};
+static const fts5YYACTIONTYPE fts5yy_default[] = {
+ /* 0 */ 80, 80, 80, 80, 80, 80, 95, 80, 80, 105,
+ /* 10 */ 80, 110, 110, 80, 110, 110, 80, 80, 80, 80,
+ /* 20 */ 80, 91, 80, 80, 80, 101, 100, 80, 80, 90,
+ /* 30 */ 103, 80, 80, 104, 80,
+};
+/********** End of lemon-generated parsing tables *****************************/
+
/* The next table maps tokens (terminal symbols) into fallback tokens.
-** If a construct like the following:
-**
-** %fallback ID X Y Z.
-**
-** appears in the grammar, then ID becomes a fallback token for X, Y,
-** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
-** but it does not parse, the type of the token is changed to ID and
-** the parse is retried before an error is thrown.
-**
-** This feature can be used, for example, to cause some keywords in a language
-** to revert to identifiers if they keyword does not apply in the context where
-** it appears.
-*/
-#ifdef fts5YYFALLBACK
-static const fts5YYCODETYPE fts5yyFallback[] = {
-};
-#endif /* fts5YYFALLBACK */
-
-/* The following structure represents a single element of the
-** parser's stack. Information stored includes:
-**
-** + The state number for the parser at this level of the stack.
-**
-** + The value of the token stored at this level of the stack.
-** (In other words, the "major" token.)
-**
-** + The semantic value stored at this level of the stack. This is
-** the information used by the action routines in the grammar.
-** It is sometimes called the "minor" token.
-**
-** After the "shift" half of a SHIFTREDUCE action, the stateno field
-** actually contains the reduce action for the second half of the
-** SHIFTREDUCE.
-*/
-struct fts5yyStackEntry {
- fts5YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
- fts5YYCODETYPE major; /* The major token value. This is the code
- ** number for the token at this stack level */
- fts5YYMINORTYPE minor; /* The user-supplied minor token value. This
- ** is the value of the token */
-};
-typedef struct fts5yyStackEntry fts5yyStackEntry;
-
-/* The state of the parser is completely contained in an instance of
-** the following structure */
-struct fts5yyParser {
- fts5yyStackEntry *fts5yytos; /* Pointer to top element of the stack */
-#ifdef fts5YYTRACKMAXSTACKDEPTH
- int fts5yyhwm; /* High-water mark of the stack */
-#endif
-#ifndef fts5YYNOERRORRECOVERY
- int fts5yyerrcnt; /* Shifts left before out of the error */
-#endif
- sqlite3Fts5ParserARG_SDECL /* A place to hold %extra_argument */
+** If a construct like the following:
+**
+** %fallback ID X Y Z.
+**
+** appears in the grammar, then ID becomes a fallback token for X, Y,
+** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
+** but it does not parse, the type of the token is changed to ID and
+** the parse is retried before an error is thrown.
+**
+** This feature can be used, for example, to cause some keywords in a language
+** to revert to identifiers if they keyword does not apply in the context where
+** it appears.
+*/
+#ifdef fts5YYFALLBACK
+static const fts5YYCODETYPE fts5yyFallback[] = {
+};
+#endif /* fts5YYFALLBACK */
+
+/* The following structure represents a single element of the
+** parser's stack. Information stored includes:
+**
+** + The state number for the parser at this level of the stack.
+**
+** + The value of the token stored at this level of the stack.
+** (In other words, the "major" token.)
+**
+** + The semantic value stored at this level of the stack. This is
+** the information used by the action routines in the grammar.
+** It is sometimes called the "minor" token.
+**
+** After the "shift" half of a SHIFTREDUCE action, the stateno field
+** actually contains the reduce action for the second half of the
+** SHIFTREDUCE.
+*/
+struct fts5yyStackEntry {
+ fts5YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
+ fts5YYCODETYPE major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ fts5YYMINORTYPE minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
+};
+typedef struct fts5yyStackEntry fts5yyStackEntry;
+
+/* The state of the parser is completely contained in an instance of
+** the following structure */
+struct fts5yyParser {
+ fts5yyStackEntry *fts5yytos; /* Pointer to top element of the stack */
+#ifdef fts5YYTRACKMAXSTACKDEPTH
+ int fts5yyhwm; /* High-water mark of the stack */
+#endif
+#ifndef fts5YYNOERRORRECOVERY
+ int fts5yyerrcnt; /* Shifts left before out of the error */
+#endif
+ sqlite3Fts5ParserARG_SDECL /* A place to hold %extra_argument */
sqlite3Fts5ParserCTX_SDECL /* A place to hold %extra_context */
-#if fts5YYSTACKDEPTH<=0
- int fts5yystksz; /* Current side of the stack */
- fts5yyStackEntry *fts5yystack; /* The parser's stack */
- fts5yyStackEntry fts5yystk0; /* First stack entry */
-#else
- fts5yyStackEntry fts5yystack[fts5YYSTACKDEPTH]; /* The parser's stack */
- fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
-#endif
-};
-typedef struct fts5yyParser fts5yyParser;
-
+#if fts5YYSTACKDEPTH<=0
+ int fts5yystksz; /* Current side of the stack */
+ fts5yyStackEntry *fts5yystack; /* The parser's stack */
+ fts5yyStackEntry fts5yystk0; /* First stack entry */
+#else
+ fts5yyStackEntry fts5yystack[fts5YYSTACKDEPTH]; /* The parser's stack */
+ fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
+#endif
+};
+typedef struct fts5yyParser fts5yyParser;
+
/* #include <assert.h> */
-#ifndef NDEBUG
-/* #include <stdio.h> */
-static FILE *fts5yyTraceFILE = 0;
-static char *fts5yyTracePrompt = 0;
-#endif /* NDEBUG */
-
-#ifndef NDEBUG
-/*
-** Turn parser tracing on by giving a stream to which to write the trace
-** and a prompt to preface each trace message. Tracing is turned off
+#ifndef NDEBUG
+/* #include <stdio.h> */
+static FILE *fts5yyTraceFILE = 0;
+static char *fts5yyTracePrompt = 0;
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/*
+** Turn parser tracing on by giving a stream to which to write the trace
+** and a prompt to preface each trace message. Tracing is turned off
** by making either argument NULL
-**
-** Inputs:
-** <ul>
-** <li> A FILE* to which trace output should be written.
-** If NULL, then tracing is turned off.
-** <li> A prefix string written at the beginning of every
-** line of trace output. If NULL, then tracing is
-** turned off.
-** </ul>
-**
-** Outputs:
-** None.
-*/
-static void sqlite3Fts5ParserTrace(FILE *TraceFILE, char *zTracePrompt){
- fts5yyTraceFILE = TraceFILE;
- fts5yyTracePrompt = zTracePrompt;
- if( fts5yyTraceFILE==0 ) fts5yyTracePrompt = 0;
- else if( fts5yyTracePrompt==0 ) fts5yyTraceFILE = 0;
-}
-#endif /* NDEBUG */
-
-#if defined(fts5YYCOVERAGE) || !defined(NDEBUG)
-/* For tracing shifts, the names of all terminals and nonterminals
-** are required. The following table supplies these names */
+**
+** Inputs:
+** <ul>
+** <li> A FILE* to which trace output should be written.
+** If NULL, then tracing is turned off.
+** <li> A prefix string written at the beginning of every
+** line of trace output. If NULL, then tracing is
+** turned off.
+** </ul>
+**
+** Outputs:
+** None.
+*/
+static void sqlite3Fts5ParserTrace(FILE *TraceFILE, char *zTracePrompt){
+ fts5yyTraceFILE = TraceFILE;
+ fts5yyTracePrompt = zTracePrompt;
+ if( fts5yyTraceFILE==0 ) fts5yyTracePrompt = 0;
+ else if( fts5yyTracePrompt==0 ) fts5yyTraceFILE = 0;
+}
+#endif /* NDEBUG */
+
+#if defined(fts5YYCOVERAGE) || !defined(NDEBUG)
+/* For tracing shifts, the names of all terminals and nonterminals
+** are required. The following table supplies these names */
static const char *const fts5yyTokenName[] = {
- /* 0 */ "$",
- /* 1 */ "OR",
- /* 2 */ "AND",
- /* 3 */ "NOT",
- /* 4 */ "TERM",
- /* 5 */ "COLON",
- /* 6 */ "MINUS",
- /* 7 */ "LCP",
- /* 8 */ "RCP",
- /* 9 */ "STRING",
- /* 10 */ "LP",
- /* 11 */ "RP",
- /* 12 */ "CARET",
- /* 13 */ "COMMA",
- /* 14 */ "PLUS",
- /* 15 */ "STAR",
+ /* 0 */ "$",
+ /* 1 */ "OR",
+ /* 2 */ "AND",
+ /* 3 */ "NOT",
+ /* 4 */ "TERM",
+ /* 5 */ "COLON",
+ /* 6 */ "MINUS",
+ /* 7 */ "LCP",
+ /* 8 */ "RCP",
+ /* 9 */ "STRING",
+ /* 10 */ "LP",
+ /* 11 */ "RP",
+ /* 12 */ "CARET",
+ /* 13 */ "COMMA",
+ /* 14 */ "PLUS",
+ /* 15 */ "STAR",
/* 16 */ "input",
/* 17 */ "expr",
/* 18 */ "cnearset",
@@ -216156,128 +216156,128 @@ static const char *const fts5yyTokenName[] = {
/* 24 */ "phrase",
/* 25 */ "neardist_opt",
/* 26 */ "star_opt",
-};
-#endif /* defined(fts5YYCOVERAGE) || !defined(NDEBUG) */
-
-#ifndef NDEBUG
-/* For tracing reduce actions, the names of all rules are required.
-*/
-static const char *const fts5yyRuleName[] = {
- /* 0 */ "input ::= expr",
- /* 1 */ "colset ::= MINUS LCP colsetlist RCP",
- /* 2 */ "colset ::= LCP colsetlist RCP",
- /* 3 */ "colset ::= STRING",
- /* 4 */ "colset ::= MINUS STRING",
- /* 5 */ "colsetlist ::= colsetlist STRING",
- /* 6 */ "colsetlist ::= STRING",
- /* 7 */ "expr ::= expr AND expr",
- /* 8 */ "expr ::= expr OR expr",
- /* 9 */ "expr ::= expr NOT expr",
- /* 10 */ "expr ::= colset COLON LP expr RP",
- /* 11 */ "expr ::= LP expr RP",
- /* 12 */ "expr ::= exprlist",
- /* 13 */ "exprlist ::= cnearset",
- /* 14 */ "exprlist ::= exprlist cnearset",
- /* 15 */ "cnearset ::= nearset",
- /* 16 */ "cnearset ::= colset COLON nearset",
- /* 17 */ "nearset ::= phrase",
- /* 18 */ "nearset ::= CARET phrase",
- /* 19 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
- /* 20 */ "nearphrases ::= phrase",
- /* 21 */ "nearphrases ::= nearphrases phrase",
- /* 22 */ "neardist_opt ::=",
- /* 23 */ "neardist_opt ::= COMMA STRING",
- /* 24 */ "phrase ::= phrase PLUS STRING star_opt",
- /* 25 */ "phrase ::= STRING star_opt",
- /* 26 */ "star_opt ::= STAR",
- /* 27 */ "star_opt ::=",
-};
-#endif /* NDEBUG */
-
-
-#if fts5YYSTACKDEPTH<=0
-/*
-** Try to increase the size of the parser stack. Return the number
-** of errors. Return 0 on success.
-*/
-static int fts5yyGrowStack(fts5yyParser *p){
- int newSize;
- int idx;
- fts5yyStackEntry *pNew;
-
- newSize = p->fts5yystksz*2 + 100;
- idx = p->fts5yytos ? (int)(p->fts5yytos - p->fts5yystack) : 0;
- if( p->fts5yystack==&p->fts5yystk0 ){
- pNew = malloc(newSize*sizeof(pNew[0]));
- if( pNew ) pNew[0] = p->fts5yystk0;
- }else{
- pNew = realloc(p->fts5yystack, newSize*sizeof(pNew[0]));
- }
- if( pNew ){
- p->fts5yystack = pNew;
- p->fts5yytos = &p->fts5yystack[idx];
-#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE,"%sStack grows from %d to %d entries.\n",
- fts5yyTracePrompt, p->fts5yystksz, newSize);
- }
-#endif
- p->fts5yystksz = newSize;
- }
+};
+#endif /* defined(fts5YYCOVERAGE) || !defined(NDEBUG) */
+
+#ifndef NDEBUG
+/* For tracing reduce actions, the names of all rules are required.
+*/
+static const char *const fts5yyRuleName[] = {
+ /* 0 */ "input ::= expr",
+ /* 1 */ "colset ::= MINUS LCP colsetlist RCP",
+ /* 2 */ "colset ::= LCP colsetlist RCP",
+ /* 3 */ "colset ::= STRING",
+ /* 4 */ "colset ::= MINUS STRING",
+ /* 5 */ "colsetlist ::= colsetlist STRING",
+ /* 6 */ "colsetlist ::= STRING",
+ /* 7 */ "expr ::= expr AND expr",
+ /* 8 */ "expr ::= expr OR expr",
+ /* 9 */ "expr ::= expr NOT expr",
+ /* 10 */ "expr ::= colset COLON LP expr RP",
+ /* 11 */ "expr ::= LP expr RP",
+ /* 12 */ "expr ::= exprlist",
+ /* 13 */ "exprlist ::= cnearset",
+ /* 14 */ "exprlist ::= exprlist cnearset",
+ /* 15 */ "cnearset ::= nearset",
+ /* 16 */ "cnearset ::= colset COLON nearset",
+ /* 17 */ "nearset ::= phrase",
+ /* 18 */ "nearset ::= CARET phrase",
+ /* 19 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
+ /* 20 */ "nearphrases ::= phrase",
+ /* 21 */ "nearphrases ::= nearphrases phrase",
+ /* 22 */ "neardist_opt ::=",
+ /* 23 */ "neardist_opt ::= COMMA STRING",
+ /* 24 */ "phrase ::= phrase PLUS STRING star_opt",
+ /* 25 */ "phrase ::= STRING star_opt",
+ /* 26 */ "star_opt ::= STAR",
+ /* 27 */ "star_opt ::=",
+};
+#endif /* NDEBUG */
+
+
+#if fts5YYSTACKDEPTH<=0
+/*
+** Try to increase the size of the parser stack. Return the number
+** of errors. Return 0 on success.
+*/
+static int fts5yyGrowStack(fts5yyParser *p){
+ int newSize;
+ int idx;
+ fts5yyStackEntry *pNew;
+
+ newSize = p->fts5yystksz*2 + 100;
+ idx = p->fts5yytos ? (int)(p->fts5yytos - p->fts5yystack) : 0;
+ if( p->fts5yystack==&p->fts5yystk0 ){
+ pNew = malloc(newSize*sizeof(pNew[0]));
+ if( pNew ) pNew[0] = p->fts5yystk0;
+ }else{
+ pNew = realloc(p->fts5yystack, newSize*sizeof(pNew[0]));
+ }
+ if( pNew ){
+ p->fts5yystack = pNew;
+ p->fts5yytos = &p->fts5yystack[idx];
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sStack grows from %d to %d entries.\n",
+ fts5yyTracePrompt, p->fts5yystksz, newSize);
+ }
+#endif
+ p->fts5yystksz = newSize;
+ }
return pNew==0;
-}
-#endif
-
-/* Datatype of the argument to the memory allocated passed as the
-** second argument to sqlite3Fts5ParserAlloc() below. This can be changed by
-** putting an appropriate #define in the %include section of the input
-** grammar.
-*/
-#ifndef fts5YYMALLOCARGTYPE
-# define fts5YYMALLOCARGTYPE size_t
-#endif
-
-/* Initialize a new parser that has already been allocated.
-*/
+}
+#endif
+
+/* Datatype of the argument to the memory allocated passed as the
+** second argument to sqlite3Fts5ParserAlloc() below. This can be changed by
+** putting an appropriate #define in the %include section of the input
+** grammar.
+*/
+#ifndef fts5YYMALLOCARGTYPE
+# define fts5YYMALLOCARGTYPE size_t
+#endif
+
+/* Initialize a new parser that has already been allocated.
+*/
static void sqlite3Fts5ParserInit(void *fts5yypRawParser sqlite3Fts5ParserCTX_PDECL){
fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yypRawParser;
sqlite3Fts5ParserCTX_STORE
-#ifdef fts5YYTRACKMAXSTACKDEPTH
+#ifdef fts5YYTRACKMAXSTACKDEPTH
fts5yypParser->fts5yyhwm = 0;
-#endif
-#if fts5YYSTACKDEPTH<=0
+#endif
+#if fts5YYSTACKDEPTH<=0
fts5yypParser->fts5yytos = NULL;
fts5yypParser->fts5yystack = NULL;
fts5yypParser->fts5yystksz = 0;
if( fts5yyGrowStack(fts5yypParser) ){
fts5yypParser->fts5yystack = &fts5yypParser->fts5yystk0;
fts5yypParser->fts5yystksz = 1;
- }
-#endif
-#ifndef fts5YYNOERRORRECOVERY
+ }
+#endif
+#ifndef fts5YYNOERRORRECOVERY
fts5yypParser->fts5yyerrcnt = -1;
-#endif
+#endif
fts5yypParser->fts5yytos = fts5yypParser->fts5yystack;
fts5yypParser->fts5yystack[0].stateno = 0;
fts5yypParser->fts5yystack[0].major = 0;
-#if fts5YYSTACKDEPTH>0
+#if fts5YYSTACKDEPTH>0
fts5yypParser->fts5yystackEnd = &fts5yypParser->fts5yystack[fts5YYSTACKDEPTH-1];
-#endif
-}
-
-#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
-/*
-** This function allocates a new parser.
-** The only argument is a pointer to a function which works like
-** malloc.
-**
-** Inputs:
-** A pointer to the function used to allocate memory.
-**
-** Outputs:
-** A pointer to a parser. This pointer is used in subsequent calls
-** to sqlite3Fts5Parser and sqlite3Fts5ParserFree.
-*/
+#endif
+}
+
+#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
+/*
+** This function allocates a new parser.
+** The only argument is a pointer to a function which works like
+** malloc.
+**
+** Inputs:
+** A pointer to the function used to allocate memory.
+**
+** Outputs:
+** A pointer to a parser. This pointer is used in subsequent calls
+** to sqlite3Fts5Parser and sqlite3Fts5ParserFree.
+*/
static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE) sqlite3Fts5ParserCTX_PDECL){
fts5yyParser *fts5yypParser;
fts5yypParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) );
@@ -216286,350 +216286,350 @@ static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE) sql
sqlite3Fts5ParserInit(fts5yypParser sqlite3Fts5ParserCTX_PARAM);
}
return (void*)fts5yypParser;
-}
-#endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */
-
-
-/* The following function deletes the "minor type" or semantic value
-** associated with a symbol. The symbol can be either a terminal
-** or nonterminal. "fts5yymajor" is the symbol code, and "fts5yypminor" is
+}
+#endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */
+
+
+/* The following function deletes the "minor type" or semantic value
+** associated with a symbol. The symbol can be either a terminal
+** or nonterminal. "fts5yymajor" is the symbol code, and "fts5yypminor" is
** a pointer to the value to be deleted. The code used to do the
-** deletions is derived from the %destructor and/or %token_destructor
-** directives of the input grammar.
-*/
-static void fts5yy_destructor(
- fts5yyParser *fts5yypParser, /* The parser */
- fts5YYCODETYPE fts5yymajor, /* Type code for object to destroy */
- fts5YYMINORTYPE *fts5yypminor /* The object to be destroyed */
-){
+** deletions is derived from the %destructor and/or %token_destructor
+** directives of the input grammar.
+*/
+static void fts5yy_destructor(
+ fts5yyParser *fts5yypParser, /* The parser */
+ fts5YYCODETYPE fts5yymajor, /* Type code for object to destroy */
+ fts5YYMINORTYPE *fts5yypminor /* The object to be destroyed */
+){
sqlite3Fts5ParserARG_FETCH
sqlite3Fts5ParserCTX_FETCH
- switch( fts5yymajor ){
- /* Here is inserted the actions which take place when a
- ** terminal or non-terminal is destroyed. This can happen
- ** when the symbol is popped from the stack during a
+ switch( fts5yymajor ){
+ /* Here is inserted the actions which take place when a
+ ** terminal or non-terminal is destroyed. This can happen
+ ** when the symbol is popped from the stack during a
** reduce or during error processing or when a parser is
- ** being destroyed before it is finished parsing.
- **
- ** Note: during a reduce, the only symbols destroyed are those
- ** which appear on the RHS of the rule, but which are *not* used
- ** inside the C code.
- */
-/********* Begin destructor definitions ***************************************/
+ ** being destroyed before it is finished parsing.
+ **
+ ** Note: during a reduce, the only symbols destroyed are those
+ ** which appear on the RHS of the rule, but which are *not* used
+ ** inside the C code.
+ */
+/********* Begin destructor definitions ***************************************/
case 16: /* input */
-{
+{
(void)pParse;
-}
- break;
+}
+ break;
case 17: /* expr */
case 18: /* cnearset */
case 19: /* exprlist */
-{
+{
sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24));
-}
- break;
+}
+ break;
case 20: /* colset */
case 21: /* colsetlist */
-{
+{
sqlite3_free((fts5yypminor->fts5yy11));
-}
- break;
+}
+ break;
case 22: /* nearset */
case 23: /* nearphrases */
-{
+{
sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
-}
- break;
+}
+ break;
case 24: /* phrase */
-{
+{
sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53));
-}
- break;
-/********* End destructor definitions *****************************************/
- default: break; /* If no destructor action specified: do nothing */
- }
-}
-
-/*
-** Pop the parser's stack once.
-**
-** If there is a destructor routine associated with the token which
-** is popped from the stack, then call it.
-*/
-static void fts5yy_pop_parser_stack(fts5yyParser *pParser){
- fts5yyStackEntry *fts5yytos;
- assert( pParser->fts5yytos!=0 );
- assert( pParser->fts5yytos > pParser->fts5yystack );
- fts5yytos = pParser->fts5yytos--;
-#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE,"%sPopping %s\n",
- fts5yyTracePrompt,
- fts5yyTokenName[fts5yytos->major]);
- }
-#endif
- fts5yy_destructor(pParser, fts5yytos->major, &fts5yytos->minor);
-}
-
-/*
-** Clear all secondary memory allocations from the parser
-*/
-static void sqlite3Fts5ParserFinalize(void *p){
- fts5yyParser *pParser = (fts5yyParser*)p;
- while( pParser->fts5yytos>pParser->fts5yystack ) fts5yy_pop_parser_stack(pParser);
-#if fts5YYSTACKDEPTH<=0
- if( pParser->fts5yystack!=&pParser->fts5yystk0 ) free(pParser->fts5yystack);
-#endif
-}
-
-#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
-/*
-** Deallocate and destroy a parser. Destructors are called for
-** all stack elements before shutting the parser down.
-**
-** If the fts5YYPARSEFREENEVERNULL macro exists (for example because it
-** is defined in a %include section of the input grammar) then it is
-** assumed that the input pointer is never NULL.
-*/
-static void sqlite3Fts5ParserFree(
- void *p, /* The parser to be deleted */
- void (*freeProc)(void*) /* Function used to reclaim memory */
-){
-#ifndef fts5YYPARSEFREENEVERNULL
- if( p==0 ) return;
-#endif
- sqlite3Fts5ParserFinalize(p);
- (*freeProc)(p);
-}
-#endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */
-
-/*
-** Return the peak depth of the stack for a parser.
-*/
-#ifdef fts5YYTRACKMAXSTACKDEPTH
-static int sqlite3Fts5ParserStackPeak(void *p){
- fts5yyParser *pParser = (fts5yyParser*)p;
- return pParser->fts5yyhwm;
-}
-#endif
-
-/* This array of booleans keeps track of the parser statement
-** coverage. The element fts5yycoverage[X][Y] is set when the parser
-** is in state X and has a lookahead token Y. In a well-tested
-** systems, every element of this matrix should end up being set.
-*/
-#if defined(fts5YYCOVERAGE)
-static unsigned char fts5yycoverage[fts5YYNSTATE][fts5YYNFTS5TOKEN];
-#endif
-
-/*
-** Write into out a description of every state/lookahead combination that
-**
-** (1) has not been used by the parser, and
-** (2) is not a syntax error.
-**
-** Return the number of missed state/lookahead combinations.
-*/
-#if defined(fts5YYCOVERAGE)
-static int sqlite3Fts5ParserCoverage(FILE *out){
- int stateno, iLookAhead, i;
- int nMissed = 0;
- for(stateno=0; stateno<fts5YYNSTATE; stateno++){
- i = fts5yy_shift_ofst[stateno];
- for(iLookAhead=0; iLookAhead<fts5YYNFTS5TOKEN; iLookAhead++){
- if( fts5yy_lookahead[i+iLookAhead]!=iLookAhead ) continue;
- if( fts5yycoverage[stateno][iLookAhead]==0 ) nMissed++;
- if( out ){
- fprintf(out,"State %d lookahead %s %s\n", stateno,
- fts5yyTokenName[iLookAhead],
- fts5yycoverage[stateno][iLookAhead] ? "ok" : "missed");
- }
- }
- }
- return nMissed;
-}
-#endif
-
-/*
-** Find the appropriate action for a parser given the terminal
-** look-ahead token iLookAhead.
-*/
+}
+ break;
+/********* End destructor definitions *****************************************/
+ default: break; /* If no destructor action specified: do nothing */
+ }
+}
+
+/*
+** Pop the parser's stack once.
+**
+** If there is a destructor routine associated with the token which
+** is popped from the stack, then call it.
+*/
+static void fts5yy_pop_parser_stack(fts5yyParser *pParser){
+ fts5yyStackEntry *fts5yytos;
+ assert( pParser->fts5yytos!=0 );
+ assert( pParser->fts5yytos > pParser->fts5yystack );
+ fts5yytos = pParser->fts5yytos--;
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sPopping %s\n",
+ fts5yyTracePrompt,
+ fts5yyTokenName[fts5yytos->major]);
+ }
+#endif
+ fts5yy_destructor(pParser, fts5yytos->major, &fts5yytos->minor);
+}
+
+/*
+** Clear all secondary memory allocations from the parser
+*/
+static void sqlite3Fts5ParserFinalize(void *p){
+ fts5yyParser *pParser = (fts5yyParser*)p;
+ while( pParser->fts5yytos>pParser->fts5yystack ) fts5yy_pop_parser_stack(pParser);
+#if fts5YYSTACKDEPTH<=0
+ if( pParser->fts5yystack!=&pParser->fts5yystk0 ) free(pParser->fts5yystack);
+#endif
+}
+
+#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
+/*
+** Deallocate and destroy a parser. Destructors are called for
+** all stack elements before shutting the parser down.
+**
+** If the fts5YYPARSEFREENEVERNULL macro exists (for example because it
+** is defined in a %include section of the input grammar) then it is
+** assumed that the input pointer is never NULL.
+*/
+static void sqlite3Fts5ParserFree(
+ void *p, /* The parser to be deleted */
+ void (*freeProc)(void*) /* Function used to reclaim memory */
+){
+#ifndef fts5YYPARSEFREENEVERNULL
+ if( p==0 ) return;
+#endif
+ sqlite3Fts5ParserFinalize(p);
+ (*freeProc)(p);
+}
+#endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */
+
+/*
+** Return the peak depth of the stack for a parser.
+*/
+#ifdef fts5YYTRACKMAXSTACKDEPTH
+static int sqlite3Fts5ParserStackPeak(void *p){
+ fts5yyParser *pParser = (fts5yyParser*)p;
+ return pParser->fts5yyhwm;
+}
+#endif
+
+/* This array of booleans keeps track of the parser statement
+** coverage. The element fts5yycoverage[X][Y] is set when the parser
+** is in state X and has a lookahead token Y. In a well-tested
+** systems, every element of this matrix should end up being set.
+*/
+#if defined(fts5YYCOVERAGE)
+static unsigned char fts5yycoverage[fts5YYNSTATE][fts5YYNFTS5TOKEN];
+#endif
+
+/*
+** Write into out a description of every state/lookahead combination that
+**
+** (1) has not been used by the parser, and
+** (2) is not a syntax error.
+**
+** Return the number of missed state/lookahead combinations.
+*/
+#if defined(fts5YYCOVERAGE)
+static int sqlite3Fts5ParserCoverage(FILE *out){
+ int stateno, iLookAhead, i;
+ int nMissed = 0;
+ for(stateno=0; stateno<fts5YYNSTATE; stateno++){
+ i = fts5yy_shift_ofst[stateno];
+ for(iLookAhead=0; iLookAhead<fts5YYNFTS5TOKEN; iLookAhead++){
+ if( fts5yy_lookahead[i+iLookAhead]!=iLookAhead ) continue;
+ if( fts5yycoverage[stateno][iLookAhead]==0 ) nMissed++;
+ if( out ){
+ fprintf(out,"State %d lookahead %s %s\n", stateno,
+ fts5yyTokenName[iLookAhead],
+ fts5yycoverage[stateno][iLookAhead] ? "ok" : "missed");
+ }
+ }
+ }
+ return nMissed;
+}
+#endif
+
+/*
+** Find the appropriate action for a parser given the terminal
+** look-ahead token iLookAhead.
+*/
static fts5YYACTIONTYPE fts5yy_find_shift_action(
fts5YYCODETYPE iLookAhead, /* The look-ahead token */
fts5YYACTIONTYPE stateno /* Current state number */
-){
- int i;
-
- if( stateno>fts5YY_MAX_SHIFT ) return stateno;
- assert( stateno <= fts5YY_SHIFT_COUNT );
-#if defined(fts5YYCOVERAGE)
- fts5yycoverage[stateno][iLookAhead] = 1;
-#endif
- do{
- i = fts5yy_shift_ofst[stateno];
+){
+ int i;
+
+ if( stateno>fts5YY_MAX_SHIFT ) return stateno;
+ assert( stateno <= fts5YY_SHIFT_COUNT );
+#if defined(fts5YYCOVERAGE)
+ fts5yycoverage[stateno][iLookAhead] = 1;
+#endif
+ do{
+ i = fts5yy_shift_ofst[stateno];
assert( i>=0 );
assert( i<=fts5YY_ACTTAB_COUNT );
assert( i+fts5YYNFTS5TOKEN<=(int)fts5YY_NLOOKAHEAD );
- assert( iLookAhead!=fts5YYNOCODE );
- assert( iLookAhead < fts5YYNFTS5TOKEN );
- i += iLookAhead;
+ assert( iLookAhead!=fts5YYNOCODE );
+ assert( iLookAhead < fts5YYNFTS5TOKEN );
+ i += iLookAhead;
assert( i<(int)fts5YY_NLOOKAHEAD );
if( fts5yy_lookahead[i]!=iLookAhead ){
-#ifdef fts5YYFALLBACK
- fts5YYCODETYPE iFallback; /* Fallback token */
+#ifdef fts5YYFALLBACK
+ fts5YYCODETYPE iFallback; /* Fallback token */
assert( iLookAhead<sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0]) );
iFallback = fts5yyFallback[iLookAhead];
if( iFallback!=0 ){
-#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE, "%sFALLBACK %s => %s\n",
- fts5yyTracePrompt, fts5yyTokenName[iLookAhead], fts5yyTokenName[iFallback]);
- }
-#endif
- assert( fts5yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
- iLookAhead = iFallback;
- continue;
- }
-#endif
-#ifdef fts5YYWILDCARD
- {
- int j = i - iLookAhead + fts5YYWILDCARD;
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE, "%sFALLBACK %s => %s\n",
+ fts5yyTracePrompt, fts5yyTokenName[iLookAhead], fts5yyTokenName[iFallback]);
+ }
+#endif
+ assert( fts5yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
+ iLookAhead = iFallback;
+ continue;
+ }
+#endif
+#ifdef fts5YYWILDCARD
+ {
+ int j = i - iLookAhead + fts5YYWILDCARD;
assert( j<(int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0])) );
if( fts5yy_lookahead[j]==fts5YYWILDCARD && iLookAhead>0 ){
-#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE, "%sWILDCARD %s => %s\n",
- fts5yyTracePrompt, fts5yyTokenName[iLookAhead],
- fts5yyTokenName[fts5YYWILDCARD]);
- }
-#endif /* NDEBUG */
- return fts5yy_action[j];
- }
- }
-#endif /* fts5YYWILDCARD */
- return fts5yy_default[stateno];
- }else{
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE, "%sWILDCARD %s => %s\n",
+ fts5yyTracePrompt, fts5yyTokenName[iLookAhead],
+ fts5yyTokenName[fts5YYWILDCARD]);
+ }
+#endif /* NDEBUG */
+ return fts5yy_action[j];
+ }
+ }
+#endif /* fts5YYWILDCARD */
+ return fts5yy_default[stateno];
+ }else{
assert( i>=0 && i<(int)(sizeof(fts5yy_action)/sizeof(fts5yy_action[0])) );
- return fts5yy_action[i];
- }
- }while(1);
-}
-
-/*
-** Find the appropriate action for a parser given the non-terminal
-** look-ahead token iLookAhead.
-*/
+ return fts5yy_action[i];
+ }
+ }while(1);
+}
+
+/*
+** Find the appropriate action for a parser given the non-terminal
+** look-ahead token iLookAhead.
+*/
static fts5YYACTIONTYPE fts5yy_find_reduce_action(
fts5YYACTIONTYPE stateno, /* Current state number */
- fts5YYCODETYPE iLookAhead /* The look-ahead token */
-){
- int i;
-#ifdef fts5YYERRORSYMBOL
- if( stateno>fts5YY_REDUCE_COUNT ){
- return fts5yy_default[stateno];
- }
-#else
- assert( stateno<=fts5YY_REDUCE_COUNT );
-#endif
- i = fts5yy_reduce_ofst[stateno];
- assert( iLookAhead!=fts5YYNOCODE );
- i += iLookAhead;
-#ifdef fts5YYERRORSYMBOL
- if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
- return fts5yy_default[stateno];
- }
-#else
- assert( i>=0 && i<fts5YY_ACTTAB_COUNT );
- assert( fts5yy_lookahead[i]==iLookAhead );
-#endif
- return fts5yy_action[i];
-}
-
-/*
-** The following routine is called if the stack overflows.
-*/
-static void fts5yyStackOverflow(fts5yyParser *fts5yypParser){
+ fts5YYCODETYPE iLookAhead /* The look-ahead token */
+){
+ int i;
+#ifdef fts5YYERRORSYMBOL
+ if( stateno>fts5YY_REDUCE_COUNT ){
+ return fts5yy_default[stateno];
+ }
+#else
+ assert( stateno<=fts5YY_REDUCE_COUNT );
+#endif
+ i = fts5yy_reduce_ofst[stateno];
+ assert( iLookAhead!=fts5YYNOCODE );
+ i += iLookAhead;
+#ifdef fts5YYERRORSYMBOL
+ if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
+ return fts5yy_default[stateno];
+ }
+#else
+ assert( i>=0 && i<fts5YY_ACTTAB_COUNT );
+ assert( fts5yy_lookahead[i]==iLookAhead );
+#endif
+ return fts5yy_action[i];
+}
+
+/*
+** The following routine is called if the stack overflows.
+*/
+static void fts5yyStackOverflow(fts5yyParser *fts5yypParser){
sqlite3Fts5ParserARG_FETCH
sqlite3Fts5ParserCTX_FETCH
-#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE,"%sStack Overflow!\n",fts5yyTracePrompt);
- }
-#endif
- while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ) fts5yy_pop_parser_stack(fts5yypParser);
- /* Here code is inserted which will execute if the parser
- ** stack every overflows */
-/******** Begin %stack_overflow code ******************************************/
-
- sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
-/******** End %stack_overflow code ********************************************/
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sStack Overflow!\n",fts5yyTracePrompt);
+ }
+#endif
+ while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ) fts5yy_pop_parser_stack(fts5yypParser);
+ /* Here code is inserted which will execute if the parser
+ ** stack every overflows */
+/******** Begin %stack_overflow code ******************************************/
+
+ sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
+/******** End %stack_overflow code ********************************************/
sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument var */
sqlite3Fts5ParserCTX_STORE
-}
-
-/*
-** Print tracing information for a SHIFT action
-*/
-#ifndef NDEBUG
-static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState, const char *zTag){
- if( fts5yyTraceFILE ){
- if( fts5yyNewState<fts5YYNSTATE ){
- fprintf(fts5yyTraceFILE,"%s%s '%s', go to state %d\n",
- fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major],
- fts5yyNewState);
- }else{
- fprintf(fts5yyTraceFILE,"%s%s '%s', pending reduce %d\n",
- fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major],
- fts5yyNewState - fts5YY_MIN_REDUCE);
- }
- }
-}
-#else
-# define fts5yyTraceShift(X,Y,Z)
-#endif
-
-/*
-** Perform a shift action.
-*/
-static void fts5yy_shift(
- fts5yyParser *fts5yypParser, /* The parser to be shifted */
+}
+
+/*
+** Print tracing information for a SHIFT action
+*/
+#ifndef NDEBUG
+static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState, const char *zTag){
+ if( fts5yyTraceFILE ){
+ if( fts5yyNewState<fts5YYNSTATE ){
+ fprintf(fts5yyTraceFILE,"%s%s '%s', go to state %d\n",
+ fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major],
+ fts5yyNewState);
+ }else{
+ fprintf(fts5yyTraceFILE,"%s%s '%s', pending reduce %d\n",
+ fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major],
+ fts5yyNewState - fts5YY_MIN_REDUCE);
+ }
+ }
+}
+#else
+# define fts5yyTraceShift(X,Y,Z)
+#endif
+
+/*
+** Perform a shift action.
+*/
+static void fts5yy_shift(
+ fts5yyParser *fts5yypParser, /* The parser to be shifted */
fts5YYACTIONTYPE fts5yyNewState, /* The new state to shift in */
fts5YYCODETYPE fts5yyMajor, /* The major token to shift in */
- sqlite3Fts5ParserFTS5TOKENTYPE fts5yyMinor /* The minor token to shift in */
-){
- fts5yyStackEntry *fts5yytos;
- fts5yypParser->fts5yytos++;
-#ifdef fts5YYTRACKMAXSTACKDEPTH
- if( (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)>fts5yypParser->fts5yyhwm ){
- fts5yypParser->fts5yyhwm++;
- assert( fts5yypParser->fts5yyhwm == (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack) );
- }
-#endif
+ sqlite3Fts5ParserFTS5TOKENTYPE fts5yyMinor /* The minor token to shift in */
+){
+ fts5yyStackEntry *fts5yytos;
+ fts5yypParser->fts5yytos++;
+#ifdef fts5YYTRACKMAXSTACKDEPTH
+ if( (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)>fts5yypParser->fts5yyhwm ){
+ fts5yypParser->fts5yyhwm++;
+ assert( fts5yypParser->fts5yyhwm == (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack) );
+ }
+#endif
#if fts5YYSTACKDEPTH>0
- if( fts5yypParser->fts5yytos>fts5yypParser->fts5yystackEnd ){
- fts5yypParser->fts5yytos--;
- fts5yyStackOverflow(fts5yypParser);
- return;
- }
-#else
- if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz] ){
- if( fts5yyGrowStack(fts5yypParser) ){
- fts5yypParser->fts5yytos--;
- fts5yyStackOverflow(fts5yypParser);
- return;
- }
- }
-#endif
- if( fts5yyNewState > fts5YY_MAX_SHIFT ){
- fts5yyNewState += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
- }
- fts5yytos = fts5yypParser->fts5yytos;
+ if( fts5yypParser->fts5yytos>fts5yypParser->fts5yystackEnd ){
+ fts5yypParser->fts5yytos--;
+ fts5yyStackOverflow(fts5yypParser);
+ return;
+ }
+#else
+ if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz] ){
+ if( fts5yyGrowStack(fts5yypParser) ){
+ fts5yypParser->fts5yytos--;
+ fts5yyStackOverflow(fts5yypParser);
+ return;
+ }
+ }
+#endif
+ if( fts5yyNewState > fts5YY_MAX_SHIFT ){
+ fts5yyNewState += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
+ }
+ fts5yytos = fts5yypParser->fts5yytos;
fts5yytos->stateno = fts5yyNewState;
fts5yytos->major = fts5yyMajor;
- fts5yytos->minor.fts5yy0 = fts5yyMinor;
- fts5yyTraceShift(fts5yypParser, fts5yyNewState, "Shift");
-}
-
+ fts5yytos->minor.fts5yy0 = fts5yyMinor;
+ fts5yyTraceShift(fts5yypParser, fts5yyNewState, "Shift");
+}
+
/* For rule J, fts5yyRuleInfoLhs[J] contains the symbol on the left-hand side
** of that rule */
static const fts5YYCODETYPE fts5yyRuleInfoLhs[] = {
@@ -216661,8 +216661,8 @@ static const fts5YYCODETYPE fts5yyRuleInfoLhs[] = {
24, /* (25) phrase ::= STRING star_opt */
26, /* (26) star_opt ::= STAR */
26, /* (27) star_opt ::= */
-};
-
+};
+
/* For rule J, fts5yyRuleInfoNRhs[J] contains the negative of the number
** of symbols on the right-hand side of that rule. */
static const signed char fts5yyRuleInfoNRhs[] = {
@@ -216696,340 +216696,340 @@ static const signed char fts5yyRuleInfoNRhs[] = {
0, /* (27) star_opt ::= */
};
-static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */
-
-/*
-** Perform a reduce action and the shift that must immediately
-** follow the reduce.
-**
-** The fts5yyLookahead and fts5yyLookaheadToken parameters provide reduce actions
-** access to the lookahead token (if any). The fts5yyLookahead will be fts5YYNOCODE
-** if the lookahead token has already been consumed. As this procedure is
-** only called from one place, optimizing compilers will in-line it, which
-** means that the extra parameters have no performance impact.
-*/
+static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */
+
+/*
+** Perform a reduce action and the shift that must immediately
+** follow the reduce.
+**
+** The fts5yyLookahead and fts5yyLookaheadToken parameters provide reduce actions
+** access to the lookahead token (if any). The fts5yyLookahead will be fts5YYNOCODE
+** if the lookahead token has already been consumed. As this procedure is
+** only called from one place, optimizing compilers will in-line it, which
+** means that the extra parameters have no performance impact.
+*/
static fts5YYACTIONTYPE fts5yy_reduce(
- fts5yyParser *fts5yypParser, /* The parser */
- unsigned int fts5yyruleno, /* Number of the rule by which to reduce */
- int fts5yyLookahead, /* Lookahead token, or fts5YYNOCODE if none */
- sqlite3Fts5ParserFTS5TOKENTYPE fts5yyLookaheadToken /* Value of the lookahead token */
+ fts5yyParser *fts5yypParser, /* The parser */
+ unsigned int fts5yyruleno, /* Number of the rule by which to reduce */
+ int fts5yyLookahead, /* Lookahead token, or fts5YYNOCODE if none */
+ sqlite3Fts5ParserFTS5TOKENTYPE fts5yyLookaheadToken /* Value of the lookahead token */
sqlite3Fts5ParserCTX_PDECL /* %extra_context */
-){
- int fts5yygoto; /* The next state */
+){
+ int fts5yygoto; /* The next state */
fts5YYACTIONTYPE fts5yyact; /* The next action */
- fts5yyStackEntry *fts5yymsp; /* The top of the parser's stack */
- int fts5yysize; /* Amount to pop the stack */
+ fts5yyStackEntry *fts5yymsp; /* The top of the parser's stack */
+ int fts5yysize; /* Amount to pop the stack */
sqlite3Fts5ParserARG_FETCH
- (void)fts5yyLookahead;
- (void)fts5yyLookaheadToken;
- fts5yymsp = fts5yypParser->fts5yytos;
-
- switch( fts5yyruleno ){
- /* Beginning here are the reduction cases. A typical example
- ** follows:
- ** case 0:
- ** #line <lineno> <grammarfile>
- ** { ... } // User supplied code
- ** #line <lineno> <thisfile>
- ** break;
- */
-/********** Begin reduce actions **********************************************/
- fts5YYMINORTYPE fts5yylhsminor;
- case 0: /* input ::= expr */
+ (void)fts5yyLookahead;
+ (void)fts5yyLookaheadToken;
+ fts5yymsp = fts5yypParser->fts5yytos;
+
+ switch( fts5yyruleno ){
+ /* Beginning here are the reduction cases. A typical example
+ ** follows:
+ ** case 0:
+ ** #line <lineno> <grammarfile>
+ ** { ... } // User supplied code
+ ** #line <lineno> <thisfile>
+ ** break;
+ */
+/********** Begin reduce actions **********************************************/
+ fts5YYMINORTYPE fts5yylhsminor;
+ case 0: /* input ::= expr */
{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
- break;
- case 1: /* colset ::= MINUS LCP colsetlist RCP */
+ break;
+ case 1: /* colset ::= MINUS LCP colsetlist RCP */
{
fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
-}
- break;
- case 2: /* colset ::= LCP colsetlist RCP */
+}
+ break;
+ case 2: /* colset ::= LCP colsetlist RCP */
{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
- break;
- case 3: /* colset ::= STRING */
-{
+ break;
+ case 3: /* colset ::= STRING */
+{
fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
-}
+}
fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
- break;
- case 4: /* colset ::= MINUS STRING */
-{
+ break;
+ case 4: /* colset ::= MINUS STRING */
+{
fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
-}
- break;
- case 5: /* colsetlist ::= colsetlist STRING */
+}
+ break;
+ case 5: /* colsetlist ::= colsetlist STRING */
{
fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
- break;
- case 6: /* colsetlist ::= STRING */
+ break;
+ case 6: /* colsetlist ::= STRING */
{
fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
-}
+}
fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
- break;
- case 7: /* expr ::= expr AND expr */
-{
+ break;
+ case 7: /* expr ::= expr AND expr */
+{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
-}
+}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
- break;
- case 8: /* expr ::= expr OR expr */
-{
+ break;
+ case 8: /* expr ::= expr OR expr */
+{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
-}
+}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
- break;
- case 9: /* expr ::= expr NOT expr */
-{
+ break;
+ case 9: /* expr ::= expr NOT expr */
+{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
-}
+}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
- break;
- case 10: /* expr ::= colset COLON LP expr RP */
-{
+ break;
+ case 10: /* expr ::= colset COLON LP expr RP */
+{
sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11);
fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;
-}
+}
fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
- break;
- case 11: /* expr ::= LP expr RP */
+ break;
+ case 11: /* expr ::= LP expr RP */
{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
- break;
- case 12: /* expr ::= exprlist */
- case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13);
+ break;
+ case 12: /* expr ::= exprlist */
+ case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13);
{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
- break;
- case 14: /* exprlist ::= exprlist cnearset */
-{
+ break;
+ case 14: /* exprlist ::= exprlist cnearset */
+{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24);
-}
+}
fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
- break;
- case 15: /* cnearset ::= nearset */
+ break;
+ case 15: /* cnearset ::= nearset */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
-}
+}
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
- break;
- case 16: /* cnearset ::= colset COLON nearset */
+ break;
+ case 16: /* cnearset ::= colset COLON nearset */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11);
-}
+}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
- break;
- case 17: /* nearset ::= phrase */
+ break;
+ case 17: /* nearset ::= phrase */
{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
- break;
- case 18: /* nearset ::= CARET phrase */
+ break;
+ case 18: /* nearset ::= CARET phrase */
{
sqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy53);
fts5yymsp[-1].minor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
-}
- break;
- case 19: /* nearset ::= STRING LP nearphrases neardist_opt RP */
-{
- sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
+}
+ break;
+ case 19: /* nearset ::= STRING LP nearphrases neardist_opt RP */
+{
+ sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46;
-}
+}
fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
- break;
- case 20: /* nearphrases ::= phrase */
+ break;
+ case 20: /* nearphrases ::= phrase */
{
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
-}
+}
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
- break;
- case 21: /* nearphrases ::= nearphrases phrase */
-{
+ break;
+ case 21: /* nearphrases ::= nearphrases phrase */
+{
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
-}
+}
fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
- break;
- case 22: /* neardist_opt ::= */
-{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
- break;
- case 23: /* neardist_opt ::= COMMA STRING */
-{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
- break;
- case 24: /* phrase ::= phrase PLUS STRING star_opt */
+ break;
+ case 22: /* neardist_opt ::= */
+{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
+ break;
+ case 23: /* neardist_opt ::= COMMA STRING */
+{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
+ break;
+ case 24: /* phrase ::= phrase PLUS STRING star_opt */
{
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
-}
+}
fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
- break;
- case 25: /* phrase ::= STRING star_opt */
+ break;
+ case 25: /* phrase ::= STRING star_opt */
{
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
-}
+}
fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
- break;
- case 26: /* star_opt ::= STAR */
-{ fts5yymsp[0].minor.fts5yy4 = 1; }
- break;
- case 27: /* star_opt ::= */
-{ fts5yymsp[1].minor.fts5yy4 = 0; }
- break;
- default:
- break;
-/********** End reduce actions ************************************************/
- };
+ break;
+ case 26: /* star_opt ::= STAR */
+{ fts5yymsp[0].minor.fts5yy4 = 1; }
+ break;
+ case 27: /* star_opt ::= */
+{ fts5yymsp[1].minor.fts5yy4 = 0; }
+ break;
+ default:
+ break;
+/********** End reduce actions ************************************************/
+ };
assert( fts5yyruleno<sizeof(fts5yyRuleInfoLhs)/sizeof(fts5yyRuleInfoLhs[0]) );
fts5yygoto = fts5yyRuleInfoLhs[fts5yyruleno];
fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
- fts5yyact = fts5yy_find_reduce_action(fts5yymsp[fts5yysize].stateno,(fts5YYCODETYPE)fts5yygoto);
-
- /* There are no SHIFTREDUCE actions on nonterminals because the table
- ** generator has simplified them to pure REDUCE actions. */
- assert( !(fts5yyact>fts5YY_MAX_SHIFT && fts5yyact<=fts5YY_MAX_SHIFTREDUCE) );
-
- /* It is not possible for a REDUCE to be followed by an error */
- assert( fts5yyact!=fts5YY_ERROR_ACTION );
-
- fts5yymsp += fts5yysize+1;
- fts5yypParser->fts5yytos = fts5yymsp;
- fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
- fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
- fts5yyTraceShift(fts5yypParser, fts5yyact, "... then shift");
+ fts5yyact = fts5yy_find_reduce_action(fts5yymsp[fts5yysize].stateno,(fts5YYCODETYPE)fts5yygoto);
+
+ /* There are no SHIFTREDUCE actions on nonterminals because the table
+ ** generator has simplified them to pure REDUCE actions. */
+ assert( !(fts5yyact>fts5YY_MAX_SHIFT && fts5yyact<=fts5YY_MAX_SHIFTREDUCE) );
+
+ /* It is not possible for a REDUCE to be followed by an error */
+ assert( fts5yyact!=fts5YY_ERROR_ACTION );
+
+ fts5yymsp += fts5yysize+1;
+ fts5yypParser->fts5yytos = fts5yymsp;
+ fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
+ fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
+ fts5yyTraceShift(fts5yypParser, fts5yyact, "... then shift");
return fts5yyact;
-}
-
-/*
-** The following code executes when the parse fails
-*/
-#ifndef fts5YYNOERRORRECOVERY
-static void fts5yy_parse_failed(
- fts5yyParser *fts5yypParser /* The parser */
-){
+}
+
+/*
+** The following code executes when the parse fails
+*/
+#ifndef fts5YYNOERRORRECOVERY
+static void fts5yy_parse_failed(
+ fts5yyParser *fts5yypParser /* The parser */
+){
sqlite3Fts5ParserARG_FETCH
sqlite3Fts5ParserCTX_FETCH
-#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE,"%sFail!\n",fts5yyTracePrompt);
- }
-#endif
- while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ) fts5yy_pop_parser_stack(fts5yypParser);
- /* Here code is inserted which will be executed whenever the
- ** parser fails */
-/************ Begin %parse_failure code ***************************************/
-/************ End %parse_failure code *****************************************/
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sFail!\n",fts5yyTracePrompt);
+ }
+#endif
+ while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ) fts5yy_pop_parser_stack(fts5yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser fails */
+/************ Begin %parse_failure code ***************************************/
+/************ End %parse_failure code *****************************************/
sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
sqlite3Fts5ParserCTX_STORE
-}
-#endif /* fts5YYNOERRORRECOVERY */
-
-/*
-** The following code executes when a syntax error first occurs.
-*/
-static void fts5yy_syntax_error(
- fts5yyParser *fts5yypParser, /* The parser */
- int fts5yymajor, /* The major type of the error token */
- sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor /* The minor type of the error token */
-){
+}
+#endif /* fts5YYNOERRORRECOVERY */
+
+/*
+** The following code executes when a syntax error first occurs.
+*/
+static void fts5yy_syntax_error(
+ fts5yyParser *fts5yypParser, /* The parser */
+ int fts5yymajor, /* The major type of the error token */
+ sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor /* The minor type of the error token */
+){
sqlite3Fts5ParserARG_FETCH
sqlite3Fts5ParserCTX_FETCH
-#define FTS5TOKEN fts5yyminor
-/************ Begin %syntax_error code ****************************************/
-
- UNUSED_PARAM(fts5yymajor); /* Silence a compiler warning */
- sqlite3Fts5ParseError(
- pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p
- );
-/************ End %syntax_error code ******************************************/
+#define FTS5TOKEN fts5yyminor
+/************ Begin %syntax_error code ****************************************/
+
+ UNUSED_PARAM(fts5yymajor); /* Silence a compiler warning */
+ sqlite3Fts5ParseError(
+ pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p
+ );
+/************ End %syntax_error code ******************************************/
sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
sqlite3Fts5ParserCTX_STORE
-}
-
-/*
-** The following is executed when the parser accepts
-*/
-static void fts5yy_accept(
- fts5yyParser *fts5yypParser /* The parser */
-){
+}
+
+/*
+** The following is executed when the parser accepts
+*/
+static void fts5yy_accept(
+ fts5yyParser *fts5yypParser /* The parser */
+){
sqlite3Fts5ParserARG_FETCH
sqlite3Fts5ParserCTX_FETCH
-#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE,"%sAccept!\n",fts5yyTracePrompt);
- }
-#endif
-#ifndef fts5YYNOERRORRECOVERY
- fts5yypParser->fts5yyerrcnt = -1;
-#endif
- assert( fts5yypParser->fts5yytos==fts5yypParser->fts5yystack );
- /* Here code is inserted which will be executed whenever the
- ** parser accepts */
-/*********** Begin %parse_accept code *****************************************/
-/*********** End %parse_accept code *******************************************/
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sAccept!\n",fts5yyTracePrompt);
+ }
+#endif
+#ifndef fts5YYNOERRORRECOVERY
+ fts5yypParser->fts5yyerrcnt = -1;
+#endif
+ assert( fts5yypParser->fts5yytos==fts5yypParser->fts5yystack );
+ /* Here code is inserted which will be executed whenever the
+ ** parser accepts */
+/*********** Begin %parse_accept code *****************************************/
+/*********** End %parse_accept code *******************************************/
sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
sqlite3Fts5ParserCTX_STORE
-}
-
-/* The main parser program.
-** The first argument is a pointer to a structure obtained from
-** "sqlite3Fts5ParserAlloc" which describes the current state of the parser.
-** The second argument is the major token number. The third is
-** the minor token. The fourth optional argument is whatever the
-** user wants (and specified in the grammar) and is available for
-** use by the action routines.
-**
-** Inputs:
-** <ul>
-** <li> A pointer to the parser (an opaque structure.)
-** <li> The major token number.
-** <li> The minor token number.
-** <li> An option argument of a grammar-specified type.
-** </ul>
-**
-** Outputs:
-** None.
-*/
-static void sqlite3Fts5Parser(
- void *fts5yyp, /* The parser */
- int fts5yymajor, /* The major token code number */
- sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor /* The value for the token */
- sqlite3Fts5ParserARG_PDECL /* Optional %extra_argument parameter */
-){
- fts5YYMINORTYPE fts5yyminorunion;
+}
+
+/* The main parser program.
+** The first argument is a pointer to a structure obtained from
+** "sqlite3Fts5ParserAlloc" which describes the current state of the parser.
+** The second argument is the major token number. The third is
+** the minor token. The fourth optional argument is whatever the
+** user wants (and specified in the grammar) and is available for
+** use by the action routines.
+**
+** Inputs:
+** <ul>
+** <li> A pointer to the parser (an opaque structure.)
+** <li> The major token number.
+** <li> The minor token number.
+** <li> An option argument of a grammar-specified type.
+** </ul>
+**
+** Outputs:
+** None.
+*/
+static void sqlite3Fts5Parser(
+ void *fts5yyp, /* The parser */
+ int fts5yymajor, /* The major token code number */
+ sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor /* The value for the token */
+ sqlite3Fts5ParserARG_PDECL /* Optional %extra_argument parameter */
+){
+ fts5YYMINORTYPE fts5yyminorunion;
fts5YYACTIONTYPE fts5yyact; /* The parser action. */
-#if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
- int fts5yyendofinput; /* True if we are at the end of input */
-#endif
-#ifdef fts5YYERRORSYMBOL
- int fts5yyerrorhit = 0; /* True if fts5yymajor has invoked an error */
-#endif
+#if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
+ int fts5yyendofinput; /* True if we are at the end of input */
+#endif
+#ifdef fts5YYERRORSYMBOL
+ int fts5yyerrorhit = 0; /* True if fts5yymajor has invoked an error */
+#endif
fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yyp; /* The parser */
sqlite3Fts5ParserCTX_FETCH
sqlite3Fts5ParserARG_STORE
-
- assert( fts5yypParser->fts5yytos!=0 );
-#if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
- fts5yyendofinput = (fts5yymajor==0);
-#endif
-
+
+ assert( fts5yypParser->fts5yytos!=0 );
+#if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
+ fts5yyendofinput = (fts5yymajor==0);
+#endif
+
fts5yyact = fts5yypParser->fts5yytos->stateno;
-#ifndef NDEBUG
- if( fts5yyTraceFILE ){
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
if( fts5yyact < fts5YY_MIN_REDUCE ){
- fprintf(fts5yyTraceFILE,"%sInput '%s' in state %d\n",
+ fprintf(fts5yyTraceFILE,"%sInput '%s' in state %d\n",
fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],fts5yyact);
- }else{
- fprintf(fts5yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
+ }else{
+ fprintf(fts5yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],fts5yyact-fts5YY_MIN_REDUCE);
- }
- }
-#endif
-
+ }
+ }
+#endif
+
while(1){ /* Exit by "break" */
assert( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystack );
assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
- if( fts5yyact >= fts5YY_MIN_REDUCE ){
+ if( fts5yyact >= fts5YY_MIN_REDUCE ){
unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */
#ifndef NDEBUG
assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
@@ -217075,134 +217075,134 @@ static void sqlite3Fts5Parser(
#endif
}
fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyruleno,fts5yymajor,fts5yyminor sqlite3Fts5ParserCTX_PARAM);
- }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
+ }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
fts5yy_shift(fts5yypParser,fts5yyact,(fts5YYCODETYPE)fts5yymajor,fts5yyminor);
-#ifndef fts5YYNOERRORRECOVERY
- fts5yypParser->fts5yyerrcnt--;
-#endif
- break;
- }else if( fts5yyact==fts5YY_ACCEPT_ACTION ){
- fts5yypParser->fts5yytos--;
- fts5yy_accept(fts5yypParser);
- return;
- }else{
- assert( fts5yyact == fts5YY_ERROR_ACTION );
- fts5yyminorunion.fts5yy0 = fts5yyminor;
-#ifdef fts5YYERRORSYMBOL
- int fts5yymx;
-#endif
-#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE,"%sSyntax Error!\n",fts5yyTracePrompt);
- }
-#endif
-#ifdef fts5YYERRORSYMBOL
- /* A syntax error has occurred.
- ** The response to an error depends upon whether or not the
+#ifndef fts5YYNOERRORRECOVERY
+ fts5yypParser->fts5yyerrcnt--;
+#endif
+ break;
+ }else if( fts5yyact==fts5YY_ACCEPT_ACTION ){
+ fts5yypParser->fts5yytos--;
+ fts5yy_accept(fts5yypParser);
+ return;
+ }else{
+ assert( fts5yyact == fts5YY_ERROR_ACTION );
+ fts5yyminorunion.fts5yy0 = fts5yyminor;
+#ifdef fts5YYERRORSYMBOL
+ int fts5yymx;
+#endif
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sSyntax Error!\n",fts5yyTracePrompt);
+ }
+#endif
+#ifdef fts5YYERRORSYMBOL
+ /* A syntax error has occurred.
+ ** The response to an error depends upon whether or not the
** grammar defines an error token "ERROR".
- **
- ** This is what we do if the grammar does define ERROR:
- **
- ** * Call the %syntax_error function.
- **
- ** * Begin popping the stack until we enter a state where
- ** it is legal to shift the error symbol, then shift
- ** the error symbol.
- **
- ** * Set the error count to three.
- **
- ** * Begin accepting and shifting new tokens. No new error
- ** processing will occur until three tokens have been
- ** shifted successfully.
- **
- */
- if( fts5yypParser->fts5yyerrcnt<0 ){
- fts5yy_syntax_error(fts5yypParser,fts5yymajor,fts5yyminor);
- }
- fts5yymx = fts5yypParser->fts5yytos->major;
- if( fts5yymx==fts5YYERRORSYMBOL || fts5yyerrorhit ){
-#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE,"%sDiscard input token %s\n",
- fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
- }
-#endif
- fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
- fts5yymajor = fts5YYNOCODE;
- }else{
+ **
+ ** This is what we do if the grammar does define ERROR:
+ **
+ ** * Call the %syntax_error function.
+ **
+ ** * Begin popping the stack until we enter a state where
+ ** it is legal to shift the error symbol, then shift
+ ** the error symbol.
+ **
+ ** * Set the error count to three.
+ **
+ ** * Begin accepting and shifting new tokens. No new error
+ ** processing will occur until three tokens have been
+ ** shifted successfully.
+ **
+ */
+ if( fts5yypParser->fts5yyerrcnt<0 ){
+ fts5yy_syntax_error(fts5yypParser,fts5yymajor,fts5yyminor);
+ }
+ fts5yymx = fts5yypParser->fts5yytos->major;
+ if( fts5yymx==fts5YYERRORSYMBOL || fts5yyerrorhit ){
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sDiscard input token %s\n",
+ fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
+ }
+#endif
+ fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
+ fts5yymajor = fts5YYNOCODE;
+ }else{
while( fts5yypParser->fts5yytos > fts5yypParser->fts5yystack ){
fts5yyact = fts5yy_find_reduce_action(fts5yypParser->fts5yytos->stateno,
fts5YYERRORSYMBOL);
if( fts5yyact<=fts5YY_MAX_SHIFTREDUCE ) break;
- fts5yy_pop_parser_stack(fts5yypParser);
- }
+ fts5yy_pop_parser_stack(fts5yypParser);
+ }
if( fts5yypParser->fts5yytos <= fts5yypParser->fts5yystack || fts5yymajor==0 ){
- fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
- fts5yy_parse_failed(fts5yypParser);
-#ifndef fts5YYNOERRORRECOVERY
- fts5yypParser->fts5yyerrcnt = -1;
-#endif
- fts5yymajor = fts5YYNOCODE;
- }else if( fts5yymx!=fts5YYERRORSYMBOL ){
- fts5yy_shift(fts5yypParser,fts5yyact,fts5YYERRORSYMBOL,fts5yyminor);
- }
- }
- fts5yypParser->fts5yyerrcnt = 3;
- fts5yyerrorhit = 1;
+ fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
+ fts5yy_parse_failed(fts5yypParser);
+#ifndef fts5YYNOERRORRECOVERY
+ fts5yypParser->fts5yyerrcnt = -1;
+#endif
+ fts5yymajor = fts5YYNOCODE;
+ }else if( fts5yymx!=fts5YYERRORSYMBOL ){
+ fts5yy_shift(fts5yypParser,fts5yyact,fts5YYERRORSYMBOL,fts5yyminor);
+ }
+ }
+ fts5yypParser->fts5yyerrcnt = 3;
+ fts5yyerrorhit = 1;
if( fts5yymajor==fts5YYNOCODE ) break;
fts5yyact = fts5yypParser->fts5yytos->stateno;
-#elif defined(fts5YYNOERRORRECOVERY)
- /* If the fts5YYNOERRORRECOVERY macro is defined, then do not attempt to
- ** do any kind of error recovery. Instead, simply invoke the syntax
- ** error routine and continue going as if nothing had happened.
- **
- ** Applications can set this macro (for example inside %include) if
- ** they intend to abandon the parse upon the first syntax error seen.
- */
- fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor);
- fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
- break;
-#else /* fts5YYERRORSYMBOL is not defined */
- /* This is what we do if the grammar does not define ERROR:
- **
- ** * Report an error message, and throw away the input token.
- **
- ** * If the input token is $, then fail the parse.
- **
- ** As before, subsequent error messages are suppressed until
- ** three input tokens have been successfully shifted.
- */
- if( fts5yypParser->fts5yyerrcnt<=0 ){
- fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor);
- }
- fts5yypParser->fts5yyerrcnt = 3;
- fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
- if( fts5yyendofinput ){
- fts5yy_parse_failed(fts5yypParser);
-#ifndef fts5YYNOERRORRECOVERY
- fts5yypParser->fts5yyerrcnt = -1;
-#endif
- }
- break;
-#endif
- }
- }
-#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fts5yyStackEntry *i;
- char cDiv = '[';
- fprintf(fts5yyTraceFILE,"%sReturn. Stack=",fts5yyTracePrompt);
- for(i=&fts5yypParser->fts5yystack[1]; i<=fts5yypParser->fts5yytos; i++){
- fprintf(fts5yyTraceFILE,"%c%s", cDiv, fts5yyTokenName[i->major]);
- cDiv = ' ';
- }
- fprintf(fts5yyTraceFILE,"]\n");
- }
-#endif
- return;
-}
-
-/*
+#elif defined(fts5YYNOERRORRECOVERY)
+ /* If the fts5YYNOERRORRECOVERY macro is defined, then do not attempt to
+ ** do any kind of error recovery. Instead, simply invoke the syntax
+ ** error routine and continue going as if nothing had happened.
+ **
+ ** Applications can set this macro (for example inside %include) if
+ ** they intend to abandon the parse upon the first syntax error seen.
+ */
+ fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor);
+ fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
+ break;
+#else /* fts5YYERRORSYMBOL is not defined */
+ /* This is what we do if the grammar does not define ERROR:
+ **
+ ** * Report an error message, and throw away the input token.
+ **
+ ** * If the input token is $, then fail the parse.
+ **
+ ** As before, subsequent error messages are suppressed until
+ ** three input tokens have been successfully shifted.
+ */
+ if( fts5yypParser->fts5yyerrcnt<=0 ){
+ fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor);
+ }
+ fts5yypParser->fts5yyerrcnt = 3;
+ fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
+ if( fts5yyendofinput ){
+ fts5yy_parse_failed(fts5yypParser);
+#ifndef fts5YYNOERRORRECOVERY
+ fts5yypParser->fts5yyerrcnt = -1;
+#endif
+ }
+ break;
+#endif
+ }
+ }
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fts5yyStackEntry *i;
+ char cDiv = '[';
+ fprintf(fts5yyTraceFILE,"%sReturn. Stack=",fts5yyTracePrompt);
+ for(i=&fts5yypParser->fts5yystack[1]; i<=fts5yypParser->fts5yytos; i++){
+ fprintf(fts5yyTraceFILE,"%c%s", cDiv, fts5yyTokenName[i->major]);
+ cDiv = ' ';
+ }
+ fprintf(fts5yyTraceFILE,"]\n");
+ }
+#endif
+ return;
+}
+
+/*
** Return the fallback token corresponding to canonical token iToken, or
** 0 if iToken has no fallback.
*/
@@ -217217,908 +217217,908 @@ static int sqlite3Fts5ParserFallback(int iToken){
}
/*
-** 2014 May 31
-**
-** 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.
-**
-******************************************************************************
-*/
-
-
-/* #include "fts5Int.h" */
-#include <math.h> /* amalgamator: keep */
-
-/*
+** 2014 May 31
+**
+** 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.
+**
+******************************************************************************
+*/
+
+
+/* #include "fts5Int.h" */
+#include <math.h> /* amalgamator: keep */
+
+/*
** Object used to iterate through all "coalesced phrase instances" in
-** a single column of the current row. If the phrase instances in the
-** column being considered do not overlap, this object simply iterates
-** through them. Or, if they do overlap (share one or more tokens in
-** common), each set of overlapping instances is treated as a single
-** match. See documentation for the highlight() auxiliary function for
-** details.
-**
-** Usage is:
-**
-** for(rc = fts5CInstIterNext(pApi, pFts, iCol, &iter);
-** (rc==SQLITE_OK && 0==fts5CInstIterEof(&iter);
-** rc = fts5CInstIterNext(&iter)
-** ){
-** printf("instance starts at %d, ends at %d\n", iter.iStart, iter.iEnd);
-** }
-**
-*/
-typedef struct CInstIter CInstIter;
-struct CInstIter {
- const Fts5ExtensionApi *pApi; /* API offered by current FTS version */
- Fts5Context *pFts; /* First arg to pass to pApi functions */
- int iCol; /* Column to search */
- int iInst; /* Next phrase instance index */
- int nInst; /* Total number of phrase instances */
-
- /* Output variables */
- int iStart; /* First token in coalesced phrase instance */
- int iEnd; /* Last token in coalesced phrase instance */
-};
-
-/*
-** Advance the iterator to the next coalesced phrase instance. Return
-** an SQLite error code if an error occurs, or SQLITE_OK otherwise.
-*/
-static int fts5CInstIterNext(CInstIter *pIter){
- int rc = SQLITE_OK;
- pIter->iStart = -1;
- pIter->iEnd = -1;
-
- while( rc==SQLITE_OK && pIter->iInst<pIter->nInst ){
- int ip; int ic; int io;
- rc = pIter->pApi->xInst(pIter->pFts, pIter->iInst, &ip, &ic, &io);
- if( rc==SQLITE_OK ){
- if( ic==pIter->iCol ){
- int iEnd = io - 1 + pIter->pApi->xPhraseSize(pIter->pFts, ip);
- if( pIter->iStart<0 ){
- pIter->iStart = io;
- pIter->iEnd = iEnd;
- }else if( io<=pIter->iEnd ){
- if( iEnd>pIter->iEnd ) pIter->iEnd = iEnd;
- }else{
- break;
- }
- }
- pIter->iInst++;
- }
- }
-
- return rc;
-}
-
-/*
+** a single column of the current row. If the phrase instances in the
+** column being considered do not overlap, this object simply iterates
+** through them. Or, if they do overlap (share one or more tokens in
+** common), each set of overlapping instances is treated as a single
+** match. See documentation for the highlight() auxiliary function for
+** details.
+**
+** Usage is:
+**
+** for(rc = fts5CInstIterNext(pApi, pFts, iCol, &iter);
+** (rc==SQLITE_OK && 0==fts5CInstIterEof(&iter);
+** rc = fts5CInstIterNext(&iter)
+** ){
+** printf("instance starts at %d, ends at %d\n", iter.iStart, iter.iEnd);
+** }
+**
+*/
+typedef struct CInstIter CInstIter;
+struct CInstIter {
+ const Fts5ExtensionApi *pApi; /* API offered by current FTS version */
+ Fts5Context *pFts; /* First arg to pass to pApi functions */
+ int iCol; /* Column to search */
+ int iInst; /* Next phrase instance index */
+ int nInst; /* Total number of phrase instances */
+
+ /* Output variables */
+ int iStart; /* First token in coalesced phrase instance */
+ int iEnd; /* Last token in coalesced phrase instance */
+};
+
+/*
+** Advance the iterator to the next coalesced phrase instance. Return
+** an SQLite error code if an error occurs, or SQLITE_OK otherwise.
+*/
+static int fts5CInstIterNext(CInstIter *pIter){
+ int rc = SQLITE_OK;
+ pIter->iStart = -1;
+ pIter->iEnd = -1;
+
+ while( rc==SQLITE_OK && pIter->iInst<pIter->nInst ){
+ int ip; int ic; int io;
+ rc = pIter->pApi->xInst(pIter->pFts, pIter->iInst, &ip, &ic, &io);
+ if( rc==SQLITE_OK ){
+ if( ic==pIter->iCol ){
+ int iEnd = io - 1 + pIter->pApi->xPhraseSize(pIter->pFts, ip);
+ if( pIter->iStart<0 ){
+ pIter->iStart = io;
+ pIter->iEnd = iEnd;
+ }else if( io<=pIter->iEnd ){
+ if( iEnd>pIter->iEnd ) pIter->iEnd = iEnd;
+ }else{
+ break;
+ }
+ }
+ pIter->iInst++;
+ }
+ }
+
+ return rc;
+}
+
+/*
** Initialize the iterator object indicated by the final parameter to
-** iterate through coalesced phrase instances in column iCol.
-*/
-static int fts5CInstIterInit(
- const Fts5ExtensionApi *pApi,
- Fts5Context *pFts,
- int iCol,
- CInstIter *pIter
-){
- int rc;
-
- memset(pIter, 0, sizeof(CInstIter));
- pIter->pApi = pApi;
- pIter->pFts = pFts;
- pIter->iCol = iCol;
- rc = pApi->xInstCount(pFts, &pIter->nInst);
-
- if( rc==SQLITE_OK ){
- rc = fts5CInstIterNext(pIter);
- }
-
- return rc;
-}
-
-
-
-/*************************************************************************
-** Start of highlight() implementation.
-*/
-typedef struct HighlightContext HighlightContext;
-struct HighlightContext {
- CInstIter iter; /* Coalesced Instance Iterator */
- int iPos; /* Current token offset in zIn[] */
- int iRangeStart; /* First token to include */
- int iRangeEnd; /* If non-zero, last token to include */
- const char *zOpen; /* Opening highlight */
- const char *zClose; /* Closing highlight */
- const char *zIn; /* Input text */
- int nIn; /* Size of input text in bytes */
- int iOff; /* Current offset within zIn[] */
- char *zOut; /* Output value */
-};
-
-/*
-** Append text to the HighlightContext output string - p->zOut. Argument
+** iterate through coalesced phrase instances in column iCol.
+*/
+static int fts5CInstIterInit(
+ const Fts5ExtensionApi *pApi,
+ Fts5Context *pFts,
+ int iCol,
+ CInstIter *pIter
+){
+ int rc;
+
+ memset(pIter, 0, sizeof(CInstIter));
+ pIter->pApi = pApi;
+ pIter->pFts = pFts;
+ pIter->iCol = iCol;
+ rc = pApi->xInstCount(pFts, &pIter->nInst);
+
+ if( rc==SQLITE_OK ){
+ rc = fts5CInstIterNext(pIter);
+ }
+
+ return rc;
+}
+
+
+
+/*************************************************************************
+** Start of highlight() implementation.
+*/
+typedef struct HighlightContext HighlightContext;
+struct HighlightContext {
+ CInstIter iter; /* Coalesced Instance Iterator */
+ int iPos; /* Current token offset in zIn[] */
+ int iRangeStart; /* First token to include */
+ int iRangeEnd; /* If non-zero, last token to include */
+ const char *zOpen; /* Opening highlight */
+ const char *zClose; /* Closing highlight */
+ const char *zIn; /* Input text */
+ int nIn; /* Size of input text in bytes */
+ int iOff; /* Current offset within zIn[] */
+ char *zOut; /* Output value */
+};
+
+/*
+** Append text to the HighlightContext output string - p->zOut. Argument
** z points to a buffer containing n bytes of text to append. If n is
-** negative, everything up until the first '\0' is appended to the output.
-**
+** negative, everything up until the first '\0' is appended to the output.
+**
** If *pRc is set to any value other than SQLITE_OK when this function is
** called, it is a no-op. If an error (i.e. an OOM condition) is encountered,
** *pRc is set to an error code before returning.
-*/
-static void fts5HighlightAppend(
+*/
+static void fts5HighlightAppend(
int *pRc,
HighlightContext *p,
- const char *z, int n
-){
+ const char *z, int n
+){
if( *pRc==SQLITE_OK && z ){
- if( n<0 ) n = (int)strlen(z);
- p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z);
- if( p->zOut==0 ) *pRc = SQLITE_NOMEM;
- }
-}
-
-/*
-** Tokenizer callback used by implementation of highlight() function.
-*/
-static int fts5HighlightCb(
- void *pContext, /* Pointer to HighlightContext object */
- int tflags, /* Mask of FTS5_TOKEN_* flags */
- const char *pToken, /* Buffer containing token */
- int nToken, /* Size of token in bytes */
- int iStartOff, /* Start offset of token */
- int iEndOff /* End offset of token */
-){
- HighlightContext *p = (HighlightContext*)pContext;
- int rc = SQLITE_OK;
- int iPos;
-
- UNUSED_PARAM2(pToken, nToken);
-
- if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK;
- iPos = p->iPos++;
-
- if( p->iRangeEnd>0 ){
- if( iPos<p->iRangeStart || iPos>p->iRangeEnd ) return SQLITE_OK;
- if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff;
- }
-
- if( iPos==p->iter.iStart ){
- fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iStartOff - p->iOff);
- fts5HighlightAppend(&rc, p, p->zOpen, -1);
- p->iOff = iStartOff;
- }
-
- if( iPos==p->iter.iEnd ){
- if( p->iRangeEnd && p->iter.iStart<p->iRangeStart ){
- fts5HighlightAppend(&rc, p, p->zOpen, -1);
- }
- fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
- fts5HighlightAppend(&rc, p, p->zClose, -1);
- p->iOff = iEndOff;
- if( rc==SQLITE_OK ){
- rc = fts5CInstIterNext(&p->iter);
- }
- }
-
- if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){
- fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
- p->iOff = iEndOff;
- if( iPos>=p->iter.iStart && iPos<p->iter.iEnd ){
- fts5HighlightAppend(&rc, p, p->zClose, -1);
- }
- }
-
- return rc;
-}
-
-/*
-** Implementation of highlight() function.
-*/
-static void fts5HighlightFunction(
- const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
- Fts5Context *pFts, /* First arg to pass to pApi functions */
- sqlite3_context *pCtx, /* Context for returning result/error */
- int nVal, /* Number of values in apVal[] array */
- sqlite3_value **apVal /* Array of trailing arguments */
-){
- HighlightContext ctx;
- int rc;
- int iCol;
-
- if( nVal!=3 ){
- const char *zErr = "wrong number of arguments to function highlight()";
- sqlite3_result_error(pCtx, zErr, -1);
- return;
- }
-
- iCol = sqlite3_value_int(apVal[0]);
- memset(&ctx, 0, sizeof(HighlightContext));
- ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
- ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
- rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn);
-
- if( ctx.zIn ){
- if( rc==SQLITE_OK ){
- rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter);
- }
-
- if( rc==SQLITE_OK ){
- rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
- }
- fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
-
- if( rc==SQLITE_OK ){
- sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT);
- }
- sqlite3_free(ctx.zOut);
- }
- if( rc!=SQLITE_OK ){
- sqlite3_result_error_code(pCtx, rc);
- }
-}
-/*
-** End of highlight() implementation.
-**************************************************************************/
-
-/*
-** Context object passed to the fts5SentenceFinderCb() function.
-*/
-typedef struct Fts5SFinder Fts5SFinder;
-struct Fts5SFinder {
- int iPos; /* Current token position */
- int nFirstAlloc; /* Allocated size of aFirst[] */
- int nFirst; /* Number of entries in aFirst[] */
- int *aFirst; /* Array of first token in each sentence */
- const char *zDoc; /* Document being tokenized */
-};
-
-/*
-** Add an entry to the Fts5SFinder.aFirst[] array. Grow the array if
-** necessary. Return SQLITE_OK if successful, or SQLITE_NOMEM if an
-** error occurs.
-*/
-static int fts5SentenceFinderAdd(Fts5SFinder *p, int iAdd){
- if( p->nFirstAlloc==p->nFirst ){
- int nNew = p->nFirstAlloc ? p->nFirstAlloc*2 : 64;
- int *aNew;
-
+ if( n<0 ) n = (int)strlen(z);
+ p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z);
+ if( p->zOut==0 ) *pRc = SQLITE_NOMEM;
+ }
+}
+
+/*
+** Tokenizer callback used by implementation of highlight() function.
+*/
+static int fts5HighlightCb(
+ void *pContext, /* Pointer to HighlightContext object */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStartOff, /* Start offset of token */
+ int iEndOff /* End offset of token */
+){
+ HighlightContext *p = (HighlightContext*)pContext;
+ int rc = SQLITE_OK;
+ int iPos;
+
+ UNUSED_PARAM2(pToken, nToken);
+
+ if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK;
+ iPos = p->iPos++;
+
+ if( p->iRangeEnd>0 ){
+ if( iPos<p->iRangeStart || iPos>p->iRangeEnd ) return SQLITE_OK;
+ if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff;
+ }
+
+ if( iPos==p->iter.iStart ){
+ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iStartOff - p->iOff);
+ fts5HighlightAppend(&rc, p, p->zOpen, -1);
+ p->iOff = iStartOff;
+ }
+
+ if( iPos==p->iter.iEnd ){
+ if( p->iRangeEnd && p->iter.iStart<p->iRangeStart ){
+ fts5HighlightAppend(&rc, p, p->zOpen, -1);
+ }
+ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
+ fts5HighlightAppend(&rc, p, p->zClose, -1);
+ p->iOff = iEndOff;
+ if( rc==SQLITE_OK ){
+ rc = fts5CInstIterNext(&p->iter);
+ }
+ }
+
+ if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){
+ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
+ p->iOff = iEndOff;
+ if( iPos>=p->iter.iStart && iPos<p->iter.iEnd ){
+ fts5HighlightAppend(&rc, p, p->zClose, -1);
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Implementation of highlight() function.
+*/
+static void fts5HighlightFunction(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+){
+ HighlightContext ctx;
+ int rc;
+ int iCol;
+
+ if( nVal!=3 ){
+ const char *zErr = "wrong number of arguments to function highlight()";
+ sqlite3_result_error(pCtx, zErr, -1);
+ return;
+ }
+
+ iCol = sqlite3_value_int(apVal[0]);
+ memset(&ctx, 0, sizeof(HighlightContext));
+ ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
+ ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
+ rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn);
+
+ if( ctx.zIn ){
+ if( rc==SQLITE_OK ){
+ rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter);
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
+ }
+ fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
+
+ if( rc==SQLITE_OK ){
+ sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT);
+ }
+ sqlite3_free(ctx.zOut);
+ }
+ if( rc!=SQLITE_OK ){
+ sqlite3_result_error_code(pCtx, rc);
+ }
+}
+/*
+** End of highlight() implementation.
+**************************************************************************/
+
+/*
+** Context object passed to the fts5SentenceFinderCb() function.
+*/
+typedef struct Fts5SFinder Fts5SFinder;
+struct Fts5SFinder {
+ int iPos; /* Current token position */
+ int nFirstAlloc; /* Allocated size of aFirst[] */
+ int nFirst; /* Number of entries in aFirst[] */
+ int *aFirst; /* Array of first token in each sentence */
+ const char *zDoc; /* Document being tokenized */
+};
+
+/*
+** Add an entry to the Fts5SFinder.aFirst[] array. Grow the array if
+** necessary. Return SQLITE_OK if successful, or SQLITE_NOMEM if an
+** error occurs.
+*/
+static int fts5SentenceFinderAdd(Fts5SFinder *p, int iAdd){
+ if( p->nFirstAlloc==p->nFirst ){
+ int nNew = p->nFirstAlloc ? p->nFirstAlloc*2 : 64;
+ int *aNew;
+
aNew = (int*)sqlite3_realloc64(p->aFirst, nNew*sizeof(int));
- if( aNew==0 ) return SQLITE_NOMEM;
- p->aFirst = aNew;
- p->nFirstAlloc = nNew;
- }
- p->aFirst[p->nFirst++] = iAdd;
- return SQLITE_OK;
-}
-
-/*
-** This function is an xTokenize() callback used by the auxiliary snippet()
-** function. Its job is to identify tokens that are the first in a sentence.
-** For each such token, an entry is added to the SFinder.aFirst[] array.
-*/
-static int fts5SentenceFinderCb(
- void *pContext, /* Pointer to HighlightContext object */
- int tflags, /* Mask of FTS5_TOKEN_* flags */
- const char *pToken, /* Buffer containing token */
- int nToken, /* Size of token in bytes */
- int iStartOff, /* Start offset of token */
- int iEndOff /* End offset of token */
-){
- int rc = SQLITE_OK;
-
- UNUSED_PARAM2(pToken, nToken);
- UNUSED_PARAM(iEndOff);
-
- if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
- Fts5SFinder *p = (Fts5SFinder*)pContext;
- if( p->iPos>0 ){
- int i;
- char c = 0;
- for(i=iStartOff-1; i>=0; i--){
- c = p->zDoc[i];
- if( c!=' ' && c!='\t' && c!='\n' && c!='\r' ) break;
- }
- if( i!=iStartOff-1 && (c=='.' || c==':') ){
- rc = fts5SentenceFinderAdd(p, p->iPos);
- }
- }else{
- rc = fts5SentenceFinderAdd(p, 0);
- }
- p->iPos++;
- }
- return rc;
-}
-
-static int fts5SnippetScore(
- const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
- Fts5Context *pFts, /* First arg to pass to pApi functions */
- int nDocsize, /* Size of column in tokens */
- unsigned char *aSeen, /* Array with one element per query phrase */
- int iCol, /* Column to score */
- int iPos, /* Starting offset to score */
- int nToken, /* Max tokens per snippet */
- int *pnScore, /* OUT: Score */
- int *piPos /* OUT: Adjusted offset */
-){
- int rc;
- int i;
- int ip = 0;
- int ic = 0;
- int iOff = 0;
- int iFirst = -1;
- int nInst;
- int nScore = 0;
- int iLast = 0;
+ if( aNew==0 ) return SQLITE_NOMEM;
+ p->aFirst = aNew;
+ p->nFirstAlloc = nNew;
+ }
+ p->aFirst[p->nFirst++] = iAdd;
+ return SQLITE_OK;
+}
+
+/*
+** This function is an xTokenize() callback used by the auxiliary snippet()
+** function. Its job is to identify tokens that are the first in a sentence.
+** For each such token, an entry is added to the SFinder.aFirst[] array.
+*/
+static int fts5SentenceFinderCb(
+ void *pContext, /* Pointer to HighlightContext object */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStartOff, /* Start offset of token */
+ int iEndOff /* End offset of token */
+){
+ int rc = SQLITE_OK;
+
+ UNUSED_PARAM2(pToken, nToken);
+ UNUSED_PARAM(iEndOff);
+
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
+ Fts5SFinder *p = (Fts5SFinder*)pContext;
+ if( p->iPos>0 ){
+ int i;
+ char c = 0;
+ for(i=iStartOff-1; i>=0; i--){
+ c = p->zDoc[i];
+ if( c!=' ' && c!='\t' && c!='\n' && c!='\r' ) break;
+ }
+ if( i!=iStartOff-1 && (c=='.' || c==':') ){
+ rc = fts5SentenceFinderAdd(p, p->iPos);
+ }
+ }else{
+ rc = fts5SentenceFinderAdd(p, 0);
+ }
+ p->iPos++;
+ }
+ return rc;
+}
+
+static int fts5SnippetScore(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ int nDocsize, /* Size of column in tokens */
+ unsigned char *aSeen, /* Array with one element per query phrase */
+ int iCol, /* Column to score */
+ int iPos, /* Starting offset to score */
+ int nToken, /* Max tokens per snippet */
+ int *pnScore, /* OUT: Score */
+ int *piPos /* OUT: Adjusted offset */
+){
+ int rc;
+ int i;
+ int ip = 0;
+ int ic = 0;
+ int iOff = 0;
+ int iFirst = -1;
+ int nInst;
+ int nScore = 0;
+ int iLast = 0;
sqlite3_int64 iEnd = (sqlite3_int64)iPos + nToken;
-
- rc = pApi->xInstCount(pFts, &nInst);
- for(i=0; i<nInst && rc==SQLITE_OK; i++){
- rc = pApi->xInst(pFts, i, &ip, &ic, &iOff);
+
+ rc = pApi->xInstCount(pFts, &nInst);
+ for(i=0; i<nInst && rc==SQLITE_OK; i++){
+ rc = pApi->xInst(pFts, i, &ip, &ic, &iOff);
if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<iEnd ){
- nScore += (aSeen[ip] ? 1 : 1000);
- aSeen[ip] = 1;
- if( iFirst<0 ) iFirst = iOff;
- iLast = iOff + pApi->xPhraseSize(pFts, ip);
- }
- }
-
- *pnScore = nScore;
- if( piPos ){
+ nScore += (aSeen[ip] ? 1 : 1000);
+ aSeen[ip] = 1;
+ if( iFirst<0 ) iFirst = iOff;
+ iLast = iOff + pApi->xPhraseSize(pFts, ip);
+ }
+ }
+
+ *pnScore = nScore;
+ if( piPos ){
sqlite3_int64 iAdj = iFirst - (nToken - (iLast-iFirst)) / 2;
- if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken;
- if( iAdj<0 ) iAdj = 0;
+ if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken;
+ if( iAdj<0 ) iAdj = 0;
*piPos = (int)iAdj;
- }
-
- return rc;
-}
-
-/*
+ }
+
+ return rc;
+}
+
+/*
** Return the value in pVal interpreted as utf-8 text. Except, if pVal
-** contains a NULL value, return a pointer to a static string zero
-** bytes in length instead of a NULL pointer.
-*/
-static const char *fts5ValueToText(sqlite3_value *pVal){
- const char *zRet = (const char*)sqlite3_value_text(pVal);
- return zRet ? zRet : "";
-}
-
-/*
-** Implementation of snippet() function.
-*/
-static void fts5SnippetFunction(
- const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
- Fts5Context *pFts, /* First arg to pass to pApi functions */
- sqlite3_context *pCtx, /* Context for returning result/error */
- int nVal, /* Number of values in apVal[] array */
- sqlite3_value **apVal /* Array of trailing arguments */
-){
- HighlightContext ctx;
- int rc = SQLITE_OK; /* Return code */
- int iCol; /* 1st argument to snippet() */
- const char *zEllips; /* 4th argument to snippet() */
- int nToken; /* 5th argument to snippet() */
- int nInst = 0; /* Number of instance matches this row */
- int i; /* Used to iterate through instances */
- int nPhrase; /* Number of phrases in query */
- unsigned char *aSeen; /* Array of "seen instance" flags */
- int iBestCol; /* Column containing best snippet */
- int iBestStart = 0; /* First token of best snippet */
- int nBestScore = 0; /* Score of best snippet */
- int nColSize = 0; /* Total size of iBestCol in tokens */
- Fts5SFinder sFinder; /* Used to find the beginnings of sentences */
- int nCol;
-
- if( nVal!=5 ){
- const char *zErr = "wrong number of arguments to function snippet()";
- sqlite3_result_error(pCtx, zErr, -1);
- return;
- }
-
- nCol = pApi->xColumnCount(pFts);
- memset(&ctx, 0, sizeof(HighlightContext));
- iCol = sqlite3_value_int(apVal[0]);
- ctx.zOpen = fts5ValueToText(apVal[1]);
- ctx.zClose = fts5ValueToText(apVal[2]);
- zEllips = fts5ValueToText(apVal[3]);
- nToken = sqlite3_value_int(apVal[4]);
-
- iBestCol = (iCol>=0 ? iCol : 0);
- nPhrase = pApi->xPhraseCount(pFts);
- aSeen = sqlite3_malloc(nPhrase);
- if( aSeen==0 ){
- rc = SQLITE_NOMEM;
- }
- if( rc==SQLITE_OK ){
- rc = pApi->xInstCount(pFts, &nInst);
- }
-
- memset(&sFinder, 0, sizeof(Fts5SFinder));
- for(i=0; i<nCol; i++){
- if( iCol<0 || iCol==i ){
- int nDoc;
- int nDocsize;
- int ii;
- sFinder.iPos = 0;
- sFinder.nFirst = 0;
- rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc);
- if( rc!=SQLITE_OK ) break;
+** contains a NULL value, return a pointer to a static string zero
+** bytes in length instead of a NULL pointer.
+*/
+static const char *fts5ValueToText(sqlite3_value *pVal){
+ const char *zRet = (const char*)sqlite3_value_text(pVal);
+ return zRet ? zRet : "";
+}
+
+/*
+** Implementation of snippet() function.
+*/
+static void fts5SnippetFunction(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+){
+ HighlightContext ctx;
+ int rc = SQLITE_OK; /* Return code */
+ int iCol; /* 1st argument to snippet() */
+ const char *zEllips; /* 4th argument to snippet() */
+ int nToken; /* 5th argument to snippet() */
+ int nInst = 0; /* Number of instance matches this row */
+ int i; /* Used to iterate through instances */
+ int nPhrase; /* Number of phrases in query */
+ unsigned char *aSeen; /* Array of "seen instance" flags */
+ int iBestCol; /* Column containing best snippet */
+ int iBestStart = 0; /* First token of best snippet */
+ int nBestScore = 0; /* Score of best snippet */
+ int nColSize = 0; /* Total size of iBestCol in tokens */
+ Fts5SFinder sFinder; /* Used to find the beginnings of sentences */
+ int nCol;
+
+ if( nVal!=5 ){
+ const char *zErr = "wrong number of arguments to function snippet()";
+ sqlite3_result_error(pCtx, zErr, -1);
+ return;
+ }
+
+ nCol = pApi->xColumnCount(pFts);
+ memset(&ctx, 0, sizeof(HighlightContext));
+ iCol = sqlite3_value_int(apVal[0]);
+ ctx.zOpen = fts5ValueToText(apVal[1]);
+ ctx.zClose = fts5ValueToText(apVal[2]);
+ zEllips = fts5ValueToText(apVal[3]);
+ nToken = sqlite3_value_int(apVal[4]);
+
+ iBestCol = (iCol>=0 ? iCol : 0);
+ nPhrase = pApi->xPhraseCount(pFts);
+ aSeen = sqlite3_malloc(nPhrase);
+ if( aSeen==0 ){
+ rc = SQLITE_NOMEM;
+ }
+ if( rc==SQLITE_OK ){
+ rc = pApi->xInstCount(pFts, &nInst);
+ }
+
+ memset(&sFinder, 0, sizeof(Fts5SFinder));
+ for(i=0; i<nCol; i++){
+ if( iCol<0 || iCol==i ){
+ int nDoc;
+ int nDocsize;
+ int ii;
+ sFinder.iPos = 0;
+ sFinder.nFirst = 0;
+ rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc);
+ if( rc!=SQLITE_OK ) break;
rc = pApi->xTokenize(pFts,
- sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb
- );
- if( rc!=SQLITE_OK ) break;
- rc = pApi->xColumnSize(pFts, i, &nDocsize);
- if( rc!=SQLITE_OK ) break;
-
- for(ii=0; rc==SQLITE_OK && ii<nInst; ii++){
- int ip, ic, io;
- int iAdj;
- int nScore;
- int jj;
-
- rc = pApi->xInst(pFts, ii, &ip, &ic, &io);
+ sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb
+ );
+ if( rc!=SQLITE_OK ) break;
+ rc = pApi->xColumnSize(pFts, i, &nDocsize);
+ if( rc!=SQLITE_OK ) break;
+
+ for(ii=0; rc==SQLITE_OK && ii<nInst; ii++){
+ int ip, ic, io;
+ int iAdj;
+ int nScore;
+ int jj;
+
+ rc = pApi->xInst(pFts, ii, &ip, &ic, &io);
if( ic!=i ) continue;
if( io>nDocsize ) rc = FTS5_CORRUPT;
if( rc!=SQLITE_OK ) continue;
- memset(aSeen, 0, nPhrase);
- rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
- io, nToken, &nScore, &iAdj
- );
- if( rc==SQLITE_OK && nScore>nBestScore ){
- nBestScore = nScore;
- iBestCol = i;
- iBestStart = iAdj;
- nColSize = nDocsize;
- }
-
- if( rc==SQLITE_OK && sFinder.nFirst && nDocsize>nToken ){
- for(jj=0; jj<(sFinder.nFirst-1); jj++){
- if( sFinder.aFirst[jj+1]>io ) break;
- }
-
- if( sFinder.aFirst[jj]<io ){
- memset(aSeen, 0, nPhrase);
+ memset(aSeen, 0, nPhrase);
+ rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
+ io, nToken, &nScore, &iAdj
+ );
+ if( rc==SQLITE_OK && nScore>nBestScore ){
+ nBestScore = nScore;
+ iBestCol = i;
+ iBestStart = iAdj;
+ nColSize = nDocsize;
+ }
+
+ if( rc==SQLITE_OK && sFinder.nFirst && nDocsize>nToken ){
+ for(jj=0; jj<(sFinder.nFirst-1); jj++){
+ if( sFinder.aFirst[jj+1]>io ) break;
+ }
+
+ if( sFinder.aFirst[jj]<io ){
+ memset(aSeen, 0, nPhrase);
rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
- sFinder.aFirst[jj], nToken, &nScore, 0
- );
-
- nScore += (sFinder.aFirst[jj]==0 ? 120 : 100);
- if( rc==SQLITE_OK && nScore>nBestScore ){
- nBestScore = nScore;
- iBestCol = i;
- iBestStart = sFinder.aFirst[jj];
- nColSize = nDocsize;
- }
- }
- }
- }
- }
- }
-
- if( rc==SQLITE_OK ){
- rc = pApi->xColumnText(pFts, iBestCol, &ctx.zIn, &ctx.nIn);
- }
- if( rc==SQLITE_OK && nColSize==0 ){
- rc = pApi->xColumnSize(pFts, iBestCol, &nColSize);
- }
- if( ctx.zIn ){
- if( rc==SQLITE_OK ){
- rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter);
- }
-
- ctx.iRangeStart = iBestStart;
- ctx.iRangeEnd = iBestStart + nToken - 1;
-
- if( iBestStart>0 ){
- fts5HighlightAppend(&rc, &ctx, zEllips, -1);
- }
-
- /* Advance iterator ctx.iter so that it points to the first coalesced
- ** phrase instance at or following position iBestStart. */
- while( ctx.iter.iStart>=0 && ctx.iter.iStart<iBestStart && rc==SQLITE_OK ){
- rc = fts5CInstIterNext(&ctx.iter);
- }
-
- if( rc==SQLITE_OK ){
- rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
- }
- if( ctx.iRangeEnd>=(nColSize-1) ){
- fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
- }else{
- fts5HighlightAppend(&rc, &ctx, zEllips, -1);
- }
- }
- if( rc==SQLITE_OK ){
- sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT);
- }else{
- sqlite3_result_error_code(pCtx, rc);
- }
- sqlite3_free(ctx.zOut);
- sqlite3_free(aSeen);
- sqlite3_free(sFinder.aFirst);
-}
-
-/************************************************************************/
-
-/*
-** The first time the bm25() function is called for a query, an instance
-** of the following structure is allocated and populated.
-*/
-typedef struct Fts5Bm25Data Fts5Bm25Data;
-struct Fts5Bm25Data {
- int nPhrase; /* Number of phrases in query */
- double avgdl; /* Average number of tokens in each row */
- double *aIDF; /* IDF for each phrase */
- double *aFreq; /* Array used to calculate phrase freq. */
-};
-
-/*
-** Callback used by fts5Bm25GetData() to count the number of rows in the
-** table matched by each individual phrase within the query.
-*/
-static int fts5CountCb(
+ sFinder.aFirst[jj], nToken, &nScore, 0
+ );
+
+ nScore += (sFinder.aFirst[jj]==0 ? 120 : 100);
+ if( rc==SQLITE_OK && nScore>nBestScore ){
+ nBestScore = nScore;
+ iBestCol = i;
+ iBestStart = sFinder.aFirst[jj];
+ nColSize = nDocsize;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = pApi->xColumnText(pFts, iBestCol, &ctx.zIn, &ctx.nIn);
+ }
+ if( rc==SQLITE_OK && nColSize==0 ){
+ rc = pApi->xColumnSize(pFts, iBestCol, &nColSize);
+ }
+ if( ctx.zIn ){
+ if( rc==SQLITE_OK ){
+ rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter);
+ }
+
+ ctx.iRangeStart = iBestStart;
+ ctx.iRangeEnd = iBestStart + nToken - 1;
+
+ if( iBestStart>0 ){
+ fts5HighlightAppend(&rc, &ctx, zEllips, -1);
+ }
+
+ /* Advance iterator ctx.iter so that it points to the first coalesced
+ ** phrase instance at or following position iBestStart. */
+ while( ctx.iter.iStart>=0 && ctx.iter.iStart<iBestStart && rc==SQLITE_OK ){
+ rc = fts5CInstIterNext(&ctx.iter);
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
+ }
+ if( ctx.iRangeEnd>=(nColSize-1) ){
+ fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
+ }else{
+ fts5HighlightAppend(&rc, &ctx, zEllips, -1);
+ }
+ }
+ if( rc==SQLITE_OK ){
+ sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_result_error_code(pCtx, rc);
+ }
+ sqlite3_free(ctx.zOut);
+ sqlite3_free(aSeen);
+ sqlite3_free(sFinder.aFirst);
+}
+
+/************************************************************************/
+
+/*
+** The first time the bm25() function is called for a query, an instance
+** of the following structure is allocated and populated.
+*/
+typedef struct Fts5Bm25Data Fts5Bm25Data;
+struct Fts5Bm25Data {
+ int nPhrase; /* Number of phrases in query */
+ double avgdl; /* Average number of tokens in each row */
+ double *aIDF; /* IDF for each phrase */
+ double *aFreq; /* Array used to calculate phrase freq. */
+};
+
+/*
+** Callback used by fts5Bm25GetData() to count the number of rows in the
+** table matched by each individual phrase within the query.
+*/
+static int fts5CountCb(
const Fts5ExtensionApi *pApi,
- Fts5Context *pFts,
- void *pUserData /* Pointer to sqlite3_int64 variable */
-){
- sqlite3_int64 *pn = (sqlite3_int64*)pUserData;
- UNUSED_PARAM2(pApi, pFts);
- (*pn)++;
- return SQLITE_OK;
-}
-
-/*
+ Fts5Context *pFts,
+ void *pUserData /* Pointer to sqlite3_int64 variable */
+){
+ sqlite3_int64 *pn = (sqlite3_int64*)pUserData;
+ UNUSED_PARAM2(pApi, pFts);
+ (*pn)++;
+ return SQLITE_OK;
+}
+
+/*
** Set *ppData to point to the Fts5Bm25Data object for the current query.
-** If the object has not already been allocated, allocate and populate it
-** now.
-*/
-static int fts5Bm25GetData(
+** If the object has not already been allocated, allocate and populate it
+** now.
+*/
+static int fts5Bm25GetData(
const Fts5ExtensionApi *pApi,
- Fts5Context *pFts,
- Fts5Bm25Data **ppData /* OUT: bm25-data object for this query */
-){
- int rc = SQLITE_OK; /* Return code */
- Fts5Bm25Data *p; /* Object to return */
-
+ Fts5Context *pFts,
+ Fts5Bm25Data **ppData /* OUT: bm25-data object for this query */
+){
+ int rc = SQLITE_OK; /* Return code */
+ Fts5Bm25Data *p; /* Object to return */
+
p = (Fts5Bm25Data*)pApi->xGetAuxdata(pFts, 0);
- if( p==0 ){
- int nPhrase; /* Number of phrases in query */
- sqlite3_int64 nRow = 0; /* Number of rows in table */
- sqlite3_int64 nToken = 0; /* Number of tokens in table */
+ if( p==0 ){
+ int nPhrase; /* Number of phrases in query */
+ sqlite3_int64 nRow = 0; /* Number of rows in table */
+ sqlite3_int64 nToken = 0; /* Number of tokens in table */
sqlite3_int64 nByte; /* Bytes of space to allocate */
- int i;
-
- /* Allocate the Fts5Bm25Data object */
- nPhrase = pApi->xPhraseCount(pFts);
- nByte = sizeof(Fts5Bm25Data) + nPhrase*2*sizeof(double);
+ int i;
+
+ /* Allocate the Fts5Bm25Data object */
+ nPhrase = pApi->xPhraseCount(pFts);
+ nByte = sizeof(Fts5Bm25Data) + nPhrase*2*sizeof(double);
p = (Fts5Bm25Data*)sqlite3_malloc64(nByte);
- if( p==0 ){
- rc = SQLITE_NOMEM;
- }else{
+ if( p==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
memset(p, 0, (size_t)nByte);
- p->nPhrase = nPhrase;
- p->aIDF = (double*)&p[1];
- p->aFreq = &p->aIDF[nPhrase];
- }
-
- /* Calculate the average document length for this FTS5 table */
- if( rc==SQLITE_OK ) rc = pApi->xRowCount(pFts, &nRow);
+ p->nPhrase = nPhrase;
+ p->aIDF = (double*)&p[1];
+ p->aFreq = &p->aIDF[nPhrase];
+ }
+
+ /* Calculate the average document length for this FTS5 table */
+ if( rc==SQLITE_OK ) rc = pApi->xRowCount(pFts, &nRow);
assert( rc!=SQLITE_OK || nRow>0 );
- if( rc==SQLITE_OK ) rc = pApi->xColumnTotalSize(pFts, -1, &nToken);
- if( rc==SQLITE_OK ) p->avgdl = (double)nToken / (double)nRow;
-
- /* Calculate an IDF for each phrase in the query */
- for(i=0; rc==SQLITE_OK && i<nPhrase; i++){
- sqlite3_int64 nHit = 0;
- rc = pApi->xQueryPhrase(pFts, i, (void*)&nHit, fts5CountCb);
- if( rc==SQLITE_OK ){
- /* Calculate the IDF (Inverse Document Frequency) for phrase i.
- ** This is done using the standard BM25 formula as found on wikipedia:
- **
- ** IDF = log( (N - nHit + 0.5) / (nHit + 0.5) )
- **
- ** where "N" is the total number of documents in the set and nHit
- ** is the number that contain at least one instance of the phrase
- ** under consideration.
- **
+ if( rc==SQLITE_OK ) rc = pApi->xColumnTotalSize(pFts, -1, &nToken);
+ if( rc==SQLITE_OK ) p->avgdl = (double)nToken / (double)nRow;
+
+ /* Calculate an IDF for each phrase in the query */
+ for(i=0; rc==SQLITE_OK && i<nPhrase; i++){
+ sqlite3_int64 nHit = 0;
+ rc = pApi->xQueryPhrase(pFts, i, (void*)&nHit, fts5CountCb);
+ if( rc==SQLITE_OK ){
+ /* Calculate the IDF (Inverse Document Frequency) for phrase i.
+ ** This is done using the standard BM25 formula as found on wikipedia:
+ **
+ ** IDF = log( (N - nHit + 0.5) / (nHit + 0.5) )
+ **
+ ** where "N" is the total number of documents in the set and nHit
+ ** is the number that contain at least one instance of the phrase
+ ** under consideration.
+ **
** The problem with this is that if (N < 2*nHit), the IDF is
- ** negative. Which is undesirable. So the mimimum allowable IDF is
- ** (1e-6) - roughly the same as a term that appears in just over
- ** half of set of 5,000,000 documents. */
- double idf = log( (nRow - nHit + 0.5) / (nHit + 0.5) );
- if( idf<=0.0 ) idf = 1e-6;
- p->aIDF[i] = idf;
- }
- }
-
- if( rc!=SQLITE_OK ){
- sqlite3_free(p);
- }else{
- rc = pApi->xSetAuxdata(pFts, p, sqlite3_free);
- }
- if( rc!=SQLITE_OK ) p = 0;
- }
- *ppData = p;
- return rc;
-}
-
-/*
-** Implementation of bm25() function.
-*/
-static void fts5Bm25Function(
- const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
- Fts5Context *pFts, /* First arg to pass to pApi functions */
- sqlite3_context *pCtx, /* Context for returning result/error */
- int nVal, /* Number of values in apVal[] array */
- sqlite3_value **apVal /* Array of trailing arguments */
-){
- const double k1 = 1.2; /* Constant "k1" from BM25 formula */
- const double b = 0.75; /* Constant "b" from BM25 formula */
+ ** negative. Which is undesirable. So the mimimum allowable IDF is
+ ** (1e-6) - roughly the same as a term that appears in just over
+ ** half of set of 5,000,000 documents. */
+ double idf = log( (nRow - nHit + 0.5) / (nHit + 0.5) );
+ if( idf<=0.0 ) idf = 1e-6;
+ p->aIDF[i] = idf;
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(p);
+ }else{
+ rc = pApi->xSetAuxdata(pFts, p, sqlite3_free);
+ }
+ if( rc!=SQLITE_OK ) p = 0;
+ }
+ *ppData = p;
+ return rc;
+}
+
+/*
+** Implementation of bm25() function.
+*/
+static void fts5Bm25Function(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+){
+ const double k1 = 1.2; /* Constant "k1" from BM25 formula */
+ const double b = 0.75; /* Constant "b" from BM25 formula */
int rc; /* Error code */
- double score = 0.0; /* SQL function return value */
- Fts5Bm25Data *pData; /* Values allocated/calculated once only */
- int i; /* Iterator variable */
- int nInst = 0; /* Value returned by xInstCount() */
- double D = 0.0; /* Total number of tokens in row */
- double *aFreq = 0; /* Array of phrase freq. for current row */
-
- /* Calculate the phrase frequency (symbol "f(qi,D)" in the documentation)
- ** for each phrase in the query for the current row. */
- rc = fts5Bm25GetData(pApi, pFts, &pData);
- if( rc==SQLITE_OK ){
- aFreq = pData->aFreq;
- memset(aFreq, 0, sizeof(double) * pData->nPhrase);
- rc = pApi->xInstCount(pFts, &nInst);
- }
- for(i=0; rc==SQLITE_OK && i<nInst; i++){
- int ip; int ic; int io;
- rc = pApi->xInst(pFts, i, &ip, &ic, &io);
- if( rc==SQLITE_OK ){
- double w = (nVal > ic) ? sqlite3_value_double(apVal[ic]) : 1.0;
- aFreq[ip] += w;
- }
- }
-
- /* Figure out the total size of the current row in tokens. */
- if( rc==SQLITE_OK ){
- int nTok;
- rc = pApi->xColumnSize(pFts, -1, &nTok);
- D = (double)nTok;
- }
-
+ double score = 0.0; /* SQL function return value */
+ Fts5Bm25Data *pData; /* Values allocated/calculated once only */
+ int i; /* Iterator variable */
+ int nInst = 0; /* Value returned by xInstCount() */
+ double D = 0.0; /* Total number of tokens in row */
+ double *aFreq = 0; /* Array of phrase freq. for current row */
+
+ /* Calculate the phrase frequency (symbol "f(qi,D)" in the documentation)
+ ** for each phrase in the query for the current row. */
+ rc = fts5Bm25GetData(pApi, pFts, &pData);
+ if( rc==SQLITE_OK ){
+ aFreq = pData->aFreq;
+ memset(aFreq, 0, sizeof(double) * pData->nPhrase);
+ rc = pApi->xInstCount(pFts, &nInst);
+ }
+ for(i=0; rc==SQLITE_OK && i<nInst; i++){
+ int ip; int ic; int io;
+ rc = pApi->xInst(pFts, i, &ip, &ic, &io);
+ if( rc==SQLITE_OK ){
+ double w = (nVal > ic) ? sqlite3_value_double(apVal[ic]) : 1.0;
+ aFreq[ip] += w;
+ }
+ }
+
+ /* Figure out the total size of the current row in tokens. */
+ if( rc==SQLITE_OK ){
+ int nTok;
+ rc = pApi->xColumnSize(pFts, -1, &nTok);
+ D = (double)nTok;
+ }
+
/* Determine and return the BM25 score for the current row. Or, if an
** error has occurred, throw an exception. */
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
for(i=0; i<pData->nPhrase; i++){
score += pData->aIDF[i] * (
( aFreq[i] * (k1 + 1.0) ) /
( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) )
);
}
- sqlite3_result_double(pCtx, -1.0 * score);
- }else{
- sqlite3_result_error_code(pCtx, rc);
- }
-}
-
-static int sqlite3Fts5AuxInit(fts5_api *pApi){
- struct Builtin {
- const char *zFunc; /* Function name (nul-terminated) */
- void *pUserData; /* User-data pointer */
- fts5_extension_function xFunc;/* Callback function */
- void (*xDestroy)(void*); /* Destructor function */
- } aBuiltin [] = {
- { "snippet", 0, fts5SnippetFunction, 0 },
- { "highlight", 0, fts5HighlightFunction, 0 },
- { "bm25", 0, fts5Bm25Function, 0 },
- };
- int rc = SQLITE_OK; /* Return code */
- int i; /* To iterate through builtin functions */
-
- for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
- rc = pApi->xCreateFunction(pApi,
- aBuiltin[i].zFunc,
- aBuiltin[i].pUserData,
- aBuiltin[i].xFunc,
- aBuiltin[i].xDestroy
- );
- }
-
- return rc;
-}
-
-/*
-** 2014 May 31
-**
-** 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.
-**
-******************************************************************************
-*/
-
-
-
-/* #include "fts5Int.h" */
-
-static int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){
- if( (u32)pBuf->nSpace<nByte ){
+ sqlite3_result_double(pCtx, -1.0 * score);
+ }else{
+ sqlite3_result_error_code(pCtx, rc);
+ }
+}
+
+static int sqlite3Fts5AuxInit(fts5_api *pApi){
+ struct Builtin {
+ const char *zFunc; /* Function name (nul-terminated) */
+ void *pUserData; /* User-data pointer */
+ fts5_extension_function xFunc;/* Callback function */
+ void (*xDestroy)(void*); /* Destructor function */
+ } aBuiltin [] = {
+ { "snippet", 0, fts5SnippetFunction, 0 },
+ { "highlight", 0, fts5HighlightFunction, 0 },
+ { "bm25", 0, fts5Bm25Function, 0 },
+ };
+ int rc = SQLITE_OK; /* Return code */
+ int i; /* To iterate through builtin functions */
+
+ for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
+ rc = pApi->xCreateFunction(pApi,
+ aBuiltin[i].zFunc,
+ aBuiltin[i].pUserData,
+ aBuiltin[i].xFunc,
+ aBuiltin[i].xDestroy
+ );
+ }
+
+ return rc;
+}
+
+/*
+** 2014 May 31
+**
+** 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.
+**
+******************************************************************************
+*/
+
+
+
+/* #include "fts5Int.h" */
+
+static int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){
+ if( (u32)pBuf->nSpace<nByte ){
u64 nNew = pBuf->nSpace ? pBuf->nSpace : 64;
- u8 *pNew;
- while( nNew<nByte ){
- nNew = nNew * 2;
- }
+ u8 *pNew;
+ while( nNew<nByte ){
+ nNew = nNew * 2;
+ }
pNew = sqlite3_realloc64(pBuf->p, nNew);
- if( pNew==0 ){
- *pRc = SQLITE_NOMEM;
- return 1;
- }else{
+ if( pNew==0 ){
+ *pRc = SQLITE_NOMEM;
+ return 1;
+ }else{
pBuf->nSpace = (int)nNew;
- pBuf->p = pNew;
- }
- }
- return 0;
-}
-
-
-/*
-** Encode value iVal as an SQLite varint and append it to the buffer object
-** pBuf. If an OOM error occurs, set the error code in p.
-*/
-static void sqlite3Fts5BufferAppendVarint(int *pRc, Fts5Buffer *pBuf, i64 iVal){
- if( fts5BufferGrow(pRc, pBuf, 9) ) return;
- pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iVal);
-}
-
-static void sqlite3Fts5Put32(u8 *aBuf, int iVal){
- aBuf[0] = (iVal>>24) & 0x00FF;
- aBuf[1] = (iVal>>16) & 0x00FF;
- aBuf[2] = (iVal>> 8) & 0x00FF;
- aBuf[3] = (iVal>> 0) & 0x00FF;
-}
-
-static int sqlite3Fts5Get32(const u8 *aBuf){
+ pBuf->p = pNew;
+ }
+ }
+ return 0;
+}
+
+
+/*
+** Encode value iVal as an SQLite varint and append it to the buffer object
+** pBuf. If an OOM error occurs, set the error code in p.
+*/
+static void sqlite3Fts5BufferAppendVarint(int *pRc, Fts5Buffer *pBuf, i64 iVal){
+ if( fts5BufferGrow(pRc, pBuf, 9) ) return;
+ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iVal);
+}
+
+static void sqlite3Fts5Put32(u8 *aBuf, int iVal){
+ aBuf[0] = (iVal>>24) & 0x00FF;
+ aBuf[1] = (iVal>>16) & 0x00FF;
+ aBuf[2] = (iVal>> 8) & 0x00FF;
+ aBuf[3] = (iVal>> 0) & 0x00FF;
+}
+
+static int sqlite3Fts5Get32(const u8 *aBuf){
return (int)((((u32)aBuf[0])<<24) + (aBuf[1]<<16) + (aBuf[2]<<8) + aBuf[3]);
-}
-
-/*
+}
+
+/*
** Append buffer nData/pData to buffer pBuf. If an OOM error occurs, set
-** the error code in p. If an error has already occurred when this function
-** is called, it is a no-op.
-*/
-static void sqlite3Fts5BufferAppendBlob(
- int *pRc,
+** the error code in p. If an error has already occurred when this function
+** is called, it is a no-op.
+*/
+static void sqlite3Fts5BufferAppendBlob(
+ int *pRc,
Fts5Buffer *pBuf,
u32 nData,
- const u8 *pData
-){
- if( nData ){
- if( fts5BufferGrow(pRc, pBuf, nData) ) return;
- memcpy(&pBuf->p[pBuf->n], pData, nData);
- pBuf->n += nData;
- }
-}
-
-/*
-** Append the nul-terminated string zStr to the buffer pBuf. This function
+ const u8 *pData
+){
+ if( nData ){
+ if( fts5BufferGrow(pRc, pBuf, nData) ) return;
+ memcpy(&pBuf->p[pBuf->n], pData, nData);
+ pBuf->n += nData;
+ }
+}
+
+/*
+** Append the nul-terminated string zStr to the buffer pBuf. This function
** ensures that the byte following the buffer data is set to 0x00, even
-** though this byte is not included in the pBuf->n count.
-*/
-static void sqlite3Fts5BufferAppendString(
- int *pRc,
+** though this byte is not included in the pBuf->n count.
+*/
+static void sqlite3Fts5BufferAppendString(
+ int *pRc,
Fts5Buffer *pBuf,
- const char *zStr
-){
- int nStr = (int)strlen(zStr);
- sqlite3Fts5BufferAppendBlob(pRc, pBuf, nStr+1, (const u8*)zStr);
- pBuf->n--;
-}
-
-/*
-** Argument zFmt is a printf() style format string. This function performs
-** the printf() style processing, then appends the results to buffer pBuf.
-**
+ const char *zStr
+){
+ int nStr = (int)strlen(zStr);
+ sqlite3Fts5BufferAppendBlob(pRc, pBuf, nStr+1, (const u8*)zStr);
+ pBuf->n--;
+}
+
+/*
+** Argument zFmt is a printf() style format string. This function performs
+** the printf() style processing, then appends the results to buffer pBuf.
+**
** Like sqlite3Fts5BufferAppendString(), this function ensures that the byte
-** following the buffer data is set to 0x00, even though this byte is not
-** included in the pBuf->n count.
+** following the buffer data is set to 0x00, even though this byte is not
+** included in the pBuf->n count.
*/
-static void sqlite3Fts5BufferAppendPrintf(
- int *pRc,
+static void sqlite3Fts5BufferAppendPrintf(
+ int *pRc,
Fts5Buffer *pBuf,
- char *zFmt, ...
-){
- if( *pRc==SQLITE_OK ){
- char *zTmp;
- va_list ap;
- va_start(ap, zFmt);
- zTmp = sqlite3_vmprintf(zFmt, ap);
- va_end(ap);
-
- if( zTmp==0 ){
- *pRc = SQLITE_NOMEM;
- }else{
- sqlite3Fts5BufferAppendString(pRc, pBuf, zTmp);
- sqlite3_free(zTmp);
- }
- }
-}
-
-static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...){
- char *zRet = 0;
- if( *pRc==SQLITE_OK ){
- va_list ap;
- va_start(ap, zFmt);
- zRet = sqlite3_vmprintf(zFmt, ap);
- va_end(ap);
- if( zRet==0 ){
+ char *zFmt, ...
+){
+ if( *pRc==SQLITE_OK ){
+ char *zTmp;
+ va_list ap;
+ va_start(ap, zFmt);
+ zTmp = sqlite3_vmprintf(zFmt, ap);
+ va_end(ap);
+
+ if( zTmp==0 ){
*pRc = SQLITE_NOMEM;
- }
- }
- return zRet;
-}
-
-
-/*
-** Free any buffer allocated by pBuf. Zero the structure before returning.
-*/
-static void sqlite3Fts5BufferFree(Fts5Buffer *pBuf){
- sqlite3_free(pBuf->p);
- memset(pBuf, 0, sizeof(Fts5Buffer));
-}
-
-/*
+ }else{
+ sqlite3Fts5BufferAppendString(pRc, pBuf, zTmp);
+ sqlite3_free(zTmp);
+ }
+ }
+}
+
+static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...){
+ char *zRet = 0;
+ if( *pRc==SQLITE_OK ){
+ va_list ap;
+ va_start(ap, zFmt);
+ zRet = sqlite3_vmprintf(zFmt, ap);
+ va_end(ap);
+ if( zRet==0 ){
+ *pRc = SQLITE_NOMEM;
+ }
+ }
+ return zRet;
+}
+
+
+/*
+** Free any buffer allocated by pBuf. Zero the structure before returning.
+*/
+static void sqlite3Fts5BufferFree(Fts5Buffer *pBuf){
+ sqlite3_free(pBuf->p);
+ memset(pBuf, 0, sizeof(Fts5Buffer));
+}
+
+/*
** Zero the contents of the buffer object. But do not free the associated
-** memory allocation.
-*/
-static void sqlite3Fts5BufferZero(Fts5Buffer *pBuf){
- pBuf->n = 0;
-}
-
-/*
-** Set the buffer to contain nData/pData. If an OOM error occurs, leave an
-** the error code in p. If an error has already occurred when this function
-** is called, it is a no-op.
-*/
-static void sqlite3Fts5BufferSet(
- int *pRc,
+** memory allocation.
+*/
+static void sqlite3Fts5BufferZero(Fts5Buffer *pBuf){
+ pBuf->n = 0;
+}
+
+/*
+** Set the buffer to contain nData/pData. If an OOM error occurs, leave an
+** the error code in p. If an error has already occurred when this function
+** is called, it is a no-op.
+*/
+static void sqlite3Fts5BufferSet(
+ int *pRc,
Fts5Buffer *pBuf,
int nData,
- const u8 *pData
-){
- pBuf->n = 0;
- sqlite3Fts5BufferAppendBlob(pRc, pBuf, nData, pData);
-}
-
-static int sqlite3Fts5PoslistNext64(
- const u8 *a, int n, /* Buffer containing poslist */
- int *pi, /* IN/OUT: Offset within a[] */
- i64 *piOff /* IN/OUT: Current offset */
-){
- int i = *pi;
- if( i>=n ){
- /* EOF */
- *piOff = -1;
+ const u8 *pData
+){
+ pBuf->n = 0;
+ sqlite3Fts5BufferAppendBlob(pRc, pBuf, nData, pData);
+}
+
+static int sqlite3Fts5PoslistNext64(
+ const u8 *a, int n, /* Buffer containing poslist */
+ int *pi, /* IN/OUT: Offset within a[] */
+ i64 *piOff /* IN/OUT: Current offset */
+){
+ int i = *pi;
+ if( i>=n ){
+ /* EOF */
+ *piOff = -1;
return 1;
- }else{
- i64 iOff = *piOff;
+ }else{
+ i64 iOff = *piOff;
u32 iVal;
- fts5FastGetVarint32(a, i, iVal);
+ fts5FastGetVarint32(a, i, iVal);
if( iVal<=1 ){
if( iVal==0 ){
*pi = i;
return 0;
}
- fts5FastGetVarint32(a, i, iVal);
- iOff = ((i64)iVal) << 32;
+ fts5FastGetVarint32(a, i, iVal);
+ iOff = ((i64)iVal) << 32;
assert( iOff>=0 );
- fts5FastGetVarint32(a, i, iVal);
+ fts5FastGetVarint32(a, i, iVal);
if( iVal<2 ){
/* This is a corrupt record. So stop parsing it here. */
*piOff = -1;
@@ -218127,47 +218127,47 @@ static int sqlite3Fts5PoslistNext64(
*piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
}else{
*piOff = (iOff & (i64)0x7FFFFFFF<<32)+((iOff + (iVal-2)) & 0x7FFFFFFF);
- }
- *pi = i;
+ }
+ *pi = i;
assert_nc( *piOff>=iOff );
- return 0;
- }
-}
-
-
-/*
-** Advance the iterator object passed as the only argument. Return true
-** if the iterator reaches EOF, or false otherwise.
-*/
-static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader *pIter){
- if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos) ){
- pIter->bEof = 1;
- }
- return pIter->bEof;
-}
-
-static int sqlite3Fts5PoslistReaderInit(
- const u8 *a, int n, /* Poslist buffer to iterate through */
- Fts5PoslistReader *pIter /* Iterator object to initialize */
-){
- memset(pIter, 0, sizeof(*pIter));
- pIter->a = a;
- pIter->n = n;
- sqlite3Fts5PoslistReaderNext(pIter);
- return pIter->bEof;
-}
-
-/*
-** Append position iPos to the position list being accumulated in buffer
-** pBuf, which must be already be large enough to hold the new data.
-** The previous position written to this list is *piPrev. *piPrev is set
-** to iPos before returning.
-*/
-static void sqlite3Fts5PoslistSafeAppend(
+ return 0;
+ }
+}
+
+
+/*
+** Advance the iterator object passed as the only argument. Return true
+** if the iterator reaches EOF, or false otherwise.
+*/
+static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader *pIter){
+ if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos) ){
+ pIter->bEof = 1;
+ }
+ return pIter->bEof;
+}
+
+static int sqlite3Fts5PoslistReaderInit(
+ const u8 *a, int n, /* Poslist buffer to iterate through */
+ Fts5PoslistReader *pIter /* Iterator object to initialize */
+){
+ memset(pIter, 0, sizeof(*pIter));
+ pIter->a = a;
+ pIter->n = n;
+ sqlite3Fts5PoslistReaderNext(pIter);
+ return pIter->bEof;
+}
+
+/*
+** Append position iPos to the position list being accumulated in buffer
+** pBuf, which must be already be large enough to hold the new data.
+** The previous position written to this list is *piPrev. *piPrev is set
+** to iPos before returning.
+*/
+static void sqlite3Fts5PoslistSafeAppend(
Fts5Buffer *pBuf,
i64 *piPrev,
- i64 iPos
-){
+ i64 iPos
+){
if( iPos>=*piPrev ){
static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
if( (iPos & colmask) != (*piPrev & colmask) ){
@@ -218177,1427 +218177,1427 @@ static void sqlite3Fts5PoslistSafeAppend(
}
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2);
*piPrev = iPos;
- }
-}
-
-static int sqlite3Fts5PoslistWriterAppend(
+ }
+}
+
+static int sqlite3Fts5PoslistWriterAppend(
Fts5Buffer *pBuf,
- Fts5PoslistWriter *pWriter,
- i64 iPos
-){
- int rc = 0; /* Initialized only to suppress erroneous warning from Clang */
- if( fts5BufferGrow(&rc, pBuf, 5+5+5) ) return rc;
- sqlite3Fts5PoslistSafeAppend(pBuf, &pWriter->iPrev, iPos);
- return SQLITE_OK;
-}
-
+ Fts5PoslistWriter *pWriter,
+ i64 iPos
+){
+ int rc = 0; /* Initialized only to suppress erroneous warning from Clang */
+ if( fts5BufferGrow(&rc, pBuf, 5+5+5) ) return rc;
+ sqlite3Fts5PoslistSafeAppend(pBuf, &pWriter->iPrev, iPos);
+ return SQLITE_OK;
+}
+
static void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte){
- void *pRet = 0;
- if( *pRc==SQLITE_OK ){
+ void *pRet = 0;
+ if( *pRc==SQLITE_OK ){
pRet = sqlite3_malloc64(nByte);
- if( pRet==0 ){
- if( nByte>0 ) *pRc = SQLITE_NOMEM;
- }else{
+ if( pRet==0 ){
+ if( nByte>0 ) *pRc = SQLITE_NOMEM;
+ }else{
memset(pRet, 0, (size_t)nByte);
- }
- }
- return pRet;
-}
-
-/*
-** Return a nul-terminated copy of the string indicated by pIn. If nIn
-** is non-negative, then it is the length of the string in bytes. Otherwise,
-** the length of the string is determined using strlen().
-**
-** It is the responsibility of the caller to eventually free the returned
+ }
+ }
+ return pRet;
+}
+
+/*
+** Return a nul-terminated copy of the string indicated by pIn. If nIn
+** is non-negative, then it is the length of the string in bytes. Otherwise,
+** the length of the string is determined using strlen().
+**
+** It is the responsibility of the caller to eventually free the returned
** buffer using sqlite3_free(). If an OOM error occurs, NULL is returned.
-*/
-static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){
- char *zRet = 0;
- if( *pRc==SQLITE_OK ){
- if( nIn<0 ){
- nIn = (int)strlen(pIn);
- }
- zRet = (char*)sqlite3_malloc(nIn+1);
- if( zRet ){
- memcpy(zRet, pIn, nIn);
- zRet[nIn] = '\0';
- }else{
- *pRc = SQLITE_NOMEM;
- }
- }
- return zRet;
-}
-
-
-/*
-** Return true if character 't' may be part of an FTS5 bareword, or false
-** otherwise. Characters that may be part of barewords:
-**
-** * All non-ASCII characters,
-** * The 52 upper and lower case ASCII characters, and
-** * The 10 integer ASCII characters.
-** * The underscore character "_" (0x5F).
-** * The unicode "subsitute" character (0x1A).
-*/
-static int sqlite3Fts5IsBareword(char t){
- u8 aBareword[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 .. 0x0F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* 0x10 .. 0x1F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 .. 0x2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30 .. 0x3F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 .. 0x4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50 .. 0x5F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 .. 0x6F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 /* 0x70 .. 0x7F */
- };
-
- return (t & 0x80) || aBareword[(int)t];
-}
-
-
-/*************************************************************************
-*/
-typedef struct Fts5TermsetEntry Fts5TermsetEntry;
-struct Fts5TermsetEntry {
- char *pTerm;
- int nTerm;
- int iIdx; /* Index (main or aPrefix[] entry) */
- Fts5TermsetEntry *pNext;
-};
-
-struct Fts5Termset {
- Fts5TermsetEntry *apHash[512];
-};
-
-static int sqlite3Fts5TermsetNew(Fts5Termset **pp){
- int rc = SQLITE_OK;
- *pp = sqlite3Fts5MallocZero(&rc, sizeof(Fts5Termset));
- return rc;
-}
-
-static int sqlite3Fts5TermsetAdd(
+*/
+static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){
+ char *zRet = 0;
+ if( *pRc==SQLITE_OK ){
+ if( nIn<0 ){
+ nIn = (int)strlen(pIn);
+ }
+ zRet = (char*)sqlite3_malloc(nIn+1);
+ if( zRet ){
+ memcpy(zRet, pIn, nIn);
+ zRet[nIn] = '\0';
+ }else{
+ *pRc = SQLITE_NOMEM;
+ }
+ }
+ return zRet;
+}
+
+
+/*
+** Return true if character 't' may be part of an FTS5 bareword, or false
+** otherwise. Characters that may be part of barewords:
+**
+** * All non-ASCII characters,
+** * The 52 upper and lower case ASCII characters, and
+** * The 10 integer ASCII characters.
+** * The underscore character "_" (0x5F).
+** * The unicode "subsitute" character (0x1A).
+*/
+static int sqlite3Fts5IsBareword(char t){
+ u8 aBareword[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 .. 0x0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* 0x10 .. 0x1F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 .. 0x2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30 .. 0x3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 .. 0x4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50 .. 0x5F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 .. 0x6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 /* 0x70 .. 0x7F */
+ };
+
+ return (t & 0x80) || aBareword[(int)t];
+}
+
+
+/*************************************************************************
+*/
+typedef struct Fts5TermsetEntry Fts5TermsetEntry;
+struct Fts5TermsetEntry {
+ char *pTerm;
+ int nTerm;
+ int iIdx; /* Index (main or aPrefix[] entry) */
+ Fts5TermsetEntry *pNext;
+};
+
+struct Fts5Termset {
+ Fts5TermsetEntry *apHash[512];
+};
+
+static int sqlite3Fts5TermsetNew(Fts5Termset **pp){
+ int rc = SQLITE_OK;
+ *pp = sqlite3Fts5MallocZero(&rc, sizeof(Fts5Termset));
+ return rc;
+}
+
+static int sqlite3Fts5TermsetAdd(
Fts5Termset *p,
- int iIdx,
+ int iIdx,
const char *pTerm, int nTerm,
- int *pbPresent
-){
- int rc = SQLITE_OK;
- *pbPresent = 0;
- if( p ){
- int i;
- u32 hash = 13;
- Fts5TermsetEntry *pEntry;
-
- /* Calculate a hash value for this term. This is the same hash checksum
- ** used by the fts5_hash.c module. This is not important for correct
- ** operation of the module, but is necessary to ensure that some tests
- ** designed to produce hash table collisions really do work. */
- for(i=nTerm-1; i>=0; i--){
- hash = (hash << 3) ^ hash ^ pTerm[i];
- }
- hash = (hash << 3) ^ hash ^ iIdx;
- hash = hash % ArraySize(p->apHash);
-
- for(pEntry=p->apHash[hash]; pEntry; pEntry=pEntry->pNext){
+ int *pbPresent
+){
+ int rc = SQLITE_OK;
+ *pbPresent = 0;
+ if( p ){
+ int i;
+ u32 hash = 13;
+ Fts5TermsetEntry *pEntry;
+
+ /* Calculate a hash value for this term. This is the same hash checksum
+ ** used by the fts5_hash.c module. This is not important for correct
+ ** operation of the module, but is necessary to ensure that some tests
+ ** designed to produce hash table collisions really do work. */
+ for(i=nTerm-1; i>=0; i--){
+ hash = (hash << 3) ^ hash ^ pTerm[i];
+ }
+ hash = (hash << 3) ^ hash ^ iIdx;
+ hash = hash % ArraySize(p->apHash);
+
+ for(pEntry=p->apHash[hash]; pEntry; pEntry=pEntry->pNext){
if( pEntry->iIdx==iIdx
&& pEntry->nTerm==nTerm
&& memcmp(pEntry->pTerm, pTerm, nTerm)==0
- ){
- *pbPresent = 1;
- break;
- }
- }
-
- if( pEntry==0 ){
- pEntry = sqlite3Fts5MallocZero(&rc, sizeof(Fts5TermsetEntry) + nTerm);
- if( pEntry ){
- pEntry->pTerm = (char*)&pEntry[1];
- pEntry->nTerm = nTerm;
- pEntry->iIdx = iIdx;
- memcpy(pEntry->pTerm, pTerm, nTerm);
- pEntry->pNext = p->apHash[hash];
- p->apHash[hash] = pEntry;
- }
- }
- }
-
- return rc;
-}
-
-static void sqlite3Fts5TermsetFree(Fts5Termset *p){
- if( p ){
- u32 i;
- for(i=0; i<ArraySize(p->apHash); i++){
- Fts5TermsetEntry *pEntry = p->apHash[i];
- while( pEntry ){
- Fts5TermsetEntry *pDel = pEntry;
- pEntry = pEntry->pNext;
- sqlite3_free(pDel);
- }
- }
- sqlite3_free(p);
- }
-}
-
-/*
-** 2014 Jun 09
-**
-** 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 is an SQLite module implementing full-text search.
-*/
-
-
-/* #include "fts5Int.h" */
-
-#define FTS5_DEFAULT_PAGE_SIZE 4050
-#define FTS5_DEFAULT_AUTOMERGE 4
-#define FTS5_DEFAULT_USERMERGE 4
-#define FTS5_DEFAULT_CRISISMERGE 16
-#define FTS5_DEFAULT_HASHSIZE (1024*1024)
-
-/* Maximum allowed page size */
+ ){
+ *pbPresent = 1;
+ break;
+ }
+ }
+
+ if( pEntry==0 ){
+ pEntry = sqlite3Fts5MallocZero(&rc, sizeof(Fts5TermsetEntry) + nTerm);
+ if( pEntry ){
+ pEntry->pTerm = (char*)&pEntry[1];
+ pEntry->nTerm = nTerm;
+ pEntry->iIdx = iIdx;
+ memcpy(pEntry->pTerm, pTerm, nTerm);
+ pEntry->pNext = p->apHash[hash];
+ p->apHash[hash] = pEntry;
+ }
+ }
+ }
+
+ return rc;
+}
+
+static void sqlite3Fts5TermsetFree(Fts5Termset *p){
+ if( p ){
+ u32 i;
+ for(i=0; i<ArraySize(p->apHash); i++){
+ Fts5TermsetEntry *pEntry = p->apHash[i];
+ while( pEntry ){
+ Fts5TermsetEntry *pDel = pEntry;
+ pEntry = pEntry->pNext;
+ sqlite3_free(pDel);
+ }
+ }
+ sqlite3_free(p);
+ }
+}
+
+/*
+** 2014 Jun 09
+**
+** 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 is an SQLite module implementing full-text search.
+*/
+
+
+/* #include "fts5Int.h" */
+
+#define FTS5_DEFAULT_PAGE_SIZE 4050
+#define FTS5_DEFAULT_AUTOMERGE 4
+#define FTS5_DEFAULT_USERMERGE 4
+#define FTS5_DEFAULT_CRISISMERGE 16
+#define FTS5_DEFAULT_HASHSIZE (1024*1024)
+
+/* Maximum allowed page size */
#define FTS5_MAX_PAGE_SIZE (64*1024)
-
-static int fts5_iswhitespace(char x){
- return (x==' ');
-}
-
-static int fts5_isopenquote(char x){
- return (x=='"' || x=='\'' || x=='[' || x=='`');
-}
-
-/*
+
+static int fts5_iswhitespace(char x){
+ return (x==' ');
+}
+
+static int fts5_isopenquote(char x){
+ return (x=='"' || x=='\'' || x=='[' || x=='`');
+}
+
+/*
** Argument pIn points to a character that is part of a nul-terminated
** string. Return a pointer to the first character following *pIn in
-** the string that is not a white-space character.
-*/
-static const char *fts5ConfigSkipWhitespace(const char *pIn){
- const char *p = pIn;
- if( p ){
- while( fts5_iswhitespace(*p) ){ p++; }
- }
- return p;
-}
-
-/*
+** the string that is not a white-space character.
+*/
+static const char *fts5ConfigSkipWhitespace(const char *pIn){
+ const char *p = pIn;
+ if( p ){
+ while( fts5_iswhitespace(*p) ){ p++; }
+ }
+ return p;
+}
+
+/*
** Argument pIn points to a character that is part of a nul-terminated
** string. Return a pointer to the first character following *pIn in
-** the string that is not a "bareword" character.
-*/
-static const char *fts5ConfigSkipBareword(const char *pIn){
- const char *p = pIn;
- while ( sqlite3Fts5IsBareword(*p) ) p++;
- if( p==pIn ) p = 0;
- return p;
-}
-
-static int fts5_isdigit(char a){
- return (a>='0' && a<='9');
-}
-
-
-
-static const char *fts5ConfigSkipLiteral(const char *pIn){
- const char *p = pIn;
- switch( *p ){
- case 'n': case 'N':
- if( sqlite3_strnicmp("null", p, 4)==0 ){
- p = &p[4];
- }else{
- p = 0;
- }
- break;
-
- case 'x': case 'X':
- p++;
- if( *p=='\'' ){
- p++;
+** the string that is not a "bareword" character.
+*/
+static const char *fts5ConfigSkipBareword(const char *pIn){
+ const char *p = pIn;
+ while ( sqlite3Fts5IsBareword(*p) ) p++;
+ if( p==pIn ) p = 0;
+ return p;
+}
+
+static int fts5_isdigit(char a){
+ return (a>='0' && a<='9');
+}
+
+
+
+static const char *fts5ConfigSkipLiteral(const char *pIn){
+ const char *p = pIn;
+ switch( *p ){
+ case 'n': case 'N':
+ if( sqlite3_strnicmp("null", p, 4)==0 ){
+ p = &p[4];
+ }else{
+ p = 0;
+ }
+ break;
+
+ case 'x': case 'X':
+ p++;
+ if( *p=='\'' ){
+ p++;
while( (*p>='a' && *p<='f')
|| (*p>='A' && *p<='F')
|| (*p>='0' && *p<='9')
- ){
- p++;
- }
- if( *p=='\'' && 0==((p-pIn)%2) ){
- p++;
- }else{
- p = 0;
- }
- }else{
- p = 0;
- }
- break;
-
- case '\'':
- p++;
- while( p ){
- if( *p=='\'' ){
- p++;
- if( *p!='\'' ) break;
- }
- p++;
- if( *p==0 ) p = 0;
- }
- break;
-
- default:
- /* maybe a number */
- if( *p=='+' || *p=='-' ) p++;
- while( fts5_isdigit(*p) ) p++;
-
+ ){
+ p++;
+ }
+ if( *p=='\'' && 0==((p-pIn)%2) ){
+ p++;
+ }else{
+ p = 0;
+ }
+ }else{
+ p = 0;
+ }
+ break;
+
+ case '\'':
+ p++;
+ while( p ){
+ if( *p=='\'' ){
+ p++;
+ if( *p!='\'' ) break;
+ }
+ p++;
+ if( *p==0 ) p = 0;
+ }
+ break;
+
+ default:
+ /* maybe a number */
+ if( *p=='+' || *p=='-' ) p++;
+ while( fts5_isdigit(*p) ) p++;
+
/* At this point, if the literal was an integer, the parse is
- ** finished. Or, if it is a floating point value, it may continue
- ** with either a decimal point or an 'E' character. */
- if( *p=='.' && fts5_isdigit(p[1]) ){
- p += 2;
- while( fts5_isdigit(*p) ) p++;
- }
- if( p==pIn ) p = 0;
-
- break;
- }
-
- return p;
-}
-
-/*
-** The first character of the string pointed to by argument z is guaranteed
-** to be an open-quote character (see function fts5_isopenquote()).
-**
-** This function searches for the corresponding close-quote character within
-** the string and, if found, dequotes the string in place and adds a new
-** nul-terminator byte.
-**
-** If the close-quote is found, the value returned is the byte offset of
+ ** finished. Or, if it is a floating point value, it may continue
+ ** with either a decimal point or an 'E' character. */
+ if( *p=='.' && fts5_isdigit(p[1]) ){
+ p += 2;
+ while( fts5_isdigit(*p) ) p++;
+ }
+ if( p==pIn ) p = 0;
+
+ break;
+ }
+
+ return p;
+}
+
+/*
+** The first character of the string pointed to by argument z is guaranteed
+** to be an open-quote character (see function fts5_isopenquote()).
+**
+** This function searches for the corresponding close-quote character within
+** the string and, if found, dequotes the string in place and adds a new
+** nul-terminator byte.
+**
+** If the close-quote is found, the value returned is the byte offset of
** the character immediately following it. Or, if the close-quote is not
** found, -1 is returned. If -1 is returned, the buffer is left in an
-** undefined state.
-*/
-static int fts5Dequote(char *z){
- char q;
- int iIn = 1;
- int iOut = 0;
- q = z[0];
-
- /* Set stack variable q to the close-quote character */
- assert( q=='[' || q=='\'' || q=='"' || q=='`' );
+** undefined state.
+*/
+static int fts5Dequote(char *z){
+ char q;
+ int iIn = 1;
+ int iOut = 0;
+ q = z[0];
+
+ /* Set stack variable q to the close-quote character */
+ assert( q=='[' || q=='\'' || q=='"' || q=='`' );
if( q=='[' ) q = ']';
-
+
while( z[iIn] ){
- if( z[iIn]==q ){
- if( z[iIn+1]!=q ){
- /* Character iIn was the close quote. */
- iIn++;
- break;
- }else{
- /* Character iIn and iIn+1 form an escaped quote character. Skip
+ if( z[iIn]==q ){
+ if( z[iIn+1]!=q ){
+ /* Character iIn was the close quote. */
+ iIn++;
+ break;
+ }else{
+ /* Character iIn and iIn+1 form an escaped quote character. Skip
** the input cursor past both and copy a single quote character
- ** to the output buffer. */
- iIn += 2;
- z[iOut++] = q;
- }
- }else{
- z[iOut++] = z[iIn++];
- }
- }
-
- z[iOut] = '\0';
- return iIn;
-}
-
-/*
-** Convert an SQL-style quoted string into a normal string by removing
-** the quote characters. The conversion is done in-place. If the
-** input does not begin with a quote character, then this routine
-** is a no-op.
-**
-** Examples:
-**
-** "abc" becomes abc
-** 'xyz' becomes xyz
-** [pqr] becomes pqr
-** `mno` becomes mno
-*/
-static void sqlite3Fts5Dequote(char *z){
- char quote; /* Quote character (if any ) */
-
- assert( 0==fts5_iswhitespace(z[0]) );
- quote = z[0];
- if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){
- fts5Dequote(z);
- }
-}
-
-
-struct Fts5Enum {
- const char *zName;
- int eVal;
-};
-typedef struct Fts5Enum Fts5Enum;
-
-static int fts5ConfigSetEnum(
+ ** to the output buffer. */
+ iIn += 2;
+ z[iOut++] = q;
+ }
+ }else{
+ z[iOut++] = z[iIn++];
+ }
+ }
+
+ z[iOut] = '\0';
+ return iIn;
+}
+
+/*
+** Convert an SQL-style quoted string into a normal string by removing
+** the quote characters. The conversion is done in-place. If the
+** input does not begin with a quote character, then this routine
+** is a no-op.
+**
+** Examples:
+**
+** "abc" becomes abc
+** 'xyz' becomes xyz
+** [pqr] becomes pqr
+** `mno` becomes mno
+*/
+static void sqlite3Fts5Dequote(char *z){
+ char quote; /* Quote character (if any ) */
+
+ assert( 0==fts5_iswhitespace(z[0]) );
+ quote = z[0];
+ if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){
+ fts5Dequote(z);
+ }
+}
+
+
+struct Fts5Enum {
+ const char *zName;
+ int eVal;
+};
+typedef struct Fts5Enum Fts5Enum;
+
+static int fts5ConfigSetEnum(
const Fts5Enum *aEnum,
const char *zEnum,
- int *peVal
-){
- int nEnum = (int)strlen(zEnum);
- int i;
- int iVal = -1;
-
- for(i=0; aEnum[i].zName; i++){
- if( sqlite3_strnicmp(aEnum[i].zName, zEnum, nEnum)==0 ){
- if( iVal>=0 ) return SQLITE_ERROR;
- iVal = aEnum[i].eVal;
- }
- }
-
- *peVal = iVal;
- return iVal<0 ? SQLITE_ERROR : SQLITE_OK;
-}
-
-/*
-** Parse a "special" CREATE VIRTUAL TABLE directive and update
-** configuration object pConfig as appropriate.
-**
-** If successful, object pConfig is updated and SQLITE_OK returned. If
-** an error occurs, an SQLite error code is returned and an error message
-** may be left in *pzErr. It is the responsibility of the caller to
-** eventually free any such error message using sqlite3_free().
-*/
-static int fts5ConfigParseSpecial(
- Fts5Global *pGlobal,
- Fts5Config *pConfig, /* Configuration object to update */
- const char *zCmd, /* Special command to parse */
- const char *zArg, /* Argument to parse */
- char **pzErr /* OUT: Error message */
-){
- int rc = SQLITE_OK;
- int nCmd = (int)strlen(zCmd);
- if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){
- const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES;
- const char *p;
- int bFirst = 1;
- if( pConfig->aPrefix==0 ){
- pConfig->aPrefix = sqlite3Fts5MallocZero(&rc, nByte);
- if( rc ) return rc;
- }
-
- p = zArg;
- while( 1 ){
- int nPre = 0;
-
- while( p[0]==' ' ) p++;
- if( bFirst==0 && p[0]==',' ){
- p++;
- while( p[0]==' ' ) p++;
- }else if( p[0]=='\0' ){
- break;
- }
- if( p[0]<'0' || p[0]>'9' ){
- *pzErr = sqlite3_mprintf("malformed prefix=... directive");
- rc = SQLITE_ERROR;
- break;
- }
-
- if( pConfig->nPrefix==FTS5_MAX_PREFIX_INDEXES ){
- *pzErr = sqlite3_mprintf(
- "too many prefix indexes (max %d)", FTS5_MAX_PREFIX_INDEXES
- );
- rc = SQLITE_ERROR;
- break;
- }
-
- while( p[0]>='0' && p[0]<='9' && nPre<1000 ){
- nPre = nPre*10 + (p[0] - '0');
- p++;
- }
-
- if( nPre<=0 || nPre>=1000 ){
- *pzErr = sqlite3_mprintf("prefix length out of range (max 999)");
- rc = SQLITE_ERROR;
- break;
- }
-
- pConfig->aPrefix[pConfig->nPrefix] = nPre;
- pConfig->nPrefix++;
- bFirst = 0;
- }
- assert( pConfig->nPrefix<=FTS5_MAX_PREFIX_INDEXES );
- return rc;
- }
-
- if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
- const char *p = (const char*)zArg;
+ int *peVal
+){
+ int nEnum = (int)strlen(zEnum);
+ int i;
+ int iVal = -1;
+
+ for(i=0; aEnum[i].zName; i++){
+ if( sqlite3_strnicmp(aEnum[i].zName, zEnum, nEnum)==0 ){
+ if( iVal>=0 ) return SQLITE_ERROR;
+ iVal = aEnum[i].eVal;
+ }
+ }
+
+ *peVal = iVal;
+ return iVal<0 ? SQLITE_ERROR : SQLITE_OK;
+}
+
+/*
+** Parse a "special" CREATE VIRTUAL TABLE directive and update
+** configuration object pConfig as appropriate.
+**
+** If successful, object pConfig is updated and SQLITE_OK returned. If
+** an error occurs, an SQLite error code is returned and an error message
+** may be left in *pzErr. It is the responsibility of the caller to
+** eventually free any such error message using sqlite3_free().
+*/
+static int fts5ConfigParseSpecial(
+ Fts5Global *pGlobal,
+ Fts5Config *pConfig, /* Configuration object to update */
+ const char *zCmd, /* Special command to parse */
+ const char *zArg, /* Argument to parse */
+ char **pzErr /* OUT: Error message */
+){
+ int rc = SQLITE_OK;
+ int nCmd = (int)strlen(zCmd);
+ if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){
+ const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES;
+ const char *p;
+ int bFirst = 1;
+ if( pConfig->aPrefix==0 ){
+ pConfig->aPrefix = sqlite3Fts5MallocZero(&rc, nByte);
+ if( rc ) return rc;
+ }
+
+ p = zArg;
+ while( 1 ){
+ int nPre = 0;
+
+ while( p[0]==' ' ) p++;
+ if( bFirst==0 && p[0]==',' ){
+ p++;
+ while( p[0]==' ' ) p++;
+ }else if( p[0]=='\0' ){
+ break;
+ }
+ if( p[0]<'0' || p[0]>'9' ){
+ *pzErr = sqlite3_mprintf("malformed prefix=... directive");
+ rc = SQLITE_ERROR;
+ break;
+ }
+
+ if( pConfig->nPrefix==FTS5_MAX_PREFIX_INDEXES ){
+ *pzErr = sqlite3_mprintf(
+ "too many prefix indexes (max %d)", FTS5_MAX_PREFIX_INDEXES
+ );
+ rc = SQLITE_ERROR;
+ break;
+ }
+
+ while( p[0]>='0' && p[0]<='9' && nPre<1000 ){
+ nPre = nPre*10 + (p[0] - '0');
+ p++;
+ }
+
+ if( nPre<=0 || nPre>=1000 ){
+ *pzErr = sqlite3_mprintf("prefix length out of range (max 999)");
+ rc = SQLITE_ERROR;
+ break;
+ }
+
+ pConfig->aPrefix[pConfig->nPrefix] = nPre;
+ pConfig->nPrefix++;
+ bFirst = 0;
+ }
+ assert( pConfig->nPrefix<=FTS5_MAX_PREFIX_INDEXES );
+ return rc;
+ }
+
+ if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
+ const char *p = (const char*)zArg;
sqlite3_int64 nArg = strlen(zArg) + 1;
- char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
- char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
- char *pSpace = pDel;
-
- if( azArg && pSpace ){
- if( pConfig->pTok ){
- *pzErr = sqlite3_mprintf("multiple tokenize=... directives");
- rc = SQLITE_ERROR;
- }else{
- for(nArg=0; p && *p; nArg++){
- const char *p2 = fts5ConfigSkipWhitespace(p);
- if( *p2=='\'' ){
- p = fts5ConfigSkipLiteral(p2);
- }else{
- p = fts5ConfigSkipBareword(p2);
- }
- if( p ){
- memcpy(pSpace, p2, p-p2);
- azArg[nArg] = pSpace;
- sqlite3Fts5Dequote(pSpace);
- pSpace += (p - p2) + 1;
- p = fts5ConfigSkipWhitespace(p);
- }
- }
- if( p==0 ){
- *pzErr = sqlite3_mprintf("parse error in tokenize directive");
- rc = SQLITE_ERROR;
- }else{
+ char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
+ char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
+ char *pSpace = pDel;
+
+ if( azArg && pSpace ){
+ if( pConfig->pTok ){
+ *pzErr = sqlite3_mprintf("multiple tokenize=... directives");
+ rc = SQLITE_ERROR;
+ }else{
+ for(nArg=0; p && *p; nArg++){
+ const char *p2 = fts5ConfigSkipWhitespace(p);
+ if( *p2=='\'' ){
+ p = fts5ConfigSkipLiteral(p2);
+ }else{
+ p = fts5ConfigSkipBareword(p2);
+ }
+ if( p ){
+ memcpy(pSpace, p2, p-p2);
+ azArg[nArg] = pSpace;
+ sqlite3Fts5Dequote(pSpace);
+ pSpace += (p - p2) + 1;
+ p = fts5ConfigSkipWhitespace(p);
+ }
+ }
+ if( p==0 ){
+ *pzErr = sqlite3_mprintf("parse error in tokenize directive");
+ rc = SQLITE_ERROR;
+ }else{
rc = sqlite3Fts5GetTokenizer(pGlobal,
(const char**)azArg, (int)nArg, pConfig,
- pzErr
- );
- }
- }
- }
-
- sqlite3_free(azArg);
- sqlite3_free(pDel);
- return rc;
- }
-
- if( sqlite3_strnicmp("content", zCmd, nCmd)==0 ){
- if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
- *pzErr = sqlite3_mprintf("multiple content=... directives");
- rc = SQLITE_ERROR;
- }else{
- if( zArg[0] ){
- pConfig->eContent = FTS5_CONTENT_EXTERNAL;
- pConfig->zContent = sqlite3Fts5Mprintf(&rc, "%Q.%Q", pConfig->zDb,zArg);
- }else{
- pConfig->eContent = FTS5_CONTENT_NONE;
- }
- }
- return rc;
- }
-
- if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){
- if( pConfig->zContentRowid ){
- *pzErr = sqlite3_mprintf("multiple content_rowid=... directives");
- rc = SQLITE_ERROR;
- }else{
- pConfig->zContentRowid = sqlite3Fts5Strndup(&rc, zArg, -1);
- }
- return rc;
- }
-
- if( sqlite3_strnicmp("columnsize", zCmd, nCmd)==0 ){
- if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
- *pzErr = sqlite3_mprintf("malformed columnsize=... directive");
- rc = SQLITE_ERROR;
- }else{
- pConfig->bColumnsize = (zArg[0]=='1');
- }
- return rc;
- }
-
- if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){
- const Fts5Enum aDetail[] = {
- { "none", FTS5_DETAIL_NONE },
- { "full", FTS5_DETAIL_FULL },
- { "columns", FTS5_DETAIL_COLUMNS },
- { 0, 0 }
- };
-
- if( (rc = fts5ConfigSetEnum(aDetail, zArg, &pConfig->eDetail)) ){
- *pzErr = sqlite3_mprintf("malformed detail=... directive");
- }
- return rc;
- }
-
- *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd);
- return SQLITE_ERROR;
-}
-
-/*
+ pzErr
+ );
+ }
+ }
+ }
+
+ sqlite3_free(azArg);
+ sqlite3_free(pDel);
+ return rc;
+ }
+
+ if( sqlite3_strnicmp("content", zCmd, nCmd)==0 ){
+ if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
+ *pzErr = sqlite3_mprintf("multiple content=... directives");
+ rc = SQLITE_ERROR;
+ }else{
+ if( zArg[0] ){
+ pConfig->eContent = FTS5_CONTENT_EXTERNAL;
+ pConfig->zContent = sqlite3Fts5Mprintf(&rc, "%Q.%Q", pConfig->zDb,zArg);
+ }else{
+ pConfig->eContent = FTS5_CONTENT_NONE;
+ }
+ }
+ return rc;
+ }
+
+ if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){
+ if( pConfig->zContentRowid ){
+ *pzErr = sqlite3_mprintf("multiple content_rowid=... directives");
+ rc = SQLITE_ERROR;
+ }else{
+ pConfig->zContentRowid = sqlite3Fts5Strndup(&rc, zArg, -1);
+ }
+ return rc;
+ }
+
+ if( sqlite3_strnicmp("columnsize", zCmd, nCmd)==0 ){
+ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
+ *pzErr = sqlite3_mprintf("malformed columnsize=... directive");
+ rc = SQLITE_ERROR;
+ }else{
+ pConfig->bColumnsize = (zArg[0]=='1');
+ }
+ return rc;
+ }
+
+ if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){
+ const Fts5Enum aDetail[] = {
+ { "none", FTS5_DETAIL_NONE },
+ { "full", FTS5_DETAIL_FULL },
+ { "columns", FTS5_DETAIL_COLUMNS },
+ { 0, 0 }
+ };
+
+ if( (rc = fts5ConfigSetEnum(aDetail, zArg, &pConfig->eDetail)) ){
+ *pzErr = sqlite3_mprintf("malformed detail=... directive");
+ }
+ return rc;
+ }
+
+ *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd);
+ return SQLITE_ERROR;
+}
+
+/*
** Allocate an instance of the default tokenizer ("simple") at
-** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error
-** code if an error occurs.
-*/
-static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){
- assert( pConfig->pTok==0 && pConfig->pTokApi==0 );
+** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error
+** code if an error occurs.
+*/
+static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){
+ assert( pConfig->pTok==0 && pConfig->pTokApi==0 );
return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0);
-}
-
-/*
-** Gobble up the first bareword or quoted word from the input buffer zIn.
-** Return a pointer to the character immediately following the last in
-** the gobbled word if successful, or a NULL pointer otherwise (failed
-** to find close-quote character).
-**
-** Before returning, set pzOut to point to a new buffer containing a
-** nul-terminated, dequoted copy of the gobbled word. If the word was
-** quoted, *pbQuoted is also set to 1 before returning.
-**
-** If *pRc is other than SQLITE_OK when this function is called, it is
-** a no-op (NULL is returned). Otherwise, if an OOM occurs within this
-** function, *pRc is set to SQLITE_NOMEM before returning. *pRc is *not*
-** set if a parse error (failed to find close quote) occurs.
-*/
-static const char *fts5ConfigGobbleWord(
- int *pRc, /* IN/OUT: Error code */
- const char *zIn, /* Buffer to gobble string/bareword from */
- char **pzOut, /* OUT: malloc'd buffer containing str/bw */
- int *pbQuoted /* OUT: Set to true if dequoting required */
-){
- const char *zRet = 0;
-
+}
+
+/*
+** Gobble up the first bareword or quoted word from the input buffer zIn.
+** Return a pointer to the character immediately following the last in
+** the gobbled word if successful, or a NULL pointer otherwise (failed
+** to find close-quote character).
+**
+** Before returning, set pzOut to point to a new buffer containing a
+** nul-terminated, dequoted copy of the gobbled word. If the word was
+** quoted, *pbQuoted is also set to 1 before returning.
+**
+** If *pRc is other than SQLITE_OK when this function is called, it is
+** a no-op (NULL is returned). Otherwise, if an OOM occurs within this
+** function, *pRc is set to SQLITE_NOMEM before returning. *pRc is *not*
+** set if a parse error (failed to find close quote) occurs.
+*/
+static const char *fts5ConfigGobbleWord(
+ int *pRc, /* IN/OUT: Error code */
+ const char *zIn, /* Buffer to gobble string/bareword from */
+ char **pzOut, /* OUT: malloc'd buffer containing str/bw */
+ int *pbQuoted /* OUT: Set to true if dequoting required */
+){
+ const char *zRet = 0;
+
sqlite3_int64 nIn = strlen(zIn);
char *zOut = sqlite3_malloc64(nIn+1);
-
- assert( *pRc==SQLITE_OK );
- *pbQuoted = 0;
- *pzOut = 0;
-
- if( zOut==0 ){
- *pRc = SQLITE_NOMEM;
- }else{
+
+ assert( *pRc==SQLITE_OK );
+ *pbQuoted = 0;
+ *pzOut = 0;
+
+ if( zOut==0 ){
+ *pRc = SQLITE_NOMEM;
+ }else{
memcpy(zOut, zIn, (size_t)(nIn+1));
- if( fts5_isopenquote(zOut[0]) ){
- int ii = fts5Dequote(zOut);
- zRet = &zIn[ii];
- *pbQuoted = 1;
- }else{
- zRet = fts5ConfigSkipBareword(zIn);
- if( zRet ){
- zOut[zRet-zIn] = '\0';
- }
- }
- }
-
- if( zRet==0 ){
- sqlite3_free(zOut);
- }else{
- *pzOut = zOut;
- }
-
- return zRet;
-}
-
-static int fts5ConfigParseColumn(
+ if( fts5_isopenquote(zOut[0]) ){
+ int ii = fts5Dequote(zOut);
+ zRet = &zIn[ii];
+ *pbQuoted = 1;
+ }else{
+ zRet = fts5ConfigSkipBareword(zIn);
+ if( zRet ){
+ zOut[zRet-zIn] = '\0';
+ }
+ }
+ }
+
+ if( zRet==0 ){
+ sqlite3_free(zOut);
+ }else{
+ *pzOut = zOut;
+ }
+
+ return zRet;
+}
+
+static int fts5ConfigParseColumn(
Fts5Config *p,
char *zCol,
char *zArg,
- char **pzErr
-){
- int rc = SQLITE_OK;
+ char **pzErr
+){
+ int rc = SQLITE_OK;
if( 0==sqlite3_stricmp(zCol, FTS5_RANK_NAME)
|| 0==sqlite3_stricmp(zCol, FTS5_ROWID_NAME)
- ){
- *pzErr = sqlite3_mprintf("reserved fts5 column name: %s", zCol);
- rc = SQLITE_ERROR;
- }else if( zArg ){
- if( 0==sqlite3_stricmp(zArg, "unindexed") ){
- p->abUnindexed[p->nCol] = 1;
- }else{
- *pzErr = sqlite3_mprintf("unrecognized column option: %s", zArg);
- rc = SQLITE_ERROR;
- }
- }
-
- p->azCol[p->nCol++] = zCol;
- return rc;
-}
-
-/*
-** Populate the Fts5Config.zContentExprlist string.
-*/
-static int fts5ConfigMakeExprlist(Fts5Config *p){
- int i;
- int rc = SQLITE_OK;
- Fts5Buffer buf = {0, 0, 0};
-
- sqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid);
- if( p->eContent!=FTS5_CONTENT_NONE ){
- for(i=0; i<p->nCol; i++){
- if( p->eContent==FTS5_CONTENT_EXTERNAL ){
- sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]);
- }else{
- sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i);
- }
- }
- }
-
- assert( p->zContentExprlist==0 );
- p->zContentExprlist = (char*)buf.p;
- return rc;
-}
-
-/*
-** Arguments nArg/azArg contain the string arguments passed to the xCreate
+ ){
+ *pzErr = sqlite3_mprintf("reserved fts5 column name: %s", zCol);
+ rc = SQLITE_ERROR;
+ }else if( zArg ){
+ if( 0==sqlite3_stricmp(zArg, "unindexed") ){
+ p->abUnindexed[p->nCol] = 1;
+ }else{
+ *pzErr = sqlite3_mprintf("unrecognized column option: %s", zArg);
+ rc = SQLITE_ERROR;
+ }
+ }
+
+ p->azCol[p->nCol++] = zCol;
+ return rc;
+}
+
+/*
+** Populate the Fts5Config.zContentExprlist string.
+*/
+static int fts5ConfigMakeExprlist(Fts5Config *p){
+ int i;
+ int rc = SQLITE_OK;
+ Fts5Buffer buf = {0, 0, 0};
+
+ sqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid);
+ if( p->eContent!=FTS5_CONTENT_NONE ){
+ for(i=0; i<p->nCol; i++){
+ if( p->eContent==FTS5_CONTENT_EXTERNAL ){
+ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]);
+ }else{
+ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i);
+ }
+ }
+ }
+
+ assert( p->zContentExprlist==0 );
+ p->zContentExprlist = (char*)buf.p;
+ return rc;
+}
+
+/*
+** Arguments nArg/azArg contain the string arguments passed to the xCreate
** or xConnect method of the virtual table. This function attempts to
-** allocate an instance of Fts5Config containing the results of parsing
-** those arguments.
-**
-** If successful, SQLITE_OK is returned and *ppOut is set to point to the
+** allocate an instance of Fts5Config containing the results of parsing
+** those arguments.
+**
+** If successful, SQLITE_OK is returned and *ppOut is set to point to the
** new Fts5Config object. If an error occurs, an SQLite error code is
-** returned, *ppOut is set to NULL and an error message may be left in
+** returned, *ppOut is set to NULL and an error message may be left in
** *pzErr. It is the responsibility of the caller to eventually free any
-** such error message using sqlite3_free().
-*/
-static int sqlite3Fts5ConfigParse(
- Fts5Global *pGlobal,
- sqlite3 *db,
- int nArg, /* Number of arguments */
- const char **azArg, /* Array of nArg CREATE VIRTUAL TABLE args */
- Fts5Config **ppOut, /* OUT: Results of parse */
- char **pzErr /* OUT: Error message */
-){
- int rc = SQLITE_OK; /* Return code */
- Fts5Config *pRet; /* New object to return */
- int i;
+** such error message using sqlite3_free().
+*/
+static int sqlite3Fts5ConfigParse(
+ Fts5Global *pGlobal,
+ sqlite3 *db,
+ int nArg, /* Number of arguments */
+ const char **azArg, /* Array of nArg CREATE VIRTUAL TABLE args */
+ Fts5Config **ppOut, /* OUT: Results of parse */
+ char **pzErr /* OUT: Error message */
+){
+ int rc = SQLITE_OK; /* Return code */
+ Fts5Config *pRet; /* New object to return */
+ int i;
sqlite3_int64 nByte;
-
- *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
- if( pRet==0 ) return SQLITE_NOMEM;
- memset(pRet, 0, sizeof(Fts5Config));
- pRet->db = db;
- pRet->iCookie = -1;
-
- nByte = nArg * (sizeof(char*) + sizeof(u8));
- pRet->azCol = (char**)sqlite3Fts5MallocZero(&rc, nByte);
+
+ *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
+ if( pRet==0 ) return SQLITE_NOMEM;
+ memset(pRet, 0, sizeof(Fts5Config));
+ pRet->db = db;
+ pRet->iCookie = -1;
+
+ nByte = nArg * (sizeof(char*) + sizeof(u8));
+ pRet->azCol = (char**)sqlite3Fts5MallocZero(&rc, nByte);
pRet->abUnindexed = pRet->azCol ? (u8*)&pRet->azCol[nArg] : 0;
- pRet->zDb = sqlite3Fts5Strndup(&rc, azArg[1], -1);
- pRet->zName = sqlite3Fts5Strndup(&rc, azArg[2], -1);
- pRet->bColumnsize = 1;
- pRet->eDetail = FTS5_DETAIL_FULL;
-#ifdef SQLITE_DEBUG
- pRet->bPrefixIndex = 1;
-#endif
- if( rc==SQLITE_OK && sqlite3_stricmp(pRet->zName, FTS5_RANK_NAME)==0 ){
- *pzErr = sqlite3_mprintf("reserved fts5 table name: %s", pRet->zName);
- rc = SQLITE_ERROR;
- }
-
- for(i=3; rc==SQLITE_OK && i<nArg; i++){
- const char *zOrig = azArg[i];
- const char *z;
- char *zOne = 0;
- char *zTwo = 0;
- int bOption = 0;
- int bMustBeCol = 0;
-
- z = fts5ConfigGobbleWord(&rc, zOrig, &zOne, &bMustBeCol);
- z = fts5ConfigSkipWhitespace(z);
- if( z && *z=='=' ){
- bOption = 1;
+ pRet->zDb = sqlite3Fts5Strndup(&rc, azArg[1], -1);
+ pRet->zName = sqlite3Fts5Strndup(&rc, azArg[2], -1);
+ pRet->bColumnsize = 1;
+ pRet->eDetail = FTS5_DETAIL_FULL;
+#ifdef SQLITE_DEBUG
+ pRet->bPrefixIndex = 1;
+#endif
+ if( rc==SQLITE_OK && sqlite3_stricmp(pRet->zName, FTS5_RANK_NAME)==0 ){
+ *pzErr = sqlite3_mprintf("reserved fts5 table name: %s", pRet->zName);
+ rc = SQLITE_ERROR;
+ }
+
+ for(i=3; rc==SQLITE_OK && i<nArg; i++){
+ const char *zOrig = azArg[i];
+ const char *z;
+ char *zOne = 0;
+ char *zTwo = 0;
+ int bOption = 0;
+ int bMustBeCol = 0;
+
+ z = fts5ConfigGobbleWord(&rc, zOrig, &zOne, &bMustBeCol);
+ z = fts5ConfigSkipWhitespace(z);
+ if( z && *z=='=' ){
+ bOption = 1;
assert( zOne!=0 );
- z++;
- if( bMustBeCol ) z = 0;
- }
- z = fts5ConfigSkipWhitespace(z);
- if( z && z[0] ){
- int bDummy;
- z = fts5ConfigGobbleWord(&rc, z, &zTwo, &bDummy);
- if( z && z[0] ) z = 0;
- }
-
- if( rc==SQLITE_OK ){
- if( z==0 ){
- *pzErr = sqlite3_mprintf("parse error in \"%s\"", zOrig);
- rc = SQLITE_ERROR;
- }else{
- if( bOption ){
+ z++;
+ if( bMustBeCol ) z = 0;
+ }
+ z = fts5ConfigSkipWhitespace(z);
+ if( z && z[0] ){
+ int bDummy;
+ z = fts5ConfigGobbleWord(&rc, z, &zTwo, &bDummy);
+ if( z && z[0] ) z = 0;
+ }
+
+ if( rc==SQLITE_OK ){
+ if( z==0 ){
+ *pzErr = sqlite3_mprintf("parse error in \"%s\"", zOrig);
+ rc = SQLITE_ERROR;
+ }else{
+ if( bOption ){
rc = fts5ConfigParseSpecial(pGlobal, pRet,
ALWAYS(zOne)?zOne:"",
zTwo?zTwo:"",
pzErr
);
- }else{
- rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr);
- zOne = 0;
- }
- }
- }
-
- sqlite3_free(zOne);
- sqlite3_free(zTwo);
- }
-
- /* If a tokenizer= option was successfully parsed, the tokenizer has
- ** already been allocated. Otherwise, allocate an instance of the default
- ** tokenizer (unicode61) now. */
- if( rc==SQLITE_OK && pRet->pTok==0 ){
- rc = fts5ConfigDefaultTokenizer(pGlobal, pRet);
- }
-
- /* If no zContent option was specified, fill in the default values. */
- if( rc==SQLITE_OK && pRet->zContent==0 ){
- const char *zTail = 0;
+ }else{
+ rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr);
+ zOne = 0;
+ }
+ }
+ }
+
+ sqlite3_free(zOne);
+ sqlite3_free(zTwo);
+ }
+
+ /* If a tokenizer= option was successfully parsed, the tokenizer has
+ ** already been allocated. Otherwise, allocate an instance of the default
+ ** tokenizer (unicode61) now. */
+ if( rc==SQLITE_OK && pRet->pTok==0 ){
+ rc = fts5ConfigDefaultTokenizer(pGlobal, pRet);
+ }
+
+ /* If no zContent option was specified, fill in the default values. */
+ if( rc==SQLITE_OK && pRet->zContent==0 ){
+ const char *zTail = 0;
assert( pRet->eContent==FTS5_CONTENT_NORMAL
|| pRet->eContent==FTS5_CONTENT_NONE
- );
- if( pRet->eContent==FTS5_CONTENT_NORMAL ){
- zTail = "content";
- }else if( pRet->bColumnsize ){
- zTail = "docsize";
- }
-
- if( zTail ){
- pRet->zContent = sqlite3Fts5Mprintf(
- &rc, "%Q.'%q_%s'", pRet->zDb, pRet->zName, zTail
- );
- }
- }
-
- if( rc==SQLITE_OK && pRet->zContentRowid==0 ){
- pRet->zContentRowid = sqlite3Fts5Strndup(&rc, "rowid", -1);
- }
-
- /* Formulate the zContentExprlist text */
- if( rc==SQLITE_OK ){
- rc = fts5ConfigMakeExprlist(pRet);
- }
-
- if( rc!=SQLITE_OK ){
- sqlite3Fts5ConfigFree(pRet);
- *ppOut = 0;
- }
- return rc;
-}
-
-/*
-** Free the configuration object passed as the only argument.
-*/
-static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){
- if( pConfig ){
- int i;
- if( pConfig->pTok ){
- pConfig->pTokApi->xDelete(pConfig->pTok);
- }
- sqlite3_free(pConfig->zDb);
- sqlite3_free(pConfig->zName);
- for(i=0; i<pConfig->nCol; i++){
- sqlite3_free(pConfig->azCol[i]);
- }
- sqlite3_free(pConfig->azCol);
- sqlite3_free(pConfig->aPrefix);
- sqlite3_free(pConfig->zRank);
- sqlite3_free(pConfig->zRankArgs);
- sqlite3_free(pConfig->zContent);
- sqlite3_free(pConfig->zContentRowid);
- sqlite3_free(pConfig->zContentExprlist);
- sqlite3_free(pConfig);
- }
-}
-
-/*
-** Call sqlite3_declare_vtab() based on the contents of the configuration
-** object passed as the only argument. Return SQLITE_OK if successful, or
-** an SQLite error code if an error occurs.
-*/
-static int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){
- int i;
- int rc = SQLITE_OK;
- char *zSql;
-
- zSql = sqlite3Fts5Mprintf(&rc, "CREATE TABLE x(");
- for(i=0; zSql && i<pConfig->nCol; i++){
- const char *zSep = (i==0?"":", ");
- zSql = sqlite3Fts5Mprintf(&rc, "%z%s%Q", zSql, zSep, pConfig->azCol[i]);
- }
+ );
+ if( pRet->eContent==FTS5_CONTENT_NORMAL ){
+ zTail = "content";
+ }else if( pRet->bColumnsize ){
+ zTail = "docsize";
+ }
+
+ if( zTail ){
+ pRet->zContent = sqlite3Fts5Mprintf(
+ &rc, "%Q.'%q_%s'", pRet->zDb, pRet->zName, zTail
+ );
+ }
+ }
+
+ if( rc==SQLITE_OK && pRet->zContentRowid==0 ){
+ pRet->zContentRowid = sqlite3Fts5Strndup(&rc, "rowid", -1);
+ }
+
+ /* Formulate the zContentExprlist text */
+ if( rc==SQLITE_OK ){
+ rc = fts5ConfigMakeExprlist(pRet);
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3Fts5ConfigFree(pRet);
+ *ppOut = 0;
+ }
+ return rc;
+}
+
+/*
+** Free the configuration object passed as the only argument.
+*/
+static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){
+ if( pConfig ){
+ int i;
+ if( pConfig->pTok ){
+ pConfig->pTokApi->xDelete(pConfig->pTok);
+ }
+ sqlite3_free(pConfig->zDb);
+ sqlite3_free(pConfig->zName);
+ for(i=0; i<pConfig->nCol; i++){
+ sqlite3_free(pConfig->azCol[i]);
+ }
+ sqlite3_free(pConfig->azCol);
+ sqlite3_free(pConfig->aPrefix);
+ sqlite3_free(pConfig->zRank);
+ sqlite3_free(pConfig->zRankArgs);
+ sqlite3_free(pConfig->zContent);
+ sqlite3_free(pConfig->zContentRowid);
+ sqlite3_free(pConfig->zContentExprlist);
+ sqlite3_free(pConfig);
+ }
+}
+
+/*
+** Call sqlite3_declare_vtab() based on the contents of the configuration
+** object passed as the only argument. Return SQLITE_OK if successful, or
+** an SQLite error code if an error occurs.
+*/
+static int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){
+ int i;
+ int rc = SQLITE_OK;
+ char *zSql;
+
+ zSql = sqlite3Fts5Mprintf(&rc, "CREATE TABLE x(");
+ for(i=0; zSql && i<pConfig->nCol; i++){
+ const char *zSep = (i==0?"":", ");
+ zSql = sqlite3Fts5Mprintf(&rc, "%z%s%Q", zSql, zSep, pConfig->azCol[i]);
+ }
zSql = sqlite3Fts5Mprintf(&rc, "%z, %Q HIDDEN, %s HIDDEN)",
- zSql, pConfig->zName, FTS5_RANK_NAME
- );
-
- assert( zSql || rc==SQLITE_NOMEM );
- if( zSql ){
- rc = sqlite3_declare_vtab(pConfig->db, zSql);
- sqlite3_free(zSql);
- }
-
- return rc;
-}
-
-/*
-** Tokenize the text passed via the second and third arguments.
-**
-** The callback is invoked once for each token in the input text. The
-** arguments passed to it are, in order:
-**
-** void *pCtx // Copy of 4th argument to sqlite3Fts5Tokenize()
-** const char *pToken // Pointer to buffer containing token
-** int nToken // Size of token in bytes
-** int iStart // Byte offset of start of token within input text
-** int iEnd // Byte offset of end of token within input text
-** int iPos // Position of token in input (first token is 0)
-**
-** If the callback returns a non-zero value the tokenization is abandoned
+ zSql, pConfig->zName, FTS5_RANK_NAME
+ );
+
+ assert( zSql || rc==SQLITE_NOMEM );
+ if( zSql ){
+ rc = sqlite3_declare_vtab(pConfig->db, zSql);
+ sqlite3_free(zSql);
+ }
+
+ return rc;
+}
+
+/*
+** Tokenize the text passed via the second and third arguments.
+**
+** The callback is invoked once for each token in the input text. The
+** arguments passed to it are, in order:
+**
+** void *pCtx // Copy of 4th argument to sqlite3Fts5Tokenize()
+** const char *pToken // Pointer to buffer containing token
+** int nToken // Size of token in bytes
+** int iStart // Byte offset of start of token within input text
+** int iEnd // Byte offset of end of token within input text
+** int iPos // Position of token in input (first token is 0)
+**
+** If the callback returns a non-zero value the tokenization is abandoned
** and no further callbacks are issued.
-**
-** This function returns SQLITE_OK if successful or an SQLite error code
-** if an error occurs. If the tokenization was abandoned early because
-** the callback returned SQLITE_DONE, this is not an error and this function
-** still returns SQLITE_OK. Or, if the tokenization was abandoned early
-** because the callback returned another non-zero value, it is assumed
-** to be an SQLite error code and returned to the caller.
-*/
-static int sqlite3Fts5Tokenize(
- Fts5Config *pConfig, /* FTS5 Configuration object */
- int flags, /* FTS5_TOKENIZE_* flags */
- const char *pText, int nText, /* Text to tokenize */
- void *pCtx, /* Context passed to xToken() */
- int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
-){
- if( pText==0 ) return SQLITE_OK;
- return pConfig->pTokApi->xTokenize(
- pConfig->pTok, pCtx, flags, pText, nText, xToken
- );
-}
-
-/*
-** Argument pIn points to the first character in what is expected to be
-** a comma-separated list of SQL literals followed by a ')' character.
-** If it actually is this, return a pointer to the ')'. Otherwise, return
-** NULL to indicate a parse error.
-*/
-static const char *fts5ConfigSkipArgs(const char *pIn){
- const char *p = pIn;
-
- while( 1 ){
- p = fts5ConfigSkipWhitespace(p);
- p = fts5ConfigSkipLiteral(p);
- p = fts5ConfigSkipWhitespace(p);
- if( p==0 || *p==')' ) break;
- if( *p!=',' ){
- p = 0;
- break;
- }
- p++;
- }
-
- return p;
-}
-
-/*
+**
+** This function returns SQLITE_OK if successful or an SQLite error code
+** if an error occurs. If the tokenization was abandoned early because
+** the callback returned SQLITE_DONE, this is not an error and this function
+** still returns SQLITE_OK. Or, if the tokenization was abandoned early
+** because the callback returned another non-zero value, it is assumed
+** to be an SQLite error code and returned to the caller.
+*/
+static int sqlite3Fts5Tokenize(
+ Fts5Config *pConfig, /* FTS5 Configuration object */
+ int flags, /* FTS5_TOKENIZE_* flags */
+ const char *pText, int nText, /* Text to tokenize */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+){
+ if( pText==0 ) return SQLITE_OK;
+ return pConfig->pTokApi->xTokenize(
+ pConfig->pTok, pCtx, flags, pText, nText, xToken
+ );
+}
+
+/*
+** Argument pIn points to the first character in what is expected to be
+** a comma-separated list of SQL literals followed by a ')' character.
+** If it actually is this, return a pointer to the ')'. Otherwise, return
+** NULL to indicate a parse error.
+*/
+static const char *fts5ConfigSkipArgs(const char *pIn){
+ const char *p = pIn;
+
+ while( 1 ){
+ p = fts5ConfigSkipWhitespace(p);
+ p = fts5ConfigSkipLiteral(p);
+ p = fts5ConfigSkipWhitespace(p);
+ if( p==0 || *p==')' ) break;
+ if( *p!=',' ){
+ p = 0;
+ break;
+ }
+ p++;
+ }
+
+ return p;
+}
+
+/*
** Parameter zIn contains a rank() function specification. The format of
-** this is:
-**
-** + Bareword (function name)
-** + Open parenthesis - "("
-** + Zero or more SQL literals in a comma separated list
-** + Close parenthesis - ")"
-*/
-static int sqlite3Fts5ConfigParseRank(
- const char *zIn, /* Input string */
- char **pzRank, /* OUT: Rank function name */
- char **pzRankArgs /* OUT: Rank function arguments */
-){
- const char *p = zIn;
- const char *pRank;
- char *zRank = 0;
- char *zRankArgs = 0;
- int rc = SQLITE_OK;
-
- *pzRank = 0;
- *pzRankArgs = 0;
-
- if( p==0 ){
- rc = SQLITE_ERROR;
- }else{
- p = fts5ConfigSkipWhitespace(p);
- pRank = p;
- p = fts5ConfigSkipBareword(p);
-
- if( p ){
- zRank = sqlite3Fts5MallocZero(&rc, 1 + p - pRank);
- if( zRank ) memcpy(zRank, pRank, p-pRank);
- }else{
- rc = SQLITE_ERROR;
- }
-
- if( rc==SQLITE_OK ){
- p = fts5ConfigSkipWhitespace(p);
- if( *p!='(' ) rc = SQLITE_ERROR;
- p++;
- }
- if( rc==SQLITE_OK ){
+** this is:
+**
+** + Bareword (function name)
+** + Open parenthesis - "("
+** + Zero or more SQL literals in a comma separated list
+** + Close parenthesis - ")"
+*/
+static int sqlite3Fts5ConfigParseRank(
+ const char *zIn, /* Input string */
+ char **pzRank, /* OUT: Rank function name */
+ char **pzRankArgs /* OUT: Rank function arguments */
+){
+ const char *p = zIn;
+ const char *pRank;
+ char *zRank = 0;
+ char *zRankArgs = 0;
+ int rc = SQLITE_OK;
+
+ *pzRank = 0;
+ *pzRankArgs = 0;
+
+ if( p==0 ){
+ rc = SQLITE_ERROR;
+ }else{
+ p = fts5ConfigSkipWhitespace(p);
+ pRank = p;
+ p = fts5ConfigSkipBareword(p);
+
+ if( p ){
+ zRank = sqlite3Fts5MallocZero(&rc, 1 + p - pRank);
+ if( zRank ) memcpy(zRank, pRank, p-pRank);
+ }else{
+ rc = SQLITE_ERROR;
+ }
+
+ if( rc==SQLITE_OK ){
+ p = fts5ConfigSkipWhitespace(p);
+ if( *p!='(' ) rc = SQLITE_ERROR;
+ p++;
+ }
+ if( rc==SQLITE_OK ){
const char *pArgs;
- p = fts5ConfigSkipWhitespace(p);
- pArgs = p;
- if( *p!=')' ){
- p = fts5ConfigSkipArgs(p);
- if( p==0 ){
- rc = SQLITE_ERROR;
- }else{
- zRankArgs = sqlite3Fts5MallocZero(&rc, 1 + p - pArgs);
- if( zRankArgs ) memcpy(zRankArgs, pArgs, p-pArgs);
- }
- }
- }
- }
-
- if( rc!=SQLITE_OK ){
- sqlite3_free(zRank);
- assert( zRankArgs==0 );
- }else{
- *pzRank = zRank;
- *pzRankArgs = zRankArgs;
- }
- return rc;
-}
-
-static int sqlite3Fts5ConfigSetValue(
+ p = fts5ConfigSkipWhitespace(p);
+ pArgs = p;
+ if( *p!=')' ){
+ p = fts5ConfigSkipArgs(p);
+ if( p==0 ){
+ rc = SQLITE_ERROR;
+ }else{
+ zRankArgs = sqlite3Fts5MallocZero(&rc, 1 + p - pArgs);
+ if( zRankArgs ) memcpy(zRankArgs, pArgs, p-pArgs);
+ }
+ }
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(zRank);
+ assert( zRankArgs==0 );
+ }else{
+ *pzRank = zRank;
+ *pzRankArgs = zRankArgs;
+ }
+ return rc;
+}
+
+static int sqlite3Fts5ConfigSetValue(
Fts5Config *pConfig,
const char *zKey,
- sqlite3_value *pVal,
- int *pbBadkey
-){
- int rc = SQLITE_OK;
-
- if( 0==sqlite3_stricmp(zKey, "pgsz") ){
- int pgsz = 0;
- if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
- pgsz = sqlite3_value_int(pVal);
- }
+ sqlite3_value *pVal,
+ int *pbBadkey
+){
+ int rc = SQLITE_OK;
+
+ if( 0==sqlite3_stricmp(zKey, "pgsz") ){
+ int pgsz = 0;
+ if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
+ pgsz = sqlite3_value_int(pVal);
+ }
if( pgsz<32 || pgsz>FTS5_MAX_PAGE_SIZE ){
- *pbBadkey = 1;
- }else{
- pConfig->pgsz = pgsz;
- }
- }
-
- else if( 0==sqlite3_stricmp(zKey, "hashsize") ){
- int nHashSize = -1;
- if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
- nHashSize = sqlite3_value_int(pVal);
- }
- if( nHashSize<=0 ){
- *pbBadkey = 1;
- }else{
- pConfig->nHashSize = nHashSize;
- }
- }
-
- else if( 0==sqlite3_stricmp(zKey, "automerge") ){
- int nAutomerge = -1;
- if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
- nAutomerge = sqlite3_value_int(pVal);
- }
- if( nAutomerge<0 || nAutomerge>64 ){
- *pbBadkey = 1;
- }else{
- if( nAutomerge==1 ) nAutomerge = FTS5_DEFAULT_AUTOMERGE;
- pConfig->nAutomerge = nAutomerge;
- }
- }
-
- else if( 0==sqlite3_stricmp(zKey, "usermerge") ){
- int nUsermerge = -1;
- if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
- nUsermerge = sqlite3_value_int(pVal);
- }
- if( nUsermerge<2 || nUsermerge>16 ){
- *pbBadkey = 1;
- }else{
- pConfig->nUsermerge = nUsermerge;
- }
- }
-
- else if( 0==sqlite3_stricmp(zKey, "crisismerge") ){
- int nCrisisMerge = -1;
- if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
- nCrisisMerge = sqlite3_value_int(pVal);
- }
- if( nCrisisMerge<0 ){
- *pbBadkey = 1;
- }else{
- if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
+ *pbBadkey = 1;
+ }else{
+ pConfig->pgsz = pgsz;
+ }
+ }
+
+ else if( 0==sqlite3_stricmp(zKey, "hashsize") ){
+ int nHashSize = -1;
+ if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
+ nHashSize = sqlite3_value_int(pVal);
+ }
+ if( nHashSize<=0 ){
+ *pbBadkey = 1;
+ }else{
+ pConfig->nHashSize = nHashSize;
+ }
+ }
+
+ else if( 0==sqlite3_stricmp(zKey, "automerge") ){
+ int nAutomerge = -1;
+ if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
+ nAutomerge = sqlite3_value_int(pVal);
+ }
+ if( nAutomerge<0 || nAutomerge>64 ){
+ *pbBadkey = 1;
+ }else{
+ if( nAutomerge==1 ) nAutomerge = FTS5_DEFAULT_AUTOMERGE;
+ pConfig->nAutomerge = nAutomerge;
+ }
+ }
+
+ else if( 0==sqlite3_stricmp(zKey, "usermerge") ){
+ int nUsermerge = -1;
+ if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
+ nUsermerge = sqlite3_value_int(pVal);
+ }
+ if( nUsermerge<2 || nUsermerge>16 ){
+ *pbBadkey = 1;
+ }else{
+ pConfig->nUsermerge = nUsermerge;
+ }
+ }
+
+ else if( 0==sqlite3_stricmp(zKey, "crisismerge") ){
+ int nCrisisMerge = -1;
+ if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
+ nCrisisMerge = sqlite3_value_int(pVal);
+ }
+ if( nCrisisMerge<0 ){
+ *pbBadkey = 1;
+ }else{
+ if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
if( nCrisisMerge>=FTS5_MAX_SEGMENT ) nCrisisMerge = FTS5_MAX_SEGMENT-1;
- pConfig->nCrisisMerge = nCrisisMerge;
- }
- }
-
- else if( 0==sqlite3_stricmp(zKey, "rank") ){
- const char *zIn = (const char*)sqlite3_value_text(pVal);
- char *zRank;
- char *zRankArgs;
- rc = sqlite3Fts5ConfigParseRank(zIn, &zRank, &zRankArgs);
- if( rc==SQLITE_OK ){
- sqlite3_free(pConfig->zRank);
- sqlite3_free(pConfig->zRankArgs);
- pConfig->zRank = zRank;
- pConfig->zRankArgs = zRankArgs;
- }else if( rc==SQLITE_ERROR ){
- rc = SQLITE_OK;
- *pbBadkey = 1;
- }
- }else{
- *pbBadkey = 1;
- }
- return rc;
-}
-
-/*
-** Load the contents of the %_config table into memory.
-*/
-static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
- const char *zSelect = "SELECT k, v FROM %Q.'%q_config'";
- char *zSql;
- sqlite3_stmt *p = 0;
- int rc = SQLITE_OK;
- int iVersion = 0;
-
- /* Set default values */
- pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
- pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
- pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE;
- pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
- pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
-
- zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName);
- if( zSql ){
- rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &p, 0);
- sqlite3_free(zSql);
- }
-
- assert( rc==SQLITE_OK || p==0 );
- if( rc==SQLITE_OK ){
- while( SQLITE_ROW==sqlite3_step(p) ){
- const char *zK = (const char*)sqlite3_column_text(p, 0);
- sqlite3_value *pVal = sqlite3_column_value(p, 1);
- if( 0==sqlite3_stricmp(zK, "version") ){
- iVersion = sqlite3_value_int(pVal);
- }else{
- int bDummy = 0;
- sqlite3Fts5ConfigSetValue(pConfig, zK, pVal, &bDummy);
- }
- }
- rc = sqlite3_finalize(p);
- }
-
- if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION ){
- rc = SQLITE_ERROR;
- if( pConfig->pzErrmsg ){
- assert( 0==*pConfig->pzErrmsg );
- *pConfig->pzErrmsg = sqlite3_mprintf(
- "invalid fts5 file format (found %d, expected %d) - run 'rebuild'",
- iVersion, FTS5_CURRENT_VERSION
- );
- }
- }
-
- if( rc==SQLITE_OK ){
- pConfig->iCookie = iCookie;
- }
- return rc;
-}
-
-/*
-** 2014 May 31
-**
-** 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.
-**
-******************************************************************************
-**
-*/
-
-
-
-/* #include "fts5Int.h" */
-/* #include "fts5parse.h" */
-
-/*
-** All token types in the generated fts5parse.h file are greater than 0.
-*/
-#define FTS5_EOF 0
-
-#define FTS5_LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
-
-typedef struct Fts5ExprTerm Fts5ExprTerm;
-
-/*
-** Functions generated by lemon from fts5parse.y.
-*/
-static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(u64));
-static void sqlite3Fts5ParserFree(void*, void (*freeProc)(void*));
-static void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
-#ifndef NDEBUG
-/* #include <stdio.h> */
-static void sqlite3Fts5ParserTrace(FILE*, char*);
-#endif
+ pConfig->nCrisisMerge = nCrisisMerge;
+ }
+ }
+
+ else if( 0==sqlite3_stricmp(zKey, "rank") ){
+ const char *zIn = (const char*)sqlite3_value_text(pVal);
+ char *zRank;
+ char *zRankArgs;
+ rc = sqlite3Fts5ConfigParseRank(zIn, &zRank, &zRankArgs);
+ if( rc==SQLITE_OK ){
+ sqlite3_free(pConfig->zRank);
+ sqlite3_free(pConfig->zRankArgs);
+ pConfig->zRank = zRank;
+ pConfig->zRankArgs = zRankArgs;
+ }else if( rc==SQLITE_ERROR ){
+ rc = SQLITE_OK;
+ *pbBadkey = 1;
+ }
+ }else{
+ *pbBadkey = 1;
+ }
+ return rc;
+}
+
+/*
+** Load the contents of the %_config table into memory.
+*/
+static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
+ const char *zSelect = "SELECT k, v FROM %Q.'%q_config'";
+ char *zSql;
+ sqlite3_stmt *p = 0;
+ int rc = SQLITE_OK;
+ int iVersion = 0;
+
+ /* Set default values */
+ pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
+ pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
+ pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE;
+ pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
+ pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
+
+ zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName);
+ if( zSql ){
+ rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &p, 0);
+ sqlite3_free(zSql);
+ }
+
+ assert( rc==SQLITE_OK || p==0 );
+ if( rc==SQLITE_OK ){
+ while( SQLITE_ROW==sqlite3_step(p) ){
+ const char *zK = (const char*)sqlite3_column_text(p, 0);
+ sqlite3_value *pVal = sqlite3_column_value(p, 1);
+ if( 0==sqlite3_stricmp(zK, "version") ){
+ iVersion = sqlite3_value_int(pVal);
+ }else{
+ int bDummy = 0;
+ sqlite3Fts5ConfigSetValue(pConfig, zK, pVal, &bDummy);
+ }
+ }
+ rc = sqlite3_finalize(p);
+ }
+
+ if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION ){
+ rc = SQLITE_ERROR;
+ if( pConfig->pzErrmsg ){
+ assert( 0==*pConfig->pzErrmsg );
+ *pConfig->pzErrmsg = sqlite3_mprintf(
+ "invalid fts5 file format (found %d, expected %d) - run 'rebuild'",
+ iVersion, FTS5_CURRENT_VERSION
+ );
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ pConfig->iCookie = iCookie;
+ }
+ return rc;
+}
+
+/*
+** 2014 May 31
+**
+** 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.
+**
+******************************************************************************
+**
+*/
+
+
+
+/* #include "fts5Int.h" */
+/* #include "fts5parse.h" */
+
+/*
+** All token types in the generated fts5parse.h file are greater than 0.
+*/
+#define FTS5_EOF 0
+
+#define FTS5_LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
+
+typedef struct Fts5ExprTerm Fts5ExprTerm;
+
+/*
+** Functions generated by lemon from fts5parse.y.
+*/
+static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(u64));
+static void sqlite3Fts5ParserFree(void*, void (*freeProc)(void*));
+static void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
+#ifndef NDEBUG
+/* #include <stdio.h> */
+static void sqlite3Fts5ParserTrace(FILE*, char*);
+#endif
static int sqlite3Fts5ParserFallback(int);
-
-
-struct Fts5Expr {
- Fts5Index *pIndex;
- Fts5Config *pConfig;
- Fts5ExprNode *pRoot;
- int bDesc; /* Iterate in descending rowid order */
- int nPhrase; /* Number of phrases in expression */
- Fts5ExprPhrase **apExprPhrase; /* Pointers to phrase objects */
-};
-
-/*
-** eType:
-** Expression node type. Always one of:
-**
-** FTS5_AND (nChild, apChild valid)
-** FTS5_OR (nChild, apChild valid)
-** FTS5_NOT (nChild, apChild valid)
-** FTS5_STRING (pNear valid)
-** FTS5_TERM (pNear valid)
-*/
-struct Fts5ExprNode {
- int eType; /* Node type */
- int bEof; /* True at EOF */
- int bNomatch; /* True if entry is not a match */
-
- /* Next method for this node. */
- int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64);
-
- i64 iRowid; /* Current rowid */
- Fts5ExprNearset *pNear; /* For FTS5_STRING - cluster of phrases */
-
+
+
+struct Fts5Expr {
+ Fts5Index *pIndex;
+ Fts5Config *pConfig;
+ Fts5ExprNode *pRoot;
+ int bDesc; /* Iterate in descending rowid order */
+ int nPhrase; /* Number of phrases in expression */
+ Fts5ExprPhrase **apExprPhrase; /* Pointers to phrase objects */
+};
+
+/*
+** eType:
+** Expression node type. Always one of:
+**
+** FTS5_AND (nChild, apChild valid)
+** FTS5_OR (nChild, apChild valid)
+** FTS5_NOT (nChild, apChild valid)
+** FTS5_STRING (pNear valid)
+** FTS5_TERM (pNear valid)
+*/
+struct Fts5ExprNode {
+ int eType; /* Node type */
+ int bEof; /* True at EOF */
+ int bNomatch; /* True if entry is not a match */
+
+ /* Next method for this node. */
+ int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64);
+
+ i64 iRowid; /* Current rowid */
+ Fts5ExprNearset *pNear; /* For FTS5_STRING - cluster of phrases */
+
/* Child nodes. For a NOT node, this array always contains 2 entries. For
- ** AND or OR nodes, it contains 2 or more entries. */
- int nChild; /* Number of child nodes */
- Fts5ExprNode *apChild[1]; /* Array of child nodes */
-};
-
-#define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING)
-
-/*
-** Invoke the xNext method of an Fts5ExprNode object. This macro should be
-** used as if it has the same signature as the xNext() methods themselves.
-*/
-#define fts5ExprNodeNext(a,b,c,d) (b)->xNext((a), (b), (c), (d))
-
-/*
-** An instance of the following structure represents a single search term
-** or term prefix.
-*/
-struct Fts5ExprTerm {
- u8 bPrefix; /* True for a prefix term */
- u8 bFirst; /* True if token must be first in column */
- char *zTerm; /* nul-terminated term */
- Fts5IndexIter *pIter; /* Iterator for this term */
- Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */
-};
-
-/*
-** A phrase. One or more terms that must appear in a contiguous sequence
-** within a document for it to match.
-*/
-struct Fts5ExprPhrase {
- Fts5ExprNode *pNode; /* FTS5_STRING node this phrase is part of */
- Fts5Buffer poslist; /* Current position list */
- int nTerm; /* Number of entries in aTerm[] */
- Fts5ExprTerm aTerm[1]; /* Terms that make up this phrase */
-};
-
-/*
-** One or more phrases that must appear within a certain token distance of
-** each other within each matching document.
-*/
-struct Fts5ExprNearset {
- int nNear; /* NEAR parameter */
- Fts5Colset *pColset; /* Columns to search (NULL -> all columns) */
- int nPhrase; /* Number of entries in aPhrase[] array */
- Fts5ExprPhrase *apPhrase[1]; /* Array of phrase pointers */
-};
-
-
-/*
-** Parse context.
-*/
-struct Fts5Parse {
- Fts5Config *pConfig;
- char *zErr;
- int rc;
- int nPhrase; /* Size of apPhrase array */
- Fts5ExprPhrase **apPhrase; /* Array of all phrases */
- Fts5ExprNode *pExpr; /* Result of a successful parse */
+ ** AND or OR nodes, it contains 2 or more entries. */
+ int nChild; /* Number of child nodes */
+ Fts5ExprNode *apChild[1]; /* Array of child nodes */
+};
+
+#define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING)
+
+/*
+** Invoke the xNext method of an Fts5ExprNode object. This macro should be
+** used as if it has the same signature as the xNext() methods themselves.
+*/
+#define fts5ExprNodeNext(a,b,c,d) (b)->xNext((a), (b), (c), (d))
+
+/*
+** An instance of the following structure represents a single search term
+** or term prefix.
+*/
+struct Fts5ExprTerm {
+ u8 bPrefix; /* True for a prefix term */
+ u8 bFirst; /* True if token must be first in column */
+ char *zTerm; /* nul-terminated term */
+ Fts5IndexIter *pIter; /* Iterator for this term */
+ Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */
+};
+
+/*
+** A phrase. One or more terms that must appear in a contiguous sequence
+** within a document for it to match.
+*/
+struct Fts5ExprPhrase {
+ Fts5ExprNode *pNode; /* FTS5_STRING node this phrase is part of */
+ Fts5Buffer poslist; /* Current position list */
+ int nTerm; /* Number of entries in aTerm[] */
+ Fts5ExprTerm aTerm[1]; /* Terms that make up this phrase */
+};
+
+/*
+** One or more phrases that must appear within a certain token distance of
+** each other within each matching document.
+*/
+struct Fts5ExprNearset {
+ int nNear; /* NEAR parameter */
+ Fts5Colset *pColset; /* Columns to search (NULL -> all columns) */
+ int nPhrase; /* Number of entries in aPhrase[] array */
+ Fts5ExprPhrase *apPhrase[1]; /* Array of phrase pointers */
+};
+
+
+/*
+** Parse context.
+*/
+struct Fts5Parse {
+ Fts5Config *pConfig;
+ char *zErr;
+ int rc;
+ int nPhrase; /* Size of apPhrase array */
+ Fts5ExprPhrase **apPhrase; /* Array of all phrases */
+ Fts5ExprNode *pExpr; /* Result of a successful parse */
int bPhraseToAnd; /* Convert "a+b" to "a AND b" */
-};
-
-static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
- va_list ap;
- va_start(ap, zFmt);
- if( pParse->rc==SQLITE_OK ){
+};
+
+static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
+ va_list ap;
+ va_start(ap, zFmt);
+ if( pParse->rc==SQLITE_OK ){
assert( pParse->zErr==0 );
- pParse->zErr = sqlite3_vmprintf(zFmt, ap);
- pParse->rc = SQLITE_ERROR;
- }
- va_end(ap);
-}
-
-static int fts5ExprIsspace(char t){
- return t==' ' || t=='\t' || t=='\n' || t=='\r';
-}
-
-/*
-** Read the first token from the nul-terminated string at *pz.
-*/
-static int fts5ExprGetToken(
+ pParse->zErr = sqlite3_vmprintf(zFmt, ap);
+ pParse->rc = SQLITE_ERROR;
+ }
+ va_end(ap);
+}
+
+static int fts5ExprIsspace(char t){
+ return t==' ' || t=='\t' || t=='\n' || t=='\r';
+}
+
+/*
+** Read the first token from the nul-terminated string at *pz.
+*/
+static int fts5ExprGetToken(
Fts5Parse *pParse,
- const char **pz, /* IN/OUT: Pointer into buffer */
- Fts5Token *pToken
-){
- const char *z = *pz;
- int tok;
-
- /* Skip past any whitespace */
- while( fts5ExprIsspace(*z) ) z++;
-
- pToken->p = z;
- pToken->n = 1;
- switch( *z ){
- case '(': tok = FTS5_LP; break;
- case ')': tok = FTS5_RP; break;
- case '{': tok = FTS5_LCP; break;
- case '}': tok = FTS5_RCP; break;
- case ':': tok = FTS5_COLON; break;
- case ',': tok = FTS5_COMMA; break;
- case '+': tok = FTS5_PLUS; break;
- case '*': tok = FTS5_STAR; break;
- case '-': tok = FTS5_MINUS; break;
- case '^': tok = FTS5_CARET; break;
- case '\0': tok = FTS5_EOF; break;
-
- case '"': {
- const char *z2;
- tok = FTS5_STRING;
-
- for(z2=&z[1]; 1; z2++){
- if( z2[0]=='"' ){
- z2++;
- if( z2[0]!='"' ) break;
- }
- if( z2[0]=='\0' ){
- sqlite3Fts5ParseError(pParse, "unterminated string");
- return FTS5_EOF;
- }
- }
- pToken->n = (z2 - z);
- break;
- }
-
- default: {
- const char *z2;
- if( sqlite3Fts5IsBareword(z[0])==0 ){
- sqlite3Fts5ParseError(pParse, "fts5: syntax error near \"%.1s\"", z);
- return FTS5_EOF;
- }
- tok = FTS5_STRING;
- for(z2=&z[1]; sqlite3Fts5IsBareword(*z2); z2++);
- pToken->n = (z2 - z);
- if( pToken->n==2 && memcmp(pToken->p, "OR", 2)==0 ) tok = FTS5_OR;
- if( pToken->n==3 && memcmp(pToken->p, "NOT", 3)==0 ) tok = FTS5_NOT;
- if( pToken->n==3 && memcmp(pToken->p, "AND", 3)==0 ) tok = FTS5_AND;
- break;
- }
- }
-
- *pz = &pToken->p[pToken->n];
- return tok;
-}
-
+ const char **pz, /* IN/OUT: Pointer into buffer */
+ Fts5Token *pToken
+){
+ const char *z = *pz;
+ int tok;
+
+ /* Skip past any whitespace */
+ while( fts5ExprIsspace(*z) ) z++;
+
+ pToken->p = z;
+ pToken->n = 1;
+ switch( *z ){
+ case '(': tok = FTS5_LP; break;
+ case ')': tok = FTS5_RP; break;
+ case '{': tok = FTS5_LCP; break;
+ case '}': tok = FTS5_RCP; break;
+ case ':': tok = FTS5_COLON; break;
+ case ',': tok = FTS5_COMMA; break;
+ case '+': tok = FTS5_PLUS; break;
+ case '*': tok = FTS5_STAR; break;
+ case '-': tok = FTS5_MINUS; break;
+ case '^': tok = FTS5_CARET; break;
+ case '\0': tok = FTS5_EOF; break;
+
+ case '"': {
+ const char *z2;
+ tok = FTS5_STRING;
+
+ for(z2=&z[1]; 1; z2++){
+ if( z2[0]=='"' ){
+ z2++;
+ if( z2[0]!='"' ) break;
+ }
+ if( z2[0]=='\0' ){
+ sqlite3Fts5ParseError(pParse, "unterminated string");
+ return FTS5_EOF;
+ }
+ }
+ pToken->n = (z2 - z);
+ break;
+ }
+
+ default: {
+ const char *z2;
+ if( sqlite3Fts5IsBareword(z[0])==0 ){
+ sqlite3Fts5ParseError(pParse, "fts5: syntax error near \"%.1s\"", z);
+ return FTS5_EOF;
+ }
+ tok = FTS5_STRING;
+ for(z2=&z[1]; sqlite3Fts5IsBareword(*z2); z2++);
+ pToken->n = (z2 - z);
+ if( pToken->n==2 && memcmp(pToken->p, "OR", 2)==0 ) tok = FTS5_OR;
+ if( pToken->n==3 && memcmp(pToken->p, "NOT", 3)==0 ) tok = FTS5_NOT;
+ if( pToken->n==3 && memcmp(pToken->p, "AND", 3)==0 ) tok = FTS5_AND;
+ break;
+ }
+ }
+
+ *pz = &pToken->p[pToken->n];
+ return tok;
+}
+
static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc64((sqlite3_int64)t);}
-static void fts5ParseFree(void *p){ sqlite3_free(p); }
-
-static int sqlite3Fts5ExprNew(
- Fts5Config *pConfig, /* FTS5 Configuration */
+static void fts5ParseFree(void *p){ sqlite3_free(p); }
+
+static int sqlite3Fts5ExprNew(
+ Fts5Config *pConfig, /* FTS5 Configuration */
int bPhraseToAnd,
- int iCol,
- const char *zExpr, /* Expression text */
+ int iCol,
+ const char *zExpr, /* Expression text */
Fts5Expr **ppNew,
- char **pzErr
-){
- Fts5Parse sParse;
- Fts5Token token;
- const char *z = zExpr;
- int t; /* Next token type */
- void *pEngine;
- Fts5Expr *pNew;
-
- *ppNew = 0;
- *pzErr = 0;
- memset(&sParse, 0, sizeof(sParse));
+ char **pzErr
+){
+ Fts5Parse sParse;
+ Fts5Token token;
+ const char *z = zExpr;
+ int t; /* Next token type */
+ void *pEngine;
+ Fts5Expr *pNew;
+
+ *ppNew = 0;
+ *pzErr = 0;
+ memset(&sParse, 0, sizeof(sParse));
sParse.bPhraseToAnd = bPhraseToAnd;
- pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc);
- if( pEngine==0 ){ return SQLITE_NOMEM; }
- sParse.pConfig = pConfig;
-
- do {
- t = fts5ExprGetToken(&sParse, &z, &token);
- sqlite3Fts5Parser(pEngine, t, token, &sParse);
- }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
- sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
-
- /* If the LHS of the MATCH expression was a user column, apply the
- ** implicit column-filter. */
- if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){
- int n = sizeof(Fts5Colset);
- Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
- if( pColset ){
- pColset->nCol = 1;
- pColset->aiCol[0] = iCol;
- sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset);
- }
- }
-
- assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
- if( sParse.rc==SQLITE_OK ){
- *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
- if( pNew==0 ){
- sParse.rc = SQLITE_NOMEM;
- sqlite3Fts5ParseNodeFree(sParse.pExpr);
- }else{
- if( !sParse.pExpr ){
- const int nByte = sizeof(Fts5ExprNode);
- pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte);
- if( pNew->pRoot ){
- pNew->pRoot->bEof = 1;
- }
- }else{
- pNew->pRoot = sParse.pExpr;
- }
- pNew->pIndex = 0;
- pNew->pConfig = pConfig;
- pNew->apExprPhrase = sParse.apPhrase;
- pNew->nPhrase = sParse.nPhrase;
+ pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc);
+ if( pEngine==0 ){ return SQLITE_NOMEM; }
+ sParse.pConfig = pConfig;
+
+ do {
+ t = fts5ExprGetToken(&sParse, &z, &token);
+ sqlite3Fts5Parser(pEngine, t, token, &sParse);
+ }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
+ sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
+
+ /* If the LHS of the MATCH expression was a user column, apply the
+ ** implicit column-filter. */
+ if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){
+ int n = sizeof(Fts5Colset);
+ Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
+ if( pColset ){
+ pColset->nCol = 1;
+ pColset->aiCol[0] = iCol;
+ sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset);
+ }
+ }
+
+ assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
+ if( sParse.rc==SQLITE_OK ){
+ *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
+ if( pNew==0 ){
+ sParse.rc = SQLITE_NOMEM;
+ sqlite3Fts5ParseNodeFree(sParse.pExpr);
+ }else{
+ if( !sParse.pExpr ){
+ const int nByte = sizeof(Fts5ExprNode);
+ pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte);
+ if( pNew->pRoot ){
+ pNew->pRoot->bEof = 1;
+ }
+ }else{
+ pNew->pRoot = sParse.pExpr;
+ }
+ pNew->pIndex = 0;
+ pNew->pConfig = pConfig;
+ pNew->apExprPhrase = sParse.apPhrase;
+ pNew->nPhrase = sParse.nPhrase;
pNew->bDesc = 0;
- sParse.apPhrase = 0;
- }
- }else{
- sqlite3Fts5ParseNodeFree(sParse.pExpr);
- }
-
- sqlite3_free(sParse.apPhrase);
- *pzErr = sParse.zErr;
- return sParse.rc;
-}
-
-/*
+ sParse.apPhrase = 0;
+ }
+ }else{
+ sqlite3Fts5ParseNodeFree(sParse.pExpr);
+ }
+
+ sqlite3_free(sParse.apPhrase);
+ *pzErr = sParse.zErr;
+ return sParse.rc;
+}
+
+/*
** This function is only called when using the special 'trigram' tokenizer.
** Argument zText contains the text of a LIKE or GLOB pattern matched
** against column iCol. This function creates and compiles an FTS5 MATCH
@@ -219673,30 +219673,30 @@ static int sqlite3Fts5ExprPattern(
}
/*
-** Free the expression node object passed as the only argument.
-*/
-static void sqlite3Fts5ParseNodeFree(Fts5ExprNode *p){
- if( p ){
- int i;
- for(i=0; i<p->nChild; i++){
- sqlite3Fts5ParseNodeFree(p->apChild[i]);
- }
- sqlite3Fts5ParseNearsetFree(p->pNear);
- sqlite3_free(p);
- }
-}
-
-/*
-** Free the expression object passed as the only argument.
-*/
-static void sqlite3Fts5ExprFree(Fts5Expr *p){
- if( p ){
- sqlite3Fts5ParseNodeFree(p->pRoot);
- sqlite3_free(p->apExprPhrase);
- sqlite3_free(p);
- }
-}
-
+** Free the expression node object passed as the only argument.
+*/
+static void sqlite3Fts5ParseNodeFree(Fts5ExprNode *p){
+ if( p ){
+ int i;
+ for(i=0; i<p->nChild; i++){
+ sqlite3Fts5ParseNodeFree(p->apChild[i]);
+ }
+ sqlite3Fts5ParseNearsetFree(p->pNear);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Free the expression object passed as the only argument.
+*/
+static void sqlite3Fts5ExprFree(Fts5Expr *p){
+ if( p ){
+ sqlite3Fts5ParseNodeFree(p->pRoot);
+ sqlite3_free(p->apExprPhrase);
+ sqlite3_free(p);
+ }
+}
+
static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){
Fts5Parse sParse;
memset(&sParse, 0, sizeof(sParse));
@@ -219733,1323 +219733,1323 @@ static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){
return sParse.rc;
}
-/*
-** Argument pTerm must be a synonym iterator. Return the current rowid
-** that it points to.
-*/
-static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
- i64 iRet = 0;
- int bRetValid = 0;
- Fts5ExprTerm *p;
-
+/*
+** Argument pTerm must be a synonym iterator. Return the current rowid
+** that it points to.
+*/
+static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
+ i64 iRet = 0;
+ int bRetValid = 0;
+ Fts5ExprTerm *p;
+
assert( pTerm );
- assert( pTerm->pSynonym );
- assert( bDesc==0 || bDesc==1 );
- for(p=pTerm; p; p=p->pSynonym){
- if( 0==sqlite3Fts5IterEof(p->pIter) ){
- i64 iRowid = p->pIter->iRowid;
- if( bRetValid==0 || (bDesc!=(iRowid<iRet)) ){
- iRet = iRowid;
- bRetValid = 1;
- }
- }
- }
-
- if( pbEof && bRetValid==0 ) *pbEof = 1;
- return iRet;
-}
-
-/*
-** Argument pTerm must be a synonym iterator.
-*/
-static int fts5ExprSynonymList(
+ assert( pTerm->pSynonym );
+ assert( bDesc==0 || bDesc==1 );
+ for(p=pTerm; p; p=p->pSynonym){
+ if( 0==sqlite3Fts5IterEof(p->pIter) ){
+ i64 iRowid = p->pIter->iRowid;
+ if( bRetValid==0 || (bDesc!=(iRowid<iRet)) ){
+ iRet = iRowid;
+ bRetValid = 1;
+ }
+ }
+ }
+
+ if( pbEof && bRetValid==0 ) *pbEof = 1;
+ return iRet;
+}
+
+/*
+** Argument pTerm must be a synonym iterator.
+*/
+static int fts5ExprSynonymList(
Fts5ExprTerm *pTerm,
- i64 iRowid,
- Fts5Buffer *pBuf, /* Use this buffer for space if required */
- u8 **pa, int *pn
-){
- Fts5PoslistReader aStatic[4];
- Fts5PoslistReader *aIter = aStatic;
- int nIter = 0;
- int nAlloc = 4;
- int rc = SQLITE_OK;
- Fts5ExprTerm *p;
-
- assert( pTerm->pSynonym );
- for(p=pTerm; p; p=p->pSynonym){
- Fts5IndexIter *pIter = p->pIter;
- if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){
- if( pIter->nData==0 ) continue;
- if( nIter==nAlloc ){
+ i64 iRowid,
+ Fts5Buffer *pBuf, /* Use this buffer for space if required */
+ u8 **pa, int *pn
+){
+ Fts5PoslistReader aStatic[4];
+ Fts5PoslistReader *aIter = aStatic;
+ int nIter = 0;
+ int nAlloc = 4;
+ int rc = SQLITE_OK;
+ Fts5ExprTerm *p;
+
+ assert( pTerm->pSynonym );
+ for(p=pTerm; p; p=p->pSynonym){
+ Fts5IndexIter *pIter = p->pIter;
+ if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){
+ if( pIter->nData==0 ) continue;
+ if( nIter==nAlloc ){
sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
- if( aNew==0 ){
- rc = SQLITE_NOMEM;
- goto synonym_poslist_out;
- }
- memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
- nAlloc = nAlloc*2;
- if( aIter!=aStatic ) sqlite3_free(aIter);
- aIter = aNew;
- }
- sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]);
- assert( aIter[nIter].bEof==0 );
- nIter++;
- }
- }
-
- if( nIter==1 ){
- *pa = (u8*)aIter[0].a;
- *pn = aIter[0].n;
- }else{
- Fts5PoslistWriter writer = {0};
- i64 iPrev = -1;
- fts5BufferZero(pBuf);
- while( 1 ){
- int i;
- i64 iMin = FTS5_LARGEST_INT64;
- for(i=0; i<nIter; i++){
- if( aIter[i].bEof==0 ){
- if( aIter[i].iPos==iPrev ){
- if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) continue;
- }
- if( aIter[i].iPos<iMin ){
- iMin = aIter[i].iPos;
- }
- }
- }
- if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break;
- rc = sqlite3Fts5PoslistWriterAppend(pBuf, &writer, iMin);
- iPrev = iMin;
- }
- if( rc==SQLITE_OK ){
- *pa = pBuf->p;
- *pn = pBuf->n;
- }
- }
-
- synonym_poslist_out:
- if( aIter!=aStatic ) sqlite3_free(aIter);
- return rc;
-}
-
-
-/*
-** All individual term iterators in pPhrase are guaranteed to be valid and
+ if( aNew==0 ){
+ rc = SQLITE_NOMEM;
+ goto synonym_poslist_out;
+ }
+ memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
+ nAlloc = nAlloc*2;
+ if( aIter!=aStatic ) sqlite3_free(aIter);
+ aIter = aNew;
+ }
+ sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]);
+ assert( aIter[nIter].bEof==0 );
+ nIter++;
+ }
+ }
+
+ if( nIter==1 ){
+ *pa = (u8*)aIter[0].a;
+ *pn = aIter[0].n;
+ }else{
+ Fts5PoslistWriter writer = {0};
+ i64 iPrev = -1;
+ fts5BufferZero(pBuf);
+ while( 1 ){
+ int i;
+ i64 iMin = FTS5_LARGEST_INT64;
+ for(i=0; i<nIter; i++){
+ if( aIter[i].bEof==0 ){
+ if( aIter[i].iPos==iPrev ){
+ if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) continue;
+ }
+ if( aIter[i].iPos<iMin ){
+ iMin = aIter[i].iPos;
+ }
+ }
+ }
+ if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break;
+ rc = sqlite3Fts5PoslistWriterAppend(pBuf, &writer, iMin);
+ iPrev = iMin;
+ }
+ if( rc==SQLITE_OK ){
+ *pa = pBuf->p;
+ *pn = pBuf->n;
+ }
+ }
+
+ synonym_poslist_out:
+ if( aIter!=aStatic ) sqlite3_free(aIter);
+ return rc;
+}
+
+
+/*
+** All individual term iterators in pPhrase are guaranteed to be valid and
** pointing to the same rowid when this function is called. This function
-** checks if the current rowid really is a match, and if so populates
-** the pPhrase->poslist buffer accordingly. Output parameter *pbMatch
-** is set to true if this is really a match, or false otherwise.
-**
+** checks if the current rowid really is a match, and if so populates
+** the pPhrase->poslist buffer accordingly. Output parameter *pbMatch
+** is set to true if this is really a match, or false otherwise.
+**
** SQLITE_OK is returned if an error occurs, or an SQLite error code
** otherwise. It is not considered an error code if the current rowid is
-** not a match.
-*/
-static int fts5ExprPhraseIsMatch(
- Fts5ExprNode *pNode, /* Node pPhrase belongs to */
- Fts5ExprPhrase *pPhrase, /* Phrase object to initialize */
- int *pbMatch /* OUT: Set to true if really a match */
-){
- Fts5PoslistWriter writer = {0};
- Fts5PoslistReader aStatic[4];
- Fts5PoslistReader *aIter = aStatic;
- int i;
- int rc = SQLITE_OK;
- int bFirst = pPhrase->aTerm[0].bFirst;
-
- fts5BufferZero(&pPhrase->poslist);
-
- /* If the aStatic[] array is not large enough, allocate a large array
- ** using sqlite3_malloc(). This approach could be improved upon. */
- if( pPhrase->nTerm>ArraySize(aStatic) ){
+** not a match.
+*/
+static int fts5ExprPhraseIsMatch(
+ Fts5ExprNode *pNode, /* Node pPhrase belongs to */
+ Fts5ExprPhrase *pPhrase, /* Phrase object to initialize */
+ int *pbMatch /* OUT: Set to true if really a match */
+){
+ Fts5PoslistWriter writer = {0};
+ Fts5PoslistReader aStatic[4];
+ Fts5PoslistReader *aIter = aStatic;
+ int i;
+ int rc = SQLITE_OK;
+ int bFirst = pPhrase->aTerm[0].bFirst;
+
+ fts5BufferZero(&pPhrase->poslist);
+
+ /* If the aStatic[] array is not large enough, allocate a large array
+ ** using sqlite3_malloc(). This approach could be improved upon. */
+ if( pPhrase->nTerm>ArraySize(aStatic) ){
sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
aIter = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
- if( !aIter ) return SQLITE_NOMEM;
- }
- memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
-
- /* Initialize a term iterator for each term in the phrase */
- for(i=0; i<pPhrase->nTerm; i++){
- Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
- int n = 0;
- int bFlag = 0;
- u8 *a = 0;
- if( pTerm->pSynonym ){
- Fts5Buffer buf = {0, 0, 0};
- rc = fts5ExprSynonymList(pTerm, pNode->iRowid, &buf, &a, &n);
- if( rc ){
- sqlite3_free(a);
- goto ismatch_out;
- }
- if( a==buf.p ) bFlag = 1;
- }else{
- a = (u8*)pTerm->pIter->pData;
- n = pTerm->pIter->nData;
- }
- sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
- aIter[i].bFlag = (u8)bFlag;
- if( aIter[i].bEof ) goto ismatch_out;
- }
-
- while( 1 ){
- int bMatch;
- i64 iPos = aIter[0].iPos;
- do {
- bMatch = 1;
- for(i=0; i<pPhrase->nTerm; i++){
- Fts5PoslistReader *pPos = &aIter[i];
- i64 iAdj = iPos + i;
- if( pPos->iPos!=iAdj ){
- bMatch = 0;
- while( pPos->iPos<iAdj ){
- if( sqlite3Fts5PoslistReaderNext(pPos) ) goto ismatch_out;
- }
- if( pPos->iPos>iAdj ) iPos = pPos->iPos-i;
- }
- }
- }while( bMatch==0 );
-
- /* Append position iPos to the output */
- if( bFirst==0 || FTS5_POS2OFFSET(iPos)==0 ){
- rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
- if( rc!=SQLITE_OK ) goto ismatch_out;
- }
-
- for(i=0; i<pPhrase->nTerm; i++){
- if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
- }
- }
-
- ismatch_out:
- *pbMatch = (pPhrase->poslist.n>0);
- for(i=0; i<pPhrase->nTerm; i++){
- if( aIter[i].bFlag ) sqlite3_free((u8*)aIter[i].a);
- }
- if( aIter!=aStatic ) sqlite3_free(aIter);
- return rc;
-}
-
-typedef struct Fts5LookaheadReader Fts5LookaheadReader;
-struct Fts5LookaheadReader {
- const u8 *a; /* Buffer containing position list */
- int n; /* Size of buffer a[] in bytes */
- int i; /* Current offset in position list */
- i64 iPos; /* Current position */
- i64 iLookahead; /* Next position */
-};
-
-#define FTS5_LOOKAHEAD_EOF (((i64)1) << 62)
-
-static int fts5LookaheadReaderNext(Fts5LookaheadReader *p){
- p->iPos = p->iLookahead;
- if( sqlite3Fts5PoslistNext64(p->a, p->n, &p->i, &p->iLookahead) ){
- p->iLookahead = FTS5_LOOKAHEAD_EOF;
- }
- return (p->iPos==FTS5_LOOKAHEAD_EOF);
-}
-
-static int fts5LookaheadReaderInit(
- const u8 *a, int n, /* Buffer to read position list from */
- Fts5LookaheadReader *p /* Iterator object to initialize */
-){
- memset(p, 0, sizeof(Fts5LookaheadReader));
- p->a = a;
- p->n = n;
- fts5LookaheadReaderNext(p);
- return fts5LookaheadReaderNext(p);
-}
-
-typedef struct Fts5NearTrimmer Fts5NearTrimmer;
-struct Fts5NearTrimmer {
- Fts5LookaheadReader reader; /* Input iterator */
- Fts5PoslistWriter writer; /* Writer context */
- Fts5Buffer *pOut; /* Output poslist */
-};
-
-/*
-** The near-set object passed as the first argument contains more than
-** one phrase. All phrases currently point to the same row. The
-** Fts5ExprPhrase.poslist buffers are populated accordingly. This function
-** tests if the current row contains instances of each phrase sufficiently
-** close together to meet the NEAR constraint. Non-zero is returned if it
-** does, or zero otherwise.
-**
-** If in/out parameter (*pRc) is set to other than SQLITE_OK when this
-** function is called, it is a no-op. Or, if an error (e.g. SQLITE_NOMEM)
-** occurs within this function (*pRc) is set accordingly before returning.
-** The return value is undefined in both these cases.
-**
-** If no error occurs and non-zero (a match) is returned, the position-list
-** of each phrase object is edited to contain only those entries that
-** meet the constraint before returning.
-*/
-static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
- Fts5NearTrimmer aStatic[4];
- Fts5NearTrimmer *a = aStatic;
- Fts5ExprPhrase **apPhrase = pNear->apPhrase;
-
- int i;
- int rc = *pRc;
- int bMatch;
-
- assert( pNear->nPhrase>1 );
-
- /* If the aStatic[] array is not large enough, allocate a large array
- ** using sqlite3_malloc(). This approach could be improved upon. */
- if( pNear->nPhrase>ArraySize(aStatic) ){
+ if( !aIter ) return SQLITE_NOMEM;
+ }
+ memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
+
+ /* Initialize a term iterator for each term in the phrase */
+ for(i=0; i<pPhrase->nTerm; i++){
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
+ int n = 0;
+ int bFlag = 0;
+ u8 *a = 0;
+ if( pTerm->pSynonym ){
+ Fts5Buffer buf = {0, 0, 0};
+ rc = fts5ExprSynonymList(pTerm, pNode->iRowid, &buf, &a, &n);
+ if( rc ){
+ sqlite3_free(a);
+ goto ismatch_out;
+ }
+ if( a==buf.p ) bFlag = 1;
+ }else{
+ a = (u8*)pTerm->pIter->pData;
+ n = pTerm->pIter->nData;
+ }
+ sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
+ aIter[i].bFlag = (u8)bFlag;
+ if( aIter[i].bEof ) goto ismatch_out;
+ }
+
+ while( 1 ){
+ int bMatch;
+ i64 iPos = aIter[0].iPos;
+ do {
+ bMatch = 1;
+ for(i=0; i<pPhrase->nTerm; i++){
+ Fts5PoslistReader *pPos = &aIter[i];
+ i64 iAdj = iPos + i;
+ if( pPos->iPos!=iAdj ){
+ bMatch = 0;
+ while( pPos->iPos<iAdj ){
+ if( sqlite3Fts5PoslistReaderNext(pPos) ) goto ismatch_out;
+ }
+ if( pPos->iPos>iAdj ) iPos = pPos->iPos-i;
+ }
+ }
+ }while( bMatch==0 );
+
+ /* Append position iPos to the output */
+ if( bFirst==0 || FTS5_POS2OFFSET(iPos)==0 ){
+ rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
+ if( rc!=SQLITE_OK ) goto ismatch_out;
+ }
+
+ for(i=0; i<pPhrase->nTerm; i++){
+ if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
+ }
+ }
+
+ ismatch_out:
+ *pbMatch = (pPhrase->poslist.n>0);
+ for(i=0; i<pPhrase->nTerm; i++){
+ if( aIter[i].bFlag ) sqlite3_free((u8*)aIter[i].a);
+ }
+ if( aIter!=aStatic ) sqlite3_free(aIter);
+ return rc;
+}
+
+typedef struct Fts5LookaheadReader Fts5LookaheadReader;
+struct Fts5LookaheadReader {
+ const u8 *a; /* Buffer containing position list */
+ int n; /* Size of buffer a[] in bytes */
+ int i; /* Current offset in position list */
+ i64 iPos; /* Current position */
+ i64 iLookahead; /* Next position */
+};
+
+#define FTS5_LOOKAHEAD_EOF (((i64)1) << 62)
+
+static int fts5LookaheadReaderNext(Fts5LookaheadReader *p){
+ p->iPos = p->iLookahead;
+ if( sqlite3Fts5PoslistNext64(p->a, p->n, &p->i, &p->iLookahead) ){
+ p->iLookahead = FTS5_LOOKAHEAD_EOF;
+ }
+ return (p->iPos==FTS5_LOOKAHEAD_EOF);
+}
+
+static int fts5LookaheadReaderInit(
+ const u8 *a, int n, /* Buffer to read position list from */
+ Fts5LookaheadReader *p /* Iterator object to initialize */
+){
+ memset(p, 0, sizeof(Fts5LookaheadReader));
+ p->a = a;
+ p->n = n;
+ fts5LookaheadReaderNext(p);
+ return fts5LookaheadReaderNext(p);
+}
+
+typedef struct Fts5NearTrimmer Fts5NearTrimmer;
+struct Fts5NearTrimmer {
+ Fts5LookaheadReader reader; /* Input iterator */
+ Fts5PoslistWriter writer; /* Writer context */
+ Fts5Buffer *pOut; /* Output poslist */
+};
+
+/*
+** The near-set object passed as the first argument contains more than
+** one phrase. All phrases currently point to the same row. The
+** Fts5ExprPhrase.poslist buffers are populated accordingly. This function
+** tests if the current row contains instances of each phrase sufficiently
+** close together to meet the NEAR constraint. Non-zero is returned if it
+** does, or zero otherwise.
+**
+** If in/out parameter (*pRc) is set to other than SQLITE_OK when this
+** function is called, it is a no-op. Or, if an error (e.g. SQLITE_NOMEM)
+** occurs within this function (*pRc) is set accordingly before returning.
+** The return value is undefined in both these cases.
+**
+** If no error occurs and non-zero (a match) is returned, the position-list
+** of each phrase object is edited to contain only those entries that
+** meet the constraint before returning.
+*/
+static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
+ Fts5NearTrimmer aStatic[4];
+ Fts5NearTrimmer *a = aStatic;
+ Fts5ExprPhrase **apPhrase = pNear->apPhrase;
+
+ int i;
+ int rc = *pRc;
+ int bMatch;
+
+ assert( pNear->nPhrase>1 );
+
+ /* If the aStatic[] array is not large enough, allocate a large array
+ ** using sqlite3_malloc(). This approach could be improved upon. */
+ if( pNear->nPhrase>ArraySize(aStatic) ){
sqlite3_int64 nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
- a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
- }else{
- memset(aStatic, 0, sizeof(aStatic));
- }
- if( rc!=SQLITE_OK ){
- *pRc = rc;
- return 0;
- }
-
- /* Initialize a lookahead iterator for each phrase. After passing the
- ** buffer and buffer size to the lookaside-reader init function, zero
- ** the phrase poslist buffer. The new poslist for the phrase (containing
+ a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
+ }else{
+ memset(aStatic, 0, sizeof(aStatic));
+ }
+ if( rc!=SQLITE_OK ){
+ *pRc = rc;
+ return 0;
+ }
+
+ /* Initialize a lookahead iterator for each phrase. After passing the
+ ** buffer and buffer size to the lookaside-reader init function, zero
+ ** the phrase poslist buffer. The new poslist for the phrase (containing
** the same entries as the original with some entries removed on account
- ** of the NEAR constraint) is written over the original even as it is
- ** being read. This is safe as the entries for the new poslist are a
- ** subset of the old, so it is not possible for data yet to be read to
- ** be overwritten. */
- for(i=0; i<pNear->nPhrase; i++){
- Fts5Buffer *pPoslist = &apPhrase[i]->poslist;
- fts5LookaheadReaderInit(pPoslist->p, pPoslist->n, &a[i].reader);
- pPoslist->n = 0;
- a[i].pOut = pPoslist;
- }
-
- while( 1 ){
- int iAdv;
- i64 iMin;
- i64 iMax;
-
- /* This block advances the phrase iterators until they point to a set of
- ** entries that together comprise a match. */
- iMax = a[0].reader.iPos;
- do {
- bMatch = 1;
- for(i=0; i<pNear->nPhrase; i++){
- Fts5LookaheadReader *pPos = &a[i].reader;
- iMin = iMax - pNear->apPhrase[i]->nTerm - pNear->nNear;
- if( pPos->iPos<iMin || pPos->iPos>iMax ){
- bMatch = 0;
- while( pPos->iPos<iMin ){
- if( fts5LookaheadReaderNext(pPos) ) goto ismatch_out;
- }
- if( pPos->iPos>iMax ) iMax = pPos->iPos;
- }
- }
- }while( bMatch==0 );
-
- /* Add an entry to each output position list */
- for(i=0; i<pNear->nPhrase; i++){
- i64 iPos = a[i].reader.iPos;
- Fts5PoslistWriter *pWriter = &a[i].writer;
- if( a[i].pOut->n==0 || iPos!=pWriter->iPrev ){
- sqlite3Fts5PoslistWriterAppend(a[i].pOut, pWriter, iPos);
- }
- }
-
- iAdv = 0;
- iMin = a[0].reader.iLookahead;
- for(i=0; i<pNear->nPhrase; i++){
- if( a[i].reader.iLookahead < iMin ){
- iMin = a[i].reader.iLookahead;
- iAdv = i;
- }
- }
- if( fts5LookaheadReaderNext(&a[iAdv].reader) ) goto ismatch_out;
- }
-
- ismatch_out: {
- int bRet = a[0].pOut->n>0;
- *pRc = rc;
- if( a!=aStatic ) sqlite3_free(a);
- return bRet;
- }
-}
-
-/*
-** Advance iterator pIter until it points to a value equal to or laster
-** than the initial value of *piLast. If this means the iterator points
-** to a value laster than *piLast, update *piLast to the new lastest value.
-**
-** If the iterator reaches EOF, set *pbEof to true before returning. If
-** an error occurs, set *pRc to an error code. If either *pbEof or *pRc
-** are set, return a non-zero value. Otherwise, return zero.
-*/
-static int fts5ExprAdvanceto(
- Fts5IndexIter *pIter, /* Iterator to advance */
- int bDesc, /* True if iterator is "rowid DESC" */
- i64 *piLast, /* IN/OUT: Lastest rowid seen so far */
- int *pRc, /* OUT: Error code */
- int *pbEof /* OUT: Set to true if EOF */
-){
- i64 iLast = *piLast;
- i64 iRowid;
-
- iRowid = pIter->iRowid;
- if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
- int rc = sqlite3Fts5IterNextFrom(pIter, iLast);
- if( rc || sqlite3Fts5IterEof(pIter) ){
- *pRc = rc;
- *pbEof = 1;
- return 1;
- }
- iRowid = pIter->iRowid;
- assert( (bDesc==0 && iRowid>=iLast) || (bDesc==1 && iRowid<=iLast) );
- }
- *piLast = iRowid;
-
- return 0;
-}
-
-static int fts5ExprSynonymAdvanceto(
- Fts5ExprTerm *pTerm, /* Term iterator to advance */
- int bDesc, /* True if iterator is "rowid DESC" */
- i64 *piLast, /* IN/OUT: Lastest rowid seen so far */
- int *pRc /* OUT: Error code */
-){
- int rc = SQLITE_OK;
- i64 iLast = *piLast;
- Fts5ExprTerm *p;
- int bEof = 0;
-
- for(p=pTerm; rc==SQLITE_OK && p; p=p->pSynonym){
- if( sqlite3Fts5IterEof(p->pIter)==0 ){
- i64 iRowid = p->pIter->iRowid;
- if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
- rc = sqlite3Fts5IterNextFrom(p->pIter, iLast);
- }
- }
- }
-
- if( rc!=SQLITE_OK ){
- *pRc = rc;
- bEof = 1;
- }else{
- *piLast = fts5ExprSynonymRowid(pTerm, bDesc, &bEof);
- }
- return bEof;
-}
-
-
-static int fts5ExprNearTest(
- int *pRc,
- Fts5Expr *pExpr, /* Expression that pNear is a part of */
- Fts5ExprNode *pNode /* The "NEAR" node (FTS5_STRING) */
-){
- Fts5ExprNearset *pNear = pNode->pNear;
- int rc = *pRc;
-
- if( pExpr->pConfig->eDetail!=FTS5_DETAIL_FULL ){
- Fts5ExprTerm *pTerm;
- Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
- pPhrase->poslist.n = 0;
- for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
- Fts5IndexIter *pIter = pTerm->pIter;
- if( sqlite3Fts5IterEof(pIter)==0 ){
- if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){
- pPhrase->poslist.n = 1;
- }
- }
- }
- return pPhrase->poslist.n;
- }else{
- int i;
-
- /* Check that each phrase in the nearset matches the current row.
- ** Populate the pPhrase->poslist buffers at the same time. If any
- ** phrase is not a match, break out of the loop early. */
- for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
- Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+ ** of the NEAR constraint) is written over the original even as it is
+ ** being read. This is safe as the entries for the new poslist are a
+ ** subset of the old, so it is not possible for data yet to be read to
+ ** be overwritten. */
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5Buffer *pPoslist = &apPhrase[i]->poslist;
+ fts5LookaheadReaderInit(pPoslist->p, pPoslist->n, &a[i].reader);
+ pPoslist->n = 0;
+ a[i].pOut = pPoslist;
+ }
+
+ while( 1 ){
+ int iAdv;
+ i64 iMin;
+ i64 iMax;
+
+ /* This block advances the phrase iterators until they point to a set of
+ ** entries that together comprise a match. */
+ iMax = a[0].reader.iPos;
+ do {
+ bMatch = 1;
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5LookaheadReader *pPos = &a[i].reader;
+ iMin = iMax - pNear->apPhrase[i]->nTerm - pNear->nNear;
+ if( pPos->iPos<iMin || pPos->iPos>iMax ){
+ bMatch = 0;
+ while( pPos->iPos<iMin ){
+ if( fts5LookaheadReaderNext(pPos) ) goto ismatch_out;
+ }
+ if( pPos->iPos>iMax ) iMax = pPos->iPos;
+ }
+ }
+ }while( bMatch==0 );
+
+ /* Add an entry to each output position list */
+ for(i=0; i<pNear->nPhrase; i++){
+ i64 iPos = a[i].reader.iPos;
+ Fts5PoslistWriter *pWriter = &a[i].writer;
+ if( a[i].pOut->n==0 || iPos!=pWriter->iPrev ){
+ sqlite3Fts5PoslistWriterAppend(a[i].pOut, pWriter, iPos);
+ }
+ }
+
+ iAdv = 0;
+ iMin = a[0].reader.iLookahead;
+ for(i=0; i<pNear->nPhrase; i++){
+ if( a[i].reader.iLookahead < iMin ){
+ iMin = a[i].reader.iLookahead;
+ iAdv = i;
+ }
+ }
+ if( fts5LookaheadReaderNext(&a[iAdv].reader) ) goto ismatch_out;
+ }
+
+ ismatch_out: {
+ int bRet = a[0].pOut->n>0;
+ *pRc = rc;
+ if( a!=aStatic ) sqlite3_free(a);
+ return bRet;
+ }
+}
+
+/*
+** Advance iterator pIter until it points to a value equal to or laster
+** than the initial value of *piLast. If this means the iterator points
+** to a value laster than *piLast, update *piLast to the new lastest value.
+**
+** If the iterator reaches EOF, set *pbEof to true before returning. If
+** an error occurs, set *pRc to an error code. If either *pbEof or *pRc
+** are set, return a non-zero value. Otherwise, return zero.
+*/
+static int fts5ExprAdvanceto(
+ Fts5IndexIter *pIter, /* Iterator to advance */
+ int bDesc, /* True if iterator is "rowid DESC" */
+ i64 *piLast, /* IN/OUT: Lastest rowid seen so far */
+ int *pRc, /* OUT: Error code */
+ int *pbEof /* OUT: Set to true if EOF */
+){
+ i64 iLast = *piLast;
+ i64 iRowid;
+
+ iRowid = pIter->iRowid;
+ if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
+ int rc = sqlite3Fts5IterNextFrom(pIter, iLast);
+ if( rc || sqlite3Fts5IterEof(pIter) ){
+ *pRc = rc;
+ *pbEof = 1;
+ return 1;
+ }
+ iRowid = pIter->iRowid;
+ assert( (bDesc==0 && iRowid>=iLast) || (bDesc==1 && iRowid<=iLast) );
+ }
+ *piLast = iRowid;
+
+ return 0;
+}
+
+static int fts5ExprSynonymAdvanceto(
+ Fts5ExprTerm *pTerm, /* Term iterator to advance */
+ int bDesc, /* True if iterator is "rowid DESC" */
+ i64 *piLast, /* IN/OUT: Lastest rowid seen so far */
+ int *pRc /* OUT: Error code */
+){
+ int rc = SQLITE_OK;
+ i64 iLast = *piLast;
+ Fts5ExprTerm *p;
+ int bEof = 0;
+
+ for(p=pTerm; rc==SQLITE_OK && p; p=p->pSynonym){
+ if( sqlite3Fts5IterEof(p->pIter)==0 ){
+ i64 iRowid = p->pIter->iRowid;
+ if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
+ rc = sqlite3Fts5IterNextFrom(p->pIter, iLast);
+ }
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ *pRc = rc;
+ bEof = 1;
+ }else{
+ *piLast = fts5ExprSynonymRowid(pTerm, bDesc, &bEof);
+ }
+ return bEof;
+}
+
+
+static int fts5ExprNearTest(
+ int *pRc,
+ Fts5Expr *pExpr, /* Expression that pNear is a part of */
+ Fts5ExprNode *pNode /* The "NEAR" node (FTS5_STRING) */
+){
+ Fts5ExprNearset *pNear = pNode->pNear;
+ int rc = *pRc;
+
+ if( pExpr->pConfig->eDetail!=FTS5_DETAIL_FULL ){
+ Fts5ExprTerm *pTerm;
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
+ pPhrase->poslist.n = 0;
+ for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
+ Fts5IndexIter *pIter = pTerm->pIter;
+ if( sqlite3Fts5IterEof(pIter)==0 ){
+ if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){
+ pPhrase->poslist.n = 1;
+ }
+ }
+ }
+ return pPhrase->poslist.n;
+ }else{
+ int i;
+
+ /* Check that each phrase in the nearset matches the current row.
+ ** Populate the pPhrase->poslist buffers at the same time. If any
+ ** phrase is not a match, break out of the loop early. */
+ for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym
- || pNear->pColset || pPhrase->aTerm[0].bFirst
- ){
- int bMatch = 0;
- rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch);
- if( bMatch==0 ) break;
- }else{
- Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
- fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData);
- }
- }
-
- *pRc = rc;
- if( i==pNear->nPhrase && (i==1 || fts5ExprNearIsMatch(pRc, pNear)) ){
- return 1;
- }
- return 0;
- }
-}
-
-
-/*
-** Initialize all term iterators in the pNear object. If any term is found
-** to match no documents at all, return immediately without initializing any
-** further iterators.
-**
-** If an error occurs, return an SQLite error code. Otherwise, return
-** SQLITE_OK. It is not considered an error if some term matches zero
-** documents.
-*/
-static int fts5ExprNearInitAll(
- Fts5Expr *pExpr,
- Fts5ExprNode *pNode
-){
- Fts5ExprNearset *pNear = pNode->pNear;
- int i;
-
- assert( pNode->bNomatch==0 );
- for(i=0; i<pNear->nPhrase; i++){
- Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
- if( pPhrase->nTerm==0 ){
- pNode->bEof = 1;
- return SQLITE_OK;
- }else{
- int j;
- for(j=0; j<pPhrase->nTerm; j++){
- Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
- Fts5ExprTerm *p;
- int bHit = 0;
-
- for(p=pTerm; p; p=p->pSynonym){
- int rc;
- if( p->pIter ){
- sqlite3Fts5IterClose(p->pIter);
- p->pIter = 0;
- }
- rc = sqlite3Fts5IndexQuery(
- pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
- (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
- (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
- pNear->pColset,
- &p->pIter
- );
- assert( (rc==SQLITE_OK)==(p->pIter!=0) );
- if( rc!=SQLITE_OK ) return rc;
- if( 0==sqlite3Fts5IterEof(p->pIter) ){
- bHit = 1;
- }
- }
-
- if( bHit==0 ){
- pNode->bEof = 1;
- return SQLITE_OK;
- }
- }
- }
- }
-
- pNode->bEof = 0;
- return SQLITE_OK;
-}
-
-/*
-** If pExpr is an ASC iterator, this function returns a value with the
-** same sign as:
-**
-** (iLhs - iRhs)
-**
-** Otherwise, if this is a DESC iterator, the opposite is returned:
-**
-** (iRhs - iLhs)
-*/
-static int fts5RowidCmp(
- Fts5Expr *pExpr,
- i64 iLhs,
- i64 iRhs
-){
- assert( pExpr->bDesc==0 || pExpr->bDesc==1 );
- if( pExpr->bDesc==0 ){
- if( iLhs<iRhs ) return -1;
- return (iLhs > iRhs);
- }else{
- if( iLhs>iRhs ) return -1;
- return (iLhs < iRhs);
- }
-}
-
-static void fts5ExprSetEof(Fts5ExprNode *pNode){
- int i;
- pNode->bEof = 1;
- pNode->bNomatch = 0;
- for(i=0; i<pNode->nChild; i++){
- fts5ExprSetEof(pNode->apChild[i]);
- }
-}
-
-static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){
- if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
- Fts5ExprNearset *pNear = pNode->pNear;
- int i;
- for(i=0; i<pNear->nPhrase; i++){
- Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
- pPhrase->poslist.n = 0;
- }
- }else{
- int i;
- for(i=0; i<pNode->nChild; i++){
- fts5ExprNodeZeroPoslist(pNode->apChild[i]);
- }
- }
-}
-
-
-
-/*
-** Compare the values currently indicated by the two nodes as follows:
-**
-** res = (*p1) - (*p2)
-**
-** Nodes that point to values that come later in the iteration order are
-** considered to be larger. Nodes at EOF are the largest of all.
-**
-** This means that if the iteration order is ASC, then numerically larger
-** rowids are considered larger. Or if it is the default DESC, numerically
-** smaller rowids are larger.
-*/
-static int fts5NodeCompare(
- Fts5Expr *pExpr,
+ || pNear->pColset || pPhrase->aTerm[0].bFirst
+ ){
+ int bMatch = 0;
+ rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch);
+ if( bMatch==0 ) break;
+ }else{
+ Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
+ fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData);
+ }
+ }
+
+ *pRc = rc;
+ if( i==pNear->nPhrase && (i==1 || fts5ExprNearIsMatch(pRc, pNear)) ){
+ return 1;
+ }
+ return 0;
+ }
+}
+
+
+/*
+** Initialize all term iterators in the pNear object. If any term is found
+** to match no documents at all, return immediately without initializing any
+** further iterators.
+**
+** If an error occurs, return an SQLite error code. Otherwise, return
+** SQLITE_OK. It is not considered an error if some term matches zero
+** documents.
+*/
+static int fts5ExprNearInitAll(
+ Fts5Expr *pExpr,
+ Fts5ExprNode *pNode
+){
+ Fts5ExprNearset *pNear = pNode->pNear;
+ int i;
+
+ assert( pNode->bNomatch==0 );
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+ if( pPhrase->nTerm==0 ){
+ pNode->bEof = 1;
+ return SQLITE_OK;
+ }else{
+ int j;
+ for(j=0; j<pPhrase->nTerm; j++){
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
+ Fts5ExprTerm *p;
+ int bHit = 0;
+
+ for(p=pTerm; p; p=p->pSynonym){
+ int rc;
+ if( p->pIter ){
+ sqlite3Fts5IterClose(p->pIter);
+ p->pIter = 0;
+ }
+ rc = sqlite3Fts5IndexQuery(
+ pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
+ (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
+ (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
+ pNear->pColset,
+ &p->pIter
+ );
+ assert( (rc==SQLITE_OK)==(p->pIter!=0) );
+ if( rc!=SQLITE_OK ) return rc;
+ if( 0==sqlite3Fts5IterEof(p->pIter) ){
+ bHit = 1;
+ }
+ }
+
+ if( bHit==0 ){
+ pNode->bEof = 1;
+ return SQLITE_OK;
+ }
+ }
+ }
+ }
+
+ pNode->bEof = 0;
+ return SQLITE_OK;
+}
+
+/*
+** If pExpr is an ASC iterator, this function returns a value with the
+** same sign as:
+**
+** (iLhs - iRhs)
+**
+** Otherwise, if this is a DESC iterator, the opposite is returned:
+**
+** (iRhs - iLhs)
+*/
+static int fts5RowidCmp(
+ Fts5Expr *pExpr,
+ i64 iLhs,
+ i64 iRhs
+){
+ assert( pExpr->bDesc==0 || pExpr->bDesc==1 );
+ if( pExpr->bDesc==0 ){
+ if( iLhs<iRhs ) return -1;
+ return (iLhs > iRhs);
+ }else{
+ if( iLhs>iRhs ) return -1;
+ return (iLhs < iRhs);
+ }
+}
+
+static void fts5ExprSetEof(Fts5ExprNode *pNode){
+ int i;
+ pNode->bEof = 1;
+ pNode->bNomatch = 0;
+ for(i=0; i<pNode->nChild; i++){
+ fts5ExprSetEof(pNode->apChild[i]);
+ }
+}
+
+static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){
+ if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
+ Fts5ExprNearset *pNear = pNode->pNear;
+ int i;
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+ pPhrase->poslist.n = 0;
+ }
+ }else{
+ int i;
+ for(i=0; i<pNode->nChild; i++){
+ fts5ExprNodeZeroPoslist(pNode->apChild[i]);
+ }
+ }
+}
+
+
+
+/*
+** Compare the values currently indicated by the two nodes as follows:
+**
+** res = (*p1) - (*p2)
+**
+** Nodes that point to values that come later in the iteration order are
+** considered to be larger. Nodes at EOF are the largest of all.
+**
+** This means that if the iteration order is ASC, then numerically larger
+** rowids are considered larger. Or if it is the default DESC, numerically
+** smaller rowids are larger.
+*/
+static int fts5NodeCompare(
+ Fts5Expr *pExpr,
Fts5ExprNode *p1,
- Fts5ExprNode *p2
-){
- if( p2->bEof ) return -1;
- if( p1->bEof ) return +1;
- return fts5RowidCmp(pExpr, p1->iRowid, p2->iRowid);
-}
-
-/*
-** All individual term iterators in pNear are guaranteed to be valid when
-** this function is called. This function checks if all term iterators
-** point to the same rowid, and if not, advances them until they do.
-** If an EOF is reached before this happens, *pbEof is set to true before
-** returning.
-**
+ Fts5ExprNode *p2
+){
+ if( p2->bEof ) return -1;
+ if( p1->bEof ) return +1;
+ return fts5RowidCmp(pExpr, p1->iRowid, p2->iRowid);
+}
+
+/*
+** All individual term iterators in pNear are guaranteed to be valid when
+** this function is called. This function checks if all term iterators
+** point to the same rowid, and if not, advances them until they do.
+** If an EOF is reached before this happens, *pbEof is set to true before
+** returning.
+**
** SQLITE_OK is returned if an error occurs, or an SQLite error code
-** otherwise. It is not considered an error code if an iterator reaches
-** EOF.
-*/
-static int fts5ExprNodeTest_STRING(
- Fts5Expr *pExpr, /* Expression pPhrase belongs to */
- Fts5ExprNode *pNode
-){
- Fts5ExprNearset *pNear = pNode->pNear;
- Fts5ExprPhrase *pLeft = pNear->apPhrase[0];
- int rc = SQLITE_OK;
- i64 iLast; /* Lastest rowid any iterator points to */
- int i, j; /* Phrase and token index, respectively */
- int bMatch; /* True if all terms are at the same rowid */
- const int bDesc = pExpr->bDesc;
-
- /* Check that this node should not be FTS5_TERM */
+** otherwise. It is not considered an error code if an iterator reaches
+** EOF.
+*/
+static int fts5ExprNodeTest_STRING(
+ Fts5Expr *pExpr, /* Expression pPhrase belongs to */
+ Fts5ExprNode *pNode
+){
+ Fts5ExprNearset *pNear = pNode->pNear;
+ Fts5ExprPhrase *pLeft = pNear->apPhrase[0];
+ int rc = SQLITE_OK;
+ i64 iLast; /* Lastest rowid any iterator points to */
+ int i, j; /* Phrase and token index, respectively */
+ int bMatch; /* True if all terms are at the same rowid */
+ const int bDesc = pExpr->bDesc;
+
+ /* Check that this node should not be FTS5_TERM */
assert( pNear->nPhrase>1
|| pNear->apPhrase[0]->nTerm>1
- || pNear->apPhrase[0]->aTerm[0].pSynonym
- || pNear->apPhrase[0]->aTerm[0].bFirst
- );
-
- /* Initialize iLast, the "lastest" rowid any iterator points to. If the
- ** iterator skips through rowids in the default ascending order, this means
- ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it
- ** means the minimum rowid. */
- if( pLeft->aTerm[0].pSynonym ){
- iLast = fts5ExprSynonymRowid(&pLeft->aTerm[0], bDesc, 0);
- }else{
- iLast = pLeft->aTerm[0].pIter->iRowid;
- }
-
- do {
- bMatch = 1;
- for(i=0; i<pNear->nPhrase; i++){
- Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
- for(j=0; j<pPhrase->nTerm; j++){
- Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
- if( pTerm->pSynonym ){
- i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0);
- if( iRowid==iLast ) continue;
- bMatch = 0;
- if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){
- pNode->bNomatch = 0;
- pNode->bEof = 1;
- return rc;
- }
- }else{
- Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
- if( pIter->iRowid==iLast || pIter->bEof ) continue;
- bMatch = 0;
- if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
- return rc;
- }
- }
- }
- }
- }while( bMatch==0 );
-
- pNode->iRowid = iLast;
- pNode->bNomatch = ((0==fts5ExprNearTest(&rc, pExpr, pNode)) && rc==SQLITE_OK);
- assert( pNode->bEof==0 || pNode->bNomatch==0 );
-
- return rc;
-}
-
-/*
-** Advance the first term iterator in the first phrase of pNear. Set output
-** variable *pbEof to true if it reaches EOF or if an error occurs.
-**
-** Return SQLITE_OK if successful, or an SQLite error code if an error
-** occurs.
-*/
-static int fts5ExprNodeNext_STRING(
- Fts5Expr *pExpr, /* Expression pPhrase belongs to */
- Fts5ExprNode *pNode, /* FTS5_STRING or FTS5_TERM node */
- int bFromValid,
+ || pNear->apPhrase[0]->aTerm[0].pSynonym
+ || pNear->apPhrase[0]->aTerm[0].bFirst
+ );
+
+ /* Initialize iLast, the "lastest" rowid any iterator points to. If the
+ ** iterator skips through rowids in the default ascending order, this means
+ ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it
+ ** means the minimum rowid. */
+ if( pLeft->aTerm[0].pSynonym ){
+ iLast = fts5ExprSynonymRowid(&pLeft->aTerm[0], bDesc, 0);
+ }else{
+ iLast = pLeft->aTerm[0].pIter->iRowid;
+ }
+
+ do {
+ bMatch = 1;
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+ for(j=0; j<pPhrase->nTerm; j++){
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
+ if( pTerm->pSynonym ){
+ i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0);
+ if( iRowid==iLast ) continue;
+ bMatch = 0;
+ if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){
+ pNode->bNomatch = 0;
+ pNode->bEof = 1;
+ return rc;
+ }
+ }else{
+ Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
+ if( pIter->iRowid==iLast || pIter->bEof ) continue;
+ bMatch = 0;
+ if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
+ return rc;
+ }
+ }
+ }
+ }
+ }while( bMatch==0 );
+
+ pNode->iRowid = iLast;
+ pNode->bNomatch = ((0==fts5ExprNearTest(&rc, pExpr, pNode)) && rc==SQLITE_OK);
+ assert( pNode->bEof==0 || pNode->bNomatch==0 );
+
+ return rc;
+}
+
+/*
+** Advance the first term iterator in the first phrase of pNear. Set output
+** variable *pbEof to true if it reaches EOF or if an error occurs.
+**
+** Return SQLITE_OK if successful, or an SQLite error code if an error
+** occurs.
+*/
+static int fts5ExprNodeNext_STRING(
+ Fts5Expr *pExpr, /* Expression pPhrase belongs to */
+ Fts5ExprNode *pNode, /* FTS5_STRING or FTS5_TERM node */
+ int bFromValid,
i64 iFrom
-){
- Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0];
- int rc = SQLITE_OK;
-
- pNode->bNomatch = 0;
- if( pTerm->pSynonym ){
- int bEof = 1;
- Fts5ExprTerm *p;
-
- /* Find the firstest rowid any synonym points to. */
- i64 iRowid = fts5ExprSynonymRowid(pTerm, pExpr->bDesc, 0);
-
- /* Advance each iterator that currently points to iRowid. Or, if iFrom
- ** is valid - each iterator that points to a rowid before iFrom. */
- for(p=pTerm; p; p=p->pSynonym){
- if( sqlite3Fts5IterEof(p->pIter)==0 ){
- i64 ii = p->pIter->iRowid;
+){
+ Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0];
+ int rc = SQLITE_OK;
+
+ pNode->bNomatch = 0;
+ if( pTerm->pSynonym ){
+ int bEof = 1;
+ Fts5ExprTerm *p;
+
+ /* Find the firstest rowid any synonym points to. */
+ i64 iRowid = fts5ExprSynonymRowid(pTerm, pExpr->bDesc, 0);
+
+ /* Advance each iterator that currently points to iRowid. Or, if iFrom
+ ** is valid - each iterator that points to a rowid before iFrom. */
+ for(p=pTerm; p; p=p->pSynonym){
+ if( sqlite3Fts5IterEof(p->pIter)==0 ){
+ i64 ii = p->pIter->iRowid;
if( ii==iRowid
|| (bFromValid && ii!=iFrom && (ii>iFrom)==pExpr->bDesc)
- ){
- if( bFromValid ){
- rc = sqlite3Fts5IterNextFrom(p->pIter, iFrom);
- }else{
- rc = sqlite3Fts5IterNext(p->pIter);
- }
- if( rc!=SQLITE_OK ) break;
- if( sqlite3Fts5IterEof(p->pIter)==0 ){
- bEof = 0;
- }
- }else{
- bEof = 0;
- }
- }
- }
-
- /* Set the EOF flag if either all synonym iterators are at EOF or an
- ** error has occurred. */
- pNode->bEof = (rc || bEof);
- }else{
- Fts5IndexIter *pIter = pTerm->pIter;
-
- assert( Fts5NodeIsString(pNode) );
- if( bFromValid ){
- rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
- }else{
- rc = sqlite3Fts5IterNext(pIter);
- }
-
- pNode->bEof = (rc || sqlite3Fts5IterEof(pIter));
- }
-
- if( pNode->bEof==0 ){
- assert( rc==SQLITE_OK );
- rc = fts5ExprNodeTest_STRING(pExpr, pNode);
- }
-
- return rc;
-}
-
-
-static int fts5ExprNodeTest_TERM(
- Fts5Expr *pExpr, /* Expression that pNear is a part of */
- Fts5ExprNode *pNode /* The "NEAR" node (FTS5_TERM) */
-){
+ ){
+ if( bFromValid ){
+ rc = sqlite3Fts5IterNextFrom(p->pIter, iFrom);
+ }else{
+ rc = sqlite3Fts5IterNext(p->pIter);
+ }
+ if( rc!=SQLITE_OK ) break;
+ if( sqlite3Fts5IterEof(p->pIter)==0 ){
+ bEof = 0;
+ }
+ }else{
+ bEof = 0;
+ }
+ }
+ }
+
+ /* Set the EOF flag if either all synonym iterators are at EOF or an
+ ** error has occurred. */
+ pNode->bEof = (rc || bEof);
+ }else{
+ Fts5IndexIter *pIter = pTerm->pIter;
+
+ assert( Fts5NodeIsString(pNode) );
+ if( bFromValid ){
+ rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
+ }else{
+ rc = sqlite3Fts5IterNext(pIter);
+ }
+
+ pNode->bEof = (rc || sqlite3Fts5IterEof(pIter));
+ }
+
+ if( pNode->bEof==0 ){
+ assert( rc==SQLITE_OK );
+ rc = fts5ExprNodeTest_STRING(pExpr, pNode);
+ }
+
+ return rc;
+}
+
+
+static int fts5ExprNodeTest_TERM(
+ Fts5Expr *pExpr, /* Expression that pNear is a part of */
+ Fts5ExprNode *pNode /* The "NEAR" node (FTS5_TERM) */
+){
/* As this "NEAR" object is actually a single phrase that consists
- ** of a single term only, grab pointers into the poslist managed by the
+ ** of a single term only, grab pointers into the poslist managed by the
** fts5_index.c iterator object. This is much faster than synthesizing
- ** a new poslist the way we have to for more complicated phrase or NEAR
- ** expressions. */
- Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0];
- Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
-
- assert( pNode->eType==FTS5_TERM );
- assert( pNode->pNear->nPhrase==1 && pPhrase->nTerm==1 );
- assert( pPhrase->aTerm[0].pSynonym==0 );
-
- pPhrase->poslist.n = pIter->nData;
- if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){
- pPhrase->poslist.p = (u8*)pIter->pData;
- }
- pNode->iRowid = pIter->iRowid;
- pNode->bNomatch = (pPhrase->poslist.n==0);
- return SQLITE_OK;
-}
-
-/*
-** xNext() method for a node of type FTS5_TERM.
-*/
-static int fts5ExprNodeNext_TERM(
+ ** a new poslist the way we have to for more complicated phrase or NEAR
+ ** expressions. */
+ Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0];
+ Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
+
+ assert( pNode->eType==FTS5_TERM );
+ assert( pNode->pNear->nPhrase==1 && pPhrase->nTerm==1 );
+ assert( pPhrase->aTerm[0].pSynonym==0 );
+
+ pPhrase->poslist.n = pIter->nData;
+ if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){
+ pPhrase->poslist.p = (u8*)pIter->pData;
+ }
+ pNode->iRowid = pIter->iRowid;
+ pNode->bNomatch = (pPhrase->poslist.n==0);
+ return SQLITE_OK;
+}
+
+/*
+** xNext() method for a node of type FTS5_TERM.
+*/
+static int fts5ExprNodeNext_TERM(
Fts5Expr *pExpr,
- Fts5ExprNode *pNode,
- int bFromValid,
- i64 iFrom
-){
- int rc;
- Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter;
-
- assert( pNode->bEof==0 );
- if( bFromValid ){
- rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
- }else{
- rc = sqlite3Fts5IterNext(pIter);
- }
- if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){
- rc = fts5ExprNodeTest_TERM(pExpr, pNode);
- }else{
- pNode->bEof = 1;
- pNode->bNomatch = 0;
- }
- return rc;
-}
-
-static void fts5ExprNodeTest_OR(
- Fts5Expr *pExpr, /* Expression of which pNode is a part */
- Fts5ExprNode *pNode /* Expression node to test */
-){
- Fts5ExprNode *pNext = pNode->apChild[0];
- int i;
-
- for(i=1; i<pNode->nChild; i++){
- Fts5ExprNode *pChild = pNode->apChild[i];
- int cmp = fts5NodeCompare(pExpr, pNext, pChild);
- if( cmp>0 || (cmp==0 && pChild->bNomatch==0) ){
- pNext = pChild;
- }
- }
- pNode->iRowid = pNext->iRowid;
- pNode->bEof = pNext->bEof;
- pNode->bNomatch = pNext->bNomatch;
-}
-
-static int fts5ExprNodeNext_OR(
+ Fts5ExprNode *pNode,
+ int bFromValid,
+ i64 iFrom
+){
+ int rc;
+ Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter;
+
+ assert( pNode->bEof==0 );
+ if( bFromValid ){
+ rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
+ }else{
+ rc = sqlite3Fts5IterNext(pIter);
+ }
+ if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){
+ rc = fts5ExprNodeTest_TERM(pExpr, pNode);
+ }else{
+ pNode->bEof = 1;
+ pNode->bNomatch = 0;
+ }
+ return rc;
+}
+
+static void fts5ExprNodeTest_OR(
+ Fts5Expr *pExpr, /* Expression of which pNode is a part */
+ Fts5ExprNode *pNode /* Expression node to test */
+){
+ Fts5ExprNode *pNext = pNode->apChild[0];
+ int i;
+
+ for(i=1; i<pNode->nChild; i++){
+ Fts5ExprNode *pChild = pNode->apChild[i];
+ int cmp = fts5NodeCompare(pExpr, pNext, pChild);
+ if( cmp>0 || (cmp==0 && pChild->bNomatch==0) ){
+ pNext = pChild;
+ }
+ }
+ pNode->iRowid = pNext->iRowid;
+ pNode->bEof = pNext->bEof;
+ pNode->bNomatch = pNext->bNomatch;
+}
+
+static int fts5ExprNodeNext_OR(
Fts5Expr *pExpr,
- Fts5ExprNode *pNode,
- int bFromValid,
- i64 iFrom
-){
- int i;
- i64 iLast = pNode->iRowid;
-
- for(i=0; i<pNode->nChild; i++){
- Fts5ExprNode *p1 = pNode->apChild[i];
- assert( p1->bEof || fts5RowidCmp(pExpr, p1->iRowid, iLast)>=0 );
- if( p1->bEof==0 ){
+ Fts5ExprNode *pNode,
+ int bFromValid,
+ i64 iFrom
+){
+ int i;
+ i64 iLast = pNode->iRowid;
+
+ for(i=0; i<pNode->nChild; i++){
+ Fts5ExprNode *p1 = pNode->apChild[i];
+ assert( p1->bEof || fts5RowidCmp(pExpr, p1->iRowid, iLast)>=0 );
+ if( p1->bEof==0 ){
if( (p1->iRowid==iLast)
- || (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
- ){
- int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
- if( rc!=SQLITE_OK ){
- pNode->bNomatch = 0;
- return rc;
- }
- }
- }
- }
-
- fts5ExprNodeTest_OR(pExpr, pNode);
- return SQLITE_OK;
-}
-
-/*
-** Argument pNode is an FTS5_AND node.
-*/
-static int fts5ExprNodeTest_AND(
- Fts5Expr *pExpr, /* Expression pPhrase belongs to */
- Fts5ExprNode *pAnd /* FTS5_AND node to advance */
-){
- int iChild;
- i64 iLast = pAnd->iRowid;
- int rc = SQLITE_OK;
- int bMatch;
-
- assert( pAnd->bEof==0 );
- do {
- pAnd->bNomatch = 0;
- bMatch = 1;
- for(iChild=0; iChild<pAnd->nChild; iChild++){
- Fts5ExprNode *pChild = pAnd->apChild[iChild];
- int cmp = fts5RowidCmp(pExpr, iLast, pChild->iRowid);
- if( cmp>0 ){
- /* Advance pChild until it points to iLast or laster */
- rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
- if( rc!=SQLITE_OK ){
- pAnd->bNomatch = 0;
- return rc;
- }
- }
-
- /* If the child node is now at EOF, so is the parent AND node. Otherwise,
- ** the child node is guaranteed to have advanced at least as far as
- ** rowid iLast. So if it is not at exactly iLast, pChild->iRowid is the
- ** new lastest rowid seen so far. */
- assert( pChild->bEof || fts5RowidCmp(pExpr, iLast, pChild->iRowid)<=0 );
- if( pChild->bEof ){
- fts5ExprSetEof(pAnd);
- bMatch = 1;
- break;
- }else if( iLast!=pChild->iRowid ){
- bMatch = 0;
- iLast = pChild->iRowid;
- }
-
- if( pChild->bNomatch ){
- pAnd->bNomatch = 1;
- }
- }
- }while( bMatch==0 );
-
- if( pAnd->bNomatch && pAnd!=pExpr->pRoot ){
- fts5ExprNodeZeroPoslist(pAnd);
- }
- pAnd->iRowid = iLast;
- return SQLITE_OK;
-}
-
-static int fts5ExprNodeNext_AND(
+ || (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
+ ){
+ int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
+ if( rc!=SQLITE_OK ){
+ pNode->bNomatch = 0;
+ return rc;
+ }
+ }
+ }
+ }
+
+ fts5ExprNodeTest_OR(pExpr, pNode);
+ return SQLITE_OK;
+}
+
+/*
+** Argument pNode is an FTS5_AND node.
+*/
+static int fts5ExprNodeTest_AND(
+ Fts5Expr *pExpr, /* Expression pPhrase belongs to */
+ Fts5ExprNode *pAnd /* FTS5_AND node to advance */
+){
+ int iChild;
+ i64 iLast = pAnd->iRowid;
+ int rc = SQLITE_OK;
+ int bMatch;
+
+ assert( pAnd->bEof==0 );
+ do {
+ pAnd->bNomatch = 0;
+ bMatch = 1;
+ for(iChild=0; iChild<pAnd->nChild; iChild++){
+ Fts5ExprNode *pChild = pAnd->apChild[iChild];
+ int cmp = fts5RowidCmp(pExpr, iLast, pChild->iRowid);
+ if( cmp>0 ){
+ /* Advance pChild until it points to iLast or laster */
+ rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
+ if( rc!=SQLITE_OK ){
+ pAnd->bNomatch = 0;
+ return rc;
+ }
+ }
+
+ /* If the child node is now at EOF, so is the parent AND node. Otherwise,
+ ** the child node is guaranteed to have advanced at least as far as
+ ** rowid iLast. So if it is not at exactly iLast, pChild->iRowid is the
+ ** new lastest rowid seen so far. */
+ assert( pChild->bEof || fts5RowidCmp(pExpr, iLast, pChild->iRowid)<=0 );
+ if( pChild->bEof ){
+ fts5ExprSetEof(pAnd);
+ bMatch = 1;
+ break;
+ }else if( iLast!=pChild->iRowid ){
+ bMatch = 0;
+ iLast = pChild->iRowid;
+ }
+
+ if( pChild->bNomatch ){
+ pAnd->bNomatch = 1;
+ }
+ }
+ }while( bMatch==0 );
+
+ if( pAnd->bNomatch && pAnd!=pExpr->pRoot ){
+ fts5ExprNodeZeroPoslist(pAnd);
+ }
+ pAnd->iRowid = iLast;
+ return SQLITE_OK;
+}
+
+static int fts5ExprNodeNext_AND(
Fts5Expr *pExpr,
- Fts5ExprNode *pNode,
- int bFromValid,
- i64 iFrom
-){
- int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
- if( rc==SQLITE_OK ){
- rc = fts5ExprNodeTest_AND(pExpr, pNode);
- }else{
- pNode->bNomatch = 0;
- }
- return rc;
-}
-
-static int fts5ExprNodeTest_NOT(
- Fts5Expr *pExpr, /* Expression pPhrase belongs to */
- Fts5ExprNode *pNode /* FTS5_NOT node to advance */
-){
- int rc = SQLITE_OK;
- Fts5ExprNode *p1 = pNode->apChild[0];
- Fts5ExprNode *p2 = pNode->apChild[1];
- assert( pNode->nChild==2 );
-
- while( rc==SQLITE_OK && p1->bEof==0 ){
- int cmp = fts5NodeCompare(pExpr, p1, p2);
- if( cmp>0 ){
- rc = fts5ExprNodeNext(pExpr, p2, 1, p1->iRowid);
- cmp = fts5NodeCompare(pExpr, p1, p2);
- }
- assert( rc!=SQLITE_OK || cmp<=0 );
- if( cmp || p2->bNomatch ) break;
- rc = fts5ExprNodeNext(pExpr, p1, 0, 0);
- }
- pNode->bEof = p1->bEof;
- pNode->bNomatch = p1->bNomatch;
- pNode->iRowid = p1->iRowid;
- if( p1->bEof ){
- fts5ExprNodeZeroPoslist(p2);
- }
- return rc;
-}
-
-static int fts5ExprNodeNext_NOT(
+ Fts5ExprNode *pNode,
+ int bFromValid,
+ i64 iFrom
+){
+ int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
+ if( rc==SQLITE_OK ){
+ rc = fts5ExprNodeTest_AND(pExpr, pNode);
+ }else{
+ pNode->bNomatch = 0;
+ }
+ return rc;
+}
+
+static int fts5ExprNodeTest_NOT(
+ Fts5Expr *pExpr, /* Expression pPhrase belongs to */
+ Fts5ExprNode *pNode /* FTS5_NOT node to advance */
+){
+ int rc = SQLITE_OK;
+ Fts5ExprNode *p1 = pNode->apChild[0];
+ Fts5ExprNode *p2 = pNode->apChild[1];
+ assert( pNode->nChild==2 );
+
+ while( rc==SQLITE_OK && p1->bEof==0 ){
+ int cmp = fts5NodeCompare(pExpr, p1, p2);
+ if( cmp>0 ){
+ rc = fts5ExprNodeNext(pExpr, p2, 1, p1->iRowid);
+ cmp = fts5NodeCompare(pExpr, p1, p2);
+ }
+ assert( rc!=SQLITE_OK || cmp<=0 );
+ if( cmp || p2->bNomatch ) break;
+ rc = fts5ExprNodeNext(pExpr, p1, 0, 0);
+ }
+ pNode->bEof = p1->bEof;
+ pNode->bNomatch = p1->bNomatch;
+ pNode->iRowid = p1->iRowid;
+ if( p1->bEof ){
+ fts5ExprNodeZeroPoslist(p2);
+ }
+ return rc;
+}
+
+static int fts5ExprNodeNext_NOT(
Fts5Expr *pExpr,
- Fts5ExprNode *pNode,
- int bFromValid,
- i64 iFrom
-){
- int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
- if( rc==SQLITE_OK ){
- rc = fts5ExprNodeTest_NOT(pExpr, pNode);
- }
- if( rc!=SQLITE_OK ){
- pNode->bNomatch = 0;
- }
- return rc;
-}
-
-/*
-** If pNode currently points to a match, this function returns SQLITE_OK
-** without modifying it. Otherwise, pNode is advanced until it does point
-** to a match or EOF is reached.
-*/
-static int fts5ExprNodeTest(
- Fts5Expr *pExpr, /* Expression of which pNode is a part */
- Fts5ExprNode *pNode /* Expression node to test */
-){
- int rc = SQLITE_OK;
- if( pNode->bEof==0 ){
- switch( pNode->eType ){
-
- case FTS5_STRING: {
- rc = fts5ExprNodeTest_STRING(pExpr, pNode);
- break;
- }
-
- case FTS5_TERM: {
- rc = fts5ExprNodeTest_TERM(pExpr, pNode);
- break;
- }
-
- case FTS5_AND: {
- rc = fts5ExprNodeTest_AND(pExpr, pNode);
- break;
- }
-
- case FTS5_OR: {
- fts5ExprNodeTest_OR(pExpr, pNode);
- break;
- }
-
- default: assert( pNode->eType==FTS5_NOT ); {
- rc = fts5ExprNodeTest_NOT(pExpr, pNode);
- break;
- }
- }
- }
- return rc;
-}
-
-
-/*
-** Set node pNode, which is part of expression pExpr, to point to the first
-** match. If there are no matches, set the Node.bEof flag to indicate EOF.
-**
-** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
-** It is not an error if there are no matches.
-*/
-static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
- int rc = SQLITE_OK;
- pNode->bEof = 0;
- pNode->bNomatch = 0;
-
- if( Fts5NodeIsString(pNode) ){
- /* Initialize all term iterators in the NEAR object. */
- rc = fts5ExprNearInitAll(pExpr, pNode);
- }else if( pNode->xNext==0 ){
- pNode->bEof = 1;
- }else{
- int i;
- int nEof = 0;
- for(i=0; i<pNode->nChild && rc==SQLITE_OK; i++){
- Fts5ExprNode *pChild = pNode->apChild[i];
- rc = fts5ExprNodeFirst(pExpr, pNode->apChild[i]);
- assert( pChild->bEof==0 || pChild->bEof==1 );
- nEof += pChild->bEof;
- }
- pNode->iRowid = pNode->apChild[0]->iRowid;
-
- switch( pNode->eType ){
- case FTS5_AND:
- if( nEof>0 ) fts5ExprSetEof(pNode);
- break;
-
- case FTS5_OR:
- if( pNode->nChild==nEof ) fts5ExprSetEof(pNode);
- break;
-
- default:
- assert( pNode->eType==FTS5_NOT );
- pNode->bEof = pNode->apChild[0]->bEof;
- break;
- }
- }
-
- if( rc==SQLITE_OK ){
- rc = fts5ExprNodeTest(pExpr, pNode);
- }
- return rc;
-}
-
-
-/*
-** Begin iterating through the set of documents in index pIdx matched by
+ Fts5ExprNode *pNode,
+ int bFromValid,
+ i64 iFrom
+){
+ int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
+ if( rc==SQLITE_OK ){
+ rc = fts5ExprNodeTest_NOT(pExpr, pNode);
+ }
+ if( rc!=SQLITE_OK ){
+ pNode->bNomatch = 0;
+ }
+ return rc;
+}
+
+/*
+** If pNode currently points to a match, this function returns SQLITE_OK
+** without modifying it. Otherwise, pNode is advanced until it does point
+** to a match or EOF is reached.
+*/
+static int fts5ExprNodeTest(
+ Fts5Expr *pExpr, /* Expression of which pNode is a part */
+ Fts5ExprNode *pNode /* Expression node to test */
+){
+ int rc = SQLITE_OK;
+ if( pNode->bEof==0 ){
+ switch( pNode->eType ){
+
+ case FTS5_STRING: {
+ rc = fts5ExprNodeTest_STRING(pExpr, pNode);
+ break;
+ }
+
+ case FTS5_TERM: {
+ rc = fts5ExprNodeTest_TERM(pExpr, pNode);
+ break;
+ }
+
+ case FTS5_AND: {
+ rc = fts5ExprNodeTest_AND(pExpr, pNode);
+ break;
+ }
+
+ case FTS5_OR: {
+ fts5ExprNodeTest_OR(pExpr, pNode);
+ break;
+ }
+
+ default: assert( pNode->eType==FTS5_NOT ); {
+ rc = fts5ExprNodeTest_NOT(pExpr, pNode);
+ break;
+ }
+ }
+ }
+ return rc;
+}
+
+
+/*
+** Set node pNode, which is part of expression pExpr, to point to the first
+** match. If there are no matches, set the Node.bEof flag to indicate EOF.
+**
+** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
+** It is not an error if there are no matches.
+*/
+static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
+ int rc = SQLITE_OK;
+ pNode->bEof = 0;
+ pNode->bNomatch = 0;
+
+ if( Fts5NodeIsString(pNode) ){
+ /* Initialize all term iterators in the NEAR object. */
+ rc = fts5ExprNearInitAll(pExpr, pNode);
+ }else if( pNode->xNext==0 ){
+ pNode->bEof = 1;
+ }else{
+ int i;
+ int nEof = 0;
+ for(i=0; i<pNode->nChild && rc==SQLITE_OK; i++){
+ Fts5ExprNode *pChild = pNode->apChild[i];
+ rc = fts5ExprNodeFirst(pExpr, pNode->apChild[i]);
+ assert( pChild->bEof==0 || pChild->bEof==1 );
+ nEof += pChild->bEof;
+ }
+ pNode->iRowid = pNode->apChild[0]->iRowid;
+
+ switch( pNode->eType ){
+ case FTS5_AND:
+ if( nEof>0 ) fts5ExprSetEof(pNode);
+ break;
+
+ case FTS5_OR:
+ if( pNode->nChild==nEof ) fts5ExprSetEof(pNode);
+ break;
+
+ default:
+ assert( pNode->eType==FTS5_NOT );
+ pNode->bEof = pNode->apChild[0]->bEof;
+ break;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = fts5ExprNodeTest(pExpr, pNode);
+ }
+ return rc;
+}
+
+
+/*
+** Begin iterating through the set of documents in index pIdx matched by
** the MATCH expression passed as the first argument. If the "bDesc"
** parameter is passed a non-zero value, iteration is in descending rowid
-** order. Or, if it is zero, in ascending order.
-**
-** If iterating in ascending rowid order (bDesc==0), the first document
-** visited is that with the smallest rowid that is larger than or equal
-** to parameter iFirst. Or, if iterating in ascending order (bDesc==1),
-** then the first document visited must have a rowid smaller than or
-** equal to iFirst.
-**
-** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
-** is not considered an error if the query does not match any documents.
-*/
-static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
- Fts5ExprNode *pRoot = p->pRoot;
- int rc; /* Return code */
-
- p->pIndex = pIdx;
- p->bDesc = bDesc;
- rc = fts5ExprNodeFirst(p, pRoot);
-
- /* If not at EOF but the current rowid occurs earlier than iFirst in
- ** the iteration order, move to document iFirst or later. */
+** order. Or, if it is zero, in ascending order.
+**
+** If iterating in ascending rowid order (bDesc==0), the first document
+** visited is that with the smallest rowid that is larger than or equal
+** to parameter iFirst. Or, if iterating in ascending order (bDesc==1),
+** then the first document visited must have a rowid smaller than or
+** equal to iFirst.
+**
+** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
+** is not considered an error if the query does not match any documents.
+*/
+static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
+ Fts5ExprNode *pRoot = p->pRoot;
+ int rc; /* Return code */
+
+ p->pIndex = pIdx;
+ p->bDesc = bDesc;
+ rc = fts5ExprNodeFirst(p, pRoot);
+
+ /* If not at EOF but the current rowid occurs earlier than iFirst in
+ ** the iteration order, move to document iFirst or later. */
if( rc==SQLITE_OK
&& 0==pRoot->bEof
&& fts5RowidCmp(p, pRoot->iRowid, iFirst)<0
- ){
- rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
- }
-
- /* If the iterator is not at a real match, skip forward until it is. */
+ ){
+ rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
+ }
+
+ /* If the iterator is not at a real match, skip forward until it is. */
while( pRoot->bNomatch && rc==SQLITE_OK ){
assert( pRoot->bEof==0 );
- rc = fts5ExprNodeNext(p, pRoot, 0, 0);
- }
- return rc;
-}
-
-/*
+ rc = fts5ExprNodeNext(p, pRoot, 0, 0);
+ }
+ return rc;
+}
+
+/*
** Move to the next document
-**
-** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
-** is not considered an error if the query does not match any documents.
-*/
-static int sqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){
- int rc;
- Fts5ExprNode *pRoot = p->pRoot;
- assert( pRoot->bEof==0 && pRoot->bNomatch==0 );
- do {
- rc = fts5ExprNodeNext(p, pRoot, 0, 0);
- assert( pRoot->bNomatch==0 || (rc==SQLITE_OK && pRoot->bEof==0) );
- }while( pRoot->bNomatch );
- if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){
- pRoot->bEof = 1;
- }
- return rc;
-}
-
-static int sqlite3Fts5ExprEof(Fts5Expr *p){
- return p->pRoot->bEof;
-}
-
-static i64 sqlite3Fts5ExprRowid(Fts5Expr *p){
- return p->pRoot->iRowid;
-}
-
-static int fts5ParseStringFromToken(Fts5Token *pToken, char **pz){
- int rc = SQLITE_OK;
- *pz = sqlite3Fts5Strndup(&rc, pToken->p, pToken->n);
- return rc;
-}
-
-/*
-** Free the phrase object passed as the only argument.
-*/
-static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){
- if( pPhrase ){
- int i;
- for(i=0; i<pPhrase->nTerm; i++){
- Fts5ExprTerm *pSyn;
- Fts5ExprTerm *pNext;
- Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
- sqlite3_free(pTerm->zTerm);
- sqlite3Fts5IterClose(pTerm->pIter);
- for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
- pNext = pSyn->pSynonym;
- sqlite3Fts5IterClose(pSyn->pIter);
- fts5BufferFree((Fts5Buffer*)&pSyn[1]);
- sqlite3_free(pSyn);
- }
- }
- if( pPhrase->poslist.nSpace>0 ) fts5BufferFree(&pPhrase->poslist);
- sqlite3_free(pPhrase);
- }
-}
-
-/*
-** Set the "bFirst" flag on the first token of the phrase passed as the
-** only argument.
-*/
-static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){
- if( pPhrase && pPhrase->nTerm ){
- pPhrase->aTerm[0].bFirst = 1;
- }
-}
-
-/*
-** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated
-** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is
-** appended to it and the results returned.
-**
-** If an OOM error occurs, both the pNear and pPhrase objects are freed and
-** NULL returned.
-*/
-static Fts5ExprNearset *sqlite3Fts5ParseNearset(
- Fts5Parse *pParse, /* Parse context */
- Fts5ExprNearset *pNear, /* Existing nearset, or NULL */
- Fts5ExprPhrase *pPhrase /* Recently parsed phrase */
-){
- const int SZALLOC = 8;
- Fts5ExprNearset *pRet = 0;
-
- if( pParse->rc==SQLITE_OK ){
- if( pPhrase==0 ){
- return pNear;
- }
- if( pNear==0 ){
+**
+** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
+** is not considered an error if the query does not match any documents.
+*/
+static int sqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){
+ int rc;
+ Fts5ExprNode *pRoot = p->pRoot;
+ assert( pRoot->bEof==0 && pRoot->bNomatch==0 );
+ do {
+ rc = fts5ExprNodeNext(p, pRoot, 0, 0);
+ assert( pRoot->bNomatch==0 || (rc==SQLITE_OK && pRoot->bEof==0) );
+ }while( pRoot->bNomatch );
+ if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){
+ pRoot->bEof = 1;
+ }
+ return rc;
+}
+
+static int sqlite3Fts5ExprEof(Fts5Expr *p){
+ return p->pRoot->bEof;
+}
+
+static i64 sqlite3Fts5ExprRowid(Fts5Expr *p){
+ return p->pRoot->iRowid;
+}
+
+static int fts5ParseStringFromToken(Fts5Token *pToken, char **pz){
+ int rc = SQLITE_OK;
+ *pz = sqlite3Fts5Strndup(&rc, pToken->p, pToken->n);
+ return rc;
+}
+
+/*
+** Free the phrase object passed as the only argument.
+*/
+static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){
+ if( pPhrase ){
+ int i;
+ for(i=0; i<pPhrase->nTerm; i++){
+ Fts5ExprTerm *pSyn;
+ Fts5ExprTerm *pNext;
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
+ sqlite3_free(pTerm->zTerm);
+ sqlite3Fts5IterClose(pTerm->pIter);
+ for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
+ pNext = pSyn->pSynonym;
+ sqlite3Fts5IterClose(pSyn->pIter);
+ fts5BufferFree((Fts5Buffer*)&pSyn[1]);
+ sqlite3_free(pSyn);
+ }
+ }
+ if( pPhrase->poslist.nSpace>0 ) fts5BufferFree(&pPhrase->poslist);
+ sqlite3_free(pPhrase);
+ }
+}
+
+/*
+** Set the "bFirst" flag on the first token of the phrase passed as the
+** only argument.
+*/
+static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){
+ if( pPhrase && pPhrase->nTerm ){
+ pPhrase->aTerm[0].bFirst = 1;
+ }
+}
+
+/*
+** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated
+** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is
+** appended to it and the results returned.
+**
+** If an OOM error occurs, both the pNear and pPhrase objects are freed and
+** NULL returned.
+*/
+static Fts5ExprNearset *sqlite3Fts5ParseNearset(
+ Fts5Parse *pParse, /* Parse context */
+ Fts5ExprNearset *pNear, /* Existing nearset, or NULL */
+ Fts5ExprPhrase *pPhrase /* Recently parsed phrase */
+){
+ const int SZALLOC = 8;
+ Fts5ExprNearset *pRet = 0;
+
+ if( pParse->rc==SQLITE_OK ){
+ if( pPhrase==0 ){
+ return pNear;
+ }
+ if( pNear==0 ){
sqlite3_int64 nByte;
nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
pRet = sqlite3_malloc64(nByte);
- if( pRet==0 ){
- pParse->rc = SQLITE_NOMEM;
- }else{
+ if( pRet==0 ){
+ pParse->rc = SQLITE_NOMEM;
+ }else{
memset(pRet, 0, (size_t)nByte);
- }
- }else if( (pNear->nPhrase % SZALLOC)==0 ){
- int nNew = pNear->nPhrase + SZALLOC;
+ }
+ }else if( (pNear->nPhrase % SZALLOC)==0 ){
+ int nNew = pNear->nPhrase + SZALLOC;
sqlite3_int64 nByte;
-
+
nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte);
- if( pRet==0 ){
- pParse->rc = SQLITE_NOMEM;
- }
- }else{
- pRet = pNear;
- }
- }
-
- if( pRet==0 ){
- assert( pParse->rc!=SQLITE_OK );
- sqlite3Fts5ParseNearsetFree(pNear);
- sqlite3Fts5ParsePhraseFree(pPhrase);
- }else{
- if( pRet->nPhrase>0 ){
- Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
- assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
- if( pPhrase->nTerm==0 ){
- fts5ExprPhraseFree(pPhrase);
- pRet->nPhrase--;
- pParse->nPhrase--;
- pPhrase = pLast;
- }else if( pLast->nTerm==0 ){
- fts5ExprPhraseFree(pLast);
- pParse->apPhrase[pParse->nPhrase-2] = pPhrase;
- pParse->nPhrase--;
- pRet->nPhrase--;
- }
- }
- pRet->apPhrase[pRet->nPhrase++] = pPhrase;
- }
- return pRet;
-}
-
-typedef struct TokenCtx TokenCtx;
-struct TokenCtx {
- Fts5ExprPhrase *pPhrase;
- int rc;
-};
-
-/*
-** Callback for tokenizing terms used by ParseTerm().
-*/
-static int fts5ParseTokenize(
- void *pContext, /* Pointer to Fts5InsertCtx object */
- int tflags, /* Mask of FTS5_TOKEN_* flags */
- const char *pToken, /* Buffer containing token */
- int nToken, /* Size of token in bytes */
- int iUnused1, /* Start offset of token */
- int iUnused2 /* End offset of token */
-){
- int rc = SQLITE_OK;
- const int SZALLOC = 8;
- TokenCtx *pCtx = (TokenCtx*)pContext;
- Fts5ExprPhrase *pPhrase = pCtx->pPhrase;
-
- UNUSED_PARAM2(iUnused1, iUnused2);
-
- /* If an error has already occurred, this is a no-op */
- if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
- if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
-
- if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){
- Fts5ExprTerm *pSyn;
+ if( pRet==0 ){
+ pParse->rc = SQLITE_NOMEM;
+ }
+ }else{
+ pRet = pNear;
+ }
+ }
+
+ if( pRet==0 ){
+ assert( pParse->rc!=SQLITE_OK );
+ sqlite3Fts5ParseNearsetFree(pNear);
+ sqlite3Fts5ParsePhraseFree(pPhrase);
+ }else{
+ if( pRet->nPhrase>0 ){
+ Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
+ assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
+ if( pPhrase->nTerm==0 ){
+ fts5ExprPhraseFree(pPhrase);
+ pRet->nPhrase--;
+ pParse->nPhrase--;
+ pPhrase = pLast;
+ }else if( pLast->nTerm==0 ){
+ fts5ExprPhraseFree(pLast);
+ pParse->apPhrase[pParse->nPhrase-2] = pPhrase;
+ pParse->nPhrase--;
+ pRet->nPhrase--;
+ }
+ }
+ pRet->apPhrase[pRet->nPhrase++] = pPhrase;
+ }
+ return pRet;
+}
+
+typedef struct TokenCtx TokenCtx;
+struct TokenCtx {
+ Fts5ExprPhrase *pPhrase;
+ int rc;
+};
+
+/*
+** Callback for tokenizing terms used by ParseTerm().
+*/
+static int fts5ParseTokenize(
+ void *pContext, /* Pointer to Fts5InsertCtx object */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iUnused1, /* Start offset of token */
+ int iUnused2 /* End offset of token */
+){
+ int rc = SQLITE_OK;
+ const int SZALLOC = 8;
+ TokenCtx *pCtx = (TokenCtx*)pContext;
+ Fts5ExprPhrase *pPhrase = pCtx->pPhrase;
+
+ UNUSED_PARAM2(iUnused1, iUnused2);
+
+ /* If an error has already occurred, this is a no-op */
+ if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
+ if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
+
+ if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){
+ Fts5ExprTerm *pSyn;
sqlite3_int64 nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
pSyn = (Fts5ExprTerm*)sqlite3_malloc64(nByte);
- if( pSyn==0 ){
- rc = SQLITE_NOMEM;
- }else{
+ if( pSyn==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
memset(pSyn, 0, (size_t)nByte);
- pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
- memcpy(pSyn->zTerm, pToken, nToken);
- pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
- pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
- }
- }else{
- Fts5ExprTerm *pTerm;
- if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){
- Fts5ExprPhrase *pNew;
- int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
-
+ pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
+ memcpy(pSyn->zTerm, pToken, nToken);
+ pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
+ pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
+ }
+ }else{
+ Fts5ExprTerm *pTerm;
+ if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){
+ Fts5ExprPhrase *pNew;
+ int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
+
pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase,
- sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
- );
- if( pNew==0 ){
- rc = SQLITE_NOMEM;
- }else{
- if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase));
- pCtx->pPhrase = pPhrase = pNew;
- pNew->nTerm = nNew - SZALLOC;
- }
- }
-
- if( rc==SQLITE_OK ){
- pTerm = &pPhrase->aTerm[pPhrase->nTerm++];
- memset(pTerm, 0, sizeof(Fts5ExprTerm));
- pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
- }
- }
-
- pCtx->rc = rc;
- return rc;
-}
-
-
-/*
-** Free the phrase object passed as the only argument.
-*/
-static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase *pPhrase){
- fts5ExprPhraseFree(pPhrase);
-}
-
-/*
-** Free the phrase object passed as the second argument.
-*/
-static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset *pNear){
- if( pNear ){
- int i;
- for(i=0; i<pNear->nPhrase; i++){
- fts5ExprPhraseFree(pNear->apPhrase[i]);
- }
- sqlite3_free(pNear->pColset);
- sqlite3_free(pNear);
- }
-}
-
-static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){
- assert( pParse->pExpr==0 );
- pParse->pExpr = p;
-}
-
+ sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
+ );
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase));
+ pCtx->pPhrase = pPhrase = pNew;
+ pNew->nTerm = nNew - SZALLOC;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ pTerm = &pPhrase->aTerm[pPhrase->nTerm++];
+ memset(pTerm, 0, sizeof(Fts5ExprTerm));
+ pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
+ }
+ }
+
+ pCtx->rc = rc;
+ return rc;
+}
+
+
+/*
+** Free the phrase object passed as the only argument.
+*/
+static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase *pPhrase){
+ fts5ExprPhraseFree(pPhrase);
+}
+
+/*
+** Free the phrase object passed as the second argument.
+*/
+static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset *pNear){
+ if( pNear ){
+ int i;
+ for(i=0; i<pNear->nPhrase; i++){
+ fts5ExprPhraseFree(pNear->apPhrase[i]);
+ }
+ sqlite3_free(pNear->pColset);
+ sqlite3_free(pNear);
+ }
+}
+
+static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){
+ assert( pParse->pExpr==0 );
+ pParse->pExpr = p;
+}
+
static int parseGrowPhraseArray(Fts5Parse *pParse){
if( (pParse->nPhrase % 8)==0 ){
sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
@@ -221064,450 +221064,450 @@ static int parseGrowPhraseArray(Fts5Parse *pParse){
return SQLITE_OK;
}
-/*
-** This function is called by the parser to process a string token. The
-** string may or may not be quoted. In any case it is tokenized and a
-** phrase object consisting of all tokens returned.
-*/
-static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
- Fts5Parse *pParse, /* Parse context */
- Fts5ExprPhrase *pAppend, /* Phrase to append to */
- Fts5Token *pToken, /* String to tokenize */
- int bPrefix /* True if there is a trailing "*" */
-){
- Fts5Config *pConfig = pParse->pConfig;
- TokenCtx sCtx; /* Context object passed to callback */
- int rc; /* Tokenize return code */
- char *z = 0;
-
- memset(&sCtx, 0, sizeof(TokenCtx));
- sCtx.pPhrase = pAppend;
-
- rc = fts5ParseStringFromToken(pToken, &z);
- if( rc==SQLITE_OK ){
- int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_PREFIX : 0);
- int n;
- sqlite3Fts5Dequote(z);
- n = (int)strlen(z);
- rc = sqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize);
- }
- sqlite3_free(z);
- if( rc || (rc = sCtx.rc) ){
- pParse->rc = rc;
- fts5ExprPhraseFree(sCtx.pPhrase);
- sCtx.pPhrase = 0;
- }else{
-
- if( pAppend==0 ){
+/*
+** This function is called by the parser to process a string token. The
+** string may or may not be quoted. In any case it is tokenized and a
+** phrase object consisting of all tokens returned.
+*/
+static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
+ Fts5Parse *pParse, /* Parse context */
+ Fts5ExprPhrase *pAppend, /* Phrase to append to */
+ Fts5Token *pToken, /* String to tokenize */
+ int bPrefix /* True if there is a trailing "*" */
+){
+ Fts5Config *pConfig = pParse->pConfig;
+ TokenCtx sCtx; /* Context object passed to callback */
+ int rc; /* Tokenize return code */
+ char *z = 0;
+
+ memset(&sCtx, 0, sizeof(TokenCtx));
+ sCtx.pPhrase = pAppend;
+
+ rc = fts5ParseStringFromToken(pToken, &z);
+ if( rc==SQLITE_OK ){
+ int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_PREFIX : 0);
+ int n;
+ sqlite3Fts5Dequote(z);
+ n = (int)strlen(z);
+ rc = sqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize);
+ }
+ sqlite3_free(z);
+ if( rc || (rc = sCtx.rc) ){
+ pParse->rc = rc;
+ fts5ExprPhraseFree(sCtx.pPhrase);
+ sCtx.pPhrase = 0;
+ }else{
+
+ if( pAppend==0 ){
if( parseGrowPhraseArray(pParse) ){
fts5ExprPhraseFree(sCtx.pPhrase);
return 0;
- }
- pParse->nPhrase++;
- }
-
- if( sCtx.pPhrase==0 ){
- /* This happens when parsing a token or quoted phrase that contains
- ** no token characters at all. (e.g ... MATCH '""'). */
- sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
- }else if( sCtx.pPhrase->nTerm ){
+ }
+ pParse->nPhrase++;
+ }
+
+ if( sCtx.pPhrase==0 ){
+ /* This happens when parsing a token or quoted phrase that contains
+ ** no token characters at all. (e.g ... MATCH '""'). */
+ sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
+ }else if( sCtx.pPhrase->nTerm ){
sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix;
- }
- pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
- }
-
- return sCtx.pPhrase;
-}
-
-/*
-** Create a new FTS5 expression by cloning phrase iPhrase of the
-** expression passed as the second argument.
-*/
-static int sqlite3Fts5ExprClonePhrase(
+ }
+ pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
+ }
+
+ return sCtx.pPhrase;
+}
+
+/*
+** Create a new FTS5 expression by cloning phrase iPhrase of the
+** expression passed as the second argument.
+*/
+static int sqlite3Fts5ExprClonePhrase(
Fts5Expr *pExpr,
int iPhrase,
- Fts5Expr **ppNew
-){
- int rc = SQLITE_OK; /* Return code */
- Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
- Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
- TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */
-
- pOrig = pExpr->apExprPhrase[iPhrase];
- pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
- if( rc==SQLITE_OK ){
+ Fts5Expr **ppNew
+){
+ int rc = SQLITE_OK; /* Return code */
+ Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
+ Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
+ TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */
+
+ pOrig = pExpr->apExprPhrase[iPhrase];
+ pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
+ if( rc==SQLITE_OK ){
pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
- sizeof(Fts5ExprPhrase*));
- }
- if( rc==SQLITE_OK ){
+ sizeof(Fts5ExprPhrase*));
+ }
+ if( rc==SQLITE_OK ){
pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc,
- sizeof(Fts5ExprNode));
- }
- if( rc==SQLITE_OK ){
+ sizeof(Fts5ExprNode));
+ }
+ if( rc==SQLITE_OK ){
pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
- sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
- }
- if( rc==SQLITE_OK ){
- Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
- if( pColsetOrig ){
+ sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
+ }
+ if( rc==SQLITE_OK ){
+ Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
+ if( pColsetOrig ){
sqlite3_int64 nByte;
Fts5Colset *pColset;
nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
if( pColset ){
memcpy(pColset, pColsetOrig, (size_t)nByte);
- }
- pNew->pRoot->pNear->pColset = pColset;
- }
- }
-
- if( pOrig->nTerm ){
- int i; /* Used to iterate through phrase terms */
- for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
- int tflags = 0;
- Fts5ExprTerm *p;
- for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
- const char *zTerm = p->zTerm;
- rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
- 0, 0);
- tflags = FTS5_TOKEN_COLOCATED;
- }
- if( rc==SQLITE_OK ){
- sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
- sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
- }
- }
- }else{
- /* This happens when parsing a token or quoted phrase that contains
- ** no token characters at all. (e.g ... MATCH '""'). */
- sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
- }
-
+ }
+ pNew->pRoot->pNear->pColset = pColset;
+ }
+ }
+
+ if( pOrig->nTerm ){
+ int i; /* Used to iterate through phrase terms */
+ for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
+ int tflags = 0;
+ Fts5ExprTerm *p;
+ for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
+ const char *zTerm = p->zTerm;
+ rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
+ 0, 0);
+ tflags = FTS5_TOKEN_COLOCATED;
+ }
+ if( rc==SQLITE_OK ){
+ sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
+ sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
+ }
+ }
+ }else{
+ /* This happens when parsing a token or quoted phrase that contains
+ ** no token characters at all. (e.g ... MATCH '""'). */
+ sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
+ }
+
if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){
- /* All the allocations succeeded. Put the expression object together. */
- pNew->pIndex = pExpr->pIndex;
- pNew->pConfig = pExpr->pConfig;
- pNew->nPhrase = 1;
- pNew->apExprPhrase[0] = sCtx.pPhrase;
- pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase;
- pNew->pRoot->pNear->nPhrase = 1;
- sCtx.pPhrase->pNode = pNew->pRoot;
-
+ /* All the allocations succeeded. Put the expression object together. */
+ pNew->pIndex = pExpr->pIndex;
+ pNew->pConfig = pExpr->pConfig;
+ pNew->nPhrase = 1;
+ pNew->apExprPhrase[0] = sCtx.pPhrase;
+ pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase;
+ pNew->pRoot->pNear->nPhrase = 1;
+ sCtx.pPhrase->pNode = pNew->pRoot;
+
if( pOrig->nTerm==1
&& pOrig->aTerm[0].pSynonym==0
&& pOrig->aTerm[0].bFirst==0
- ){
- pNew->pRoot->eType = FTS5_TERM;
- pNew->pRoot->xNext = fts5ExprNodeNext_TERM;
- }else{
- pNew->pRoot->eType = FTS5_STRING;
- pNew->pRoot->xNext = fts5ExprNodeNext_STRING;
- }
- }else{
- sqlite3Fts5ExprFree(pNew);
- fts5ExprPhraseFree(sCtx.pPhrase);
- pNew = 0;
- }
-
- *ppNew = pNew;
- return rc;
-}
-
-
-/*
-** Token pTok has appeared in a MATCH expression where the NEAR operator
-** is expected. If token pTok does not contain "NEAR", store an error
-** in the pParse object.
-*/
-static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token *pTok){
- if( pTok->n!=4 || memcmp("NEAR", pTok->p, 4) ){
- sqlite3Fts5ParseError(
- pParse, "fts5: syntax error near \"%.*s\"", pTok->n, pTok->p
- );
- }
-}
-
-static void sqlite3Fts5ParseSetDistance(
+ ){
+ pNew->pRoot->eType = FTS5_TERM;
+ pNew->pRoot->xNext = fts5ExprNodeNext_TERM;
+ }else{
+ pNew->pRoot->eType = FTS5_STRING;
+ pNew->pRoot->xNext = fts5ExprNodeNext_STRING;
+ }
+ }else{
+ sqlite3Fts5ExprFree(pNew);
+ fts5ExprPhraseFree(sCtx.pPhrase);
+ pNew = 0;
+ }
+
+ *ppNew = pNew;
+ return rc;
+}
+
+
+/*
+** Token pTok has appeared in a MATCH expression where the NEAR operator
+** is expected. If token pTok does not contain "NEAR", store an error
+** in the pParse object.
+*/
+static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token *pTok){
+ if( pTok->n!=4 || memcmp("NEAR", pTok->p, 4) ){
+ sqlite3Fts5ParseError(
+ pParse, "fts5: syntax error near \"%.*s\"", pTok->n, pTok->p
+ );
+ }
+}
+
+static void sqlite3Fts5ParseSetDistance(
Fts5Parse *pParse,
- Fts5ExprNearset *pNear,
- Fts5Token *p
-){
- if( pNear ){
- int nNear = 0;
- int i;
- if( p->n ){
- for(i=0; i<p->n; i++){
- char c = (char)p->p[i];
- if( c<'0' || c>'9' ){
- sqlite3Fts5ParseError(
- pParse, "expected integer, got \"%.*s\"", p->n, p->p
- );
- return;
- }
- nNear = nNear * 10 + (p->p[i] - '0');
- }
- }else{
- nNear = FTS5_DEFAULT_NEARDIST;
- }
- pNear->nNear = nNear;
- }
-}
-
-/*
-** The second argument passed to this function may be NULL, or it may be
-** an existing Fts5Colset object. This function returns a pointer to
-** a new colset object containing the contents of (p) with new value column
+ Fts5ExprNearset *pNear,
+ Fts5Token *p
+){
+ if( pNear ){
+ int nNear = 0;
+ int i;
+ if( p->n ){
+ for(i=0; i<p->n; i++){
+ char c = (char)p->p[i];
+ if( c<'0' || c>'9' ){
+ sqlite3Fts5ParseError(
+ pParse, "expected integer, got \"%.*s\"", p->n, p->p
+ );
+ return;
+ }
+ nNear = nNear * 10 + (p->p[i] - '0');
+ }
+ }else{
+ nNear = FTS5_DEFAULT_NEARDIST;
+ }
+ pNear->nNear = nNear;
+ }
+}
+
+/*
+** The second argument passed to this function may be NULL, or it may be
+** an existing Fts5Colset object. This function returns a pointer to
+** a new colset object containing the contents of (p) with new value column
** number iCol appended.
-**
-** If an OOM error occurs, store an error code in pParse and return NULL.
-** The old colset object (if any) is not freed in this case.
-*/
-static Fts5Colset *fts5ParseColset(
- Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
- Fts5Colset *p, /* Existing colset object */
- int iCol /* New column to add to colset object */
-){
- int nCol = p ? p->nCol : 0; /* Num. columns already in colset object */
- Fts5Colset *pNew; /* New colset object to return */
-
- assert( pParse->rc==SQLITE_OK );
- assert( iCol>=0 && iCol<pParse->pConfig->nCol );
-
+**
+** If an OOM error occurs, store an error code in pParse and return NULL.
+** The old colset object (if any) is not freed in this case.
+*/
+static Fts5Colset *fts5ParseColset(
+ Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
+ Fts5Colset *p, /* Existing colset object */
+ int iCol /* New column to add to colset object */
+){
+ int nCol = p ? p->nCol : 0; /* Num. columns already in colset object */
+ Fts5Colset *pNew; /* New colset object to return */
+
+ assert( pParse->rc==SQLITE_OK );
+ assert( iCol>=0 && iCol<pParse->pConfig->nCol );
+
pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
- if( pNew==0 ){
- pParse->rc = SQLITE_NOMEM;
- }else{
- int *aiCol = pNew->aiCol;
- int i, j;
- for(i=0; i<nCol; i++){
- if( aiCol[i]==iCol ) return pNew;
- if( aiCol[i]>iCol ) break;
- }
- for(j=nCol; j>i; j--){
- aiCol[j] = aiCol[j-1];
- }
- aiCol[i] = iCol;
- pNew->nCol = nCol+1;
-
-#ifndef NDEBUG
- /* Check that the array is in order and contains no duplicate entries. */
- for(i=1; i<pNew->nCol; i++) assert( pNew->aiCol[i]>pNew->aiCol[i-1] );
-#endif
- }
-
- return pNew;
-}
-
-/*
-** Allocate and return an Fts5Colset object specifying the inverse of
-** the colset passed as the second argument. Free the colset passed
-** as the second argument before returning.
-*/
-static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){
- Fts5Colset *pRet;
- int nCol = pParse->pConfig->nCol;
-
+ if( pNew==0 ){
+ pParse->rc = SQLITE_NOMEM;
+ }else{
+ int *aiCol = pNew->aiCol;
+ int i, j;
+ for(i=0; i<nCol; i++){
+ if( aiCol[i]==iCol ) return pNew;
+ if( aiCol[i]>iCol ) break;
+ }
+ for(j=nCol; j>i; j--){
+ aiCol[j] = aiCol[j-1];
+ }
+ aiCol[i] = iCol;
+ pNew->nCol = nCol+1;
+
+#ifndef NDEBUG
+ /* Check that the array is in order and contains no duplicate entries. */
+ for(i=1; i<pNew->nCol; i++) assert( pNew->aiCol[i]>pNew->aiCol[i-1] );
+#endif
+ }
+
+ return pNew;
+}
+
+/*
+** Allocate and return an Fts5Colset object specifying the inverse of
+** the colset passed as the second argument. Free the colset passed
+** as the second argument before returning.
+*/
+static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){
+ Fts5Colset *pRet;
+ int nCol = pParse->pConfig->nCol;
+
pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc,
- sizeof(Fts5Colset) + sizeof(int)*nCol
- );
- if( pRet ){
- int i;
- int iOld = 0;
- for(i=0; i<nCol; i++){
- if( iOld>=p->nCol || p->aiCol[iOld]!=i ){
- pRet->aiCol[pRet->nCol++] = i;
- }else{
- iOld++;
- }
- }
- }
-
- sqlite3_free(p);
- return pRet;
-}
-
-static Fts5Colset *sqlite3Fts5ParseColset(
- Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
- Fts5Colset *pColset, /* Existing colset object */
- Fts5Token *p
-){
- Fts5Colset *pRet = 0;
- int iCol;
- char *z; /* Dequoted copy of token p */
-
- z = sqlite3Fts5Strndup(&pParse->rc, p->p, p->n);
- if( pParse->rc==SQLITE_OK ){
- Fts5Config *pConfig = pParse->pConfig;
- sqlite3Fts5Dequote(z);
- for(iCol=0; iCol<pConfig->nCol; iCol++){
- if( 0==sqlite3_stricmp(pConfig->azCol[iCol], z) ) break;
- }
- if( iCol==pConfig->nCol ){
- sqlite3Fts5ParseError(pParse, "no such column: %s", z);
- }else{
- pRet = fts5ParseColset(pParse, pColset, iCol);
- }
- sqlite3_free(z);
- }
-
- if( pRet==0 ){
- assert( pParse->rc!=SQLITE_OK );
- sqlite3_free(pColset);
- }
-
- return pRet;
-}
-
-/*
-** If argument pOrig is NULL, or if (*pRc) is set to anything other than
+ sizeof(Fts5Colset) + sizeof(int)*nCol
+ );
+ if( pRet ){
+ int i;
+ int iOld = 0;
+ for(i=0; i<nCol; i++){
+ if( iOld>=p->nCol || p->aiCol[iOld]!=i ){
+ pRet->aiCol[pRet->nCol++] = i;
+ }else{
+ iOld++;
+ }
+ }
+ }
+
+ sqlite3_free(p);
+ return pRet;
+}
+
+static Fts5Colset *sqlite3Fts5ParseColset(
+ Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
+ Fts5Colset *pColset, /* Existing colset object */
+ Fts5Token *p
+){
+ Fts5Colset *pRet = 0;
+ int iCol;
+ char *z; /* Dequoted copy of token p */
+
+ z = sqlite3Fts5Strndup(&pParse->rc, p->p, p->n);
+ if( pParse->rc==SQLITE_OK ){
+ Fts5Config *pConfig = pParse->pConfig;
+ sqlite3Fts5Dequote(z);
+ for(iCol=0; iCol<pConfig->nCol; iCol++){
+ if( 0==sqlite3_stricmp(pConfig->azCol[iCol], z) ) break;
+ }
+ if( iCol==pConfig->nCol ){
+ sqlite3Fts5ParseError(pParse, "no such column: %s", z);
+ }else{
+ pRet = fts5ParseColset(pParse, pColset, iCol);
+ }
+ sqlite3_free(z);
+ }
+
+ if( pRet==0 ){
+ assert( pParse->rc!=SQLITE_OK );
+ sqlite3_free(pColset);
+ }
+
+ return pRet;
+}
+
+/*
+** If argument pOrig is NULL, or if (*pRc) is set to anything other than
** SQLITE_OK when this function is called, NULL is returned.
-**
-** Otherwise, a copy of (*pOrig) is made into memory obtained from
-** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation
-** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned.
-*/
-static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
- Fts5Colset *pRet;
- if( pOrig ){
+**
+** Otherwise, a copy of (*pOrig) is made into memory obtained from
+** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation
+** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned.
+*/
+static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
+ Fts5Colset *pRet;
+ if( pOrig ){
sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
- pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
+ pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
if( pRet ){
memcpy(pRet, pOrig, (size_t)nByte);
- }
- }else{
- pRet = 0;
- }
- return pRet;
-}
-
-/*
-** Remove from colset pColset any columns that are not also in colset pMerge.
-*/
-static void fts5MergeColset(Fts5Colset *pColset, Fts5Colset *pMerge){
- int iIn = 0; /* Next input in pColset */
- int iMerge = 0; /* Next input in pMerge */
- int iOut = 0; /* Next output slot in pColset */
-
- while( iIn<pColset->nCol && iMerge<pMerge->nCol ){
- int iDiff = pColset->aiCol[iIn] - pMerge->aiCol[iMerge];
- if( iDiff==0 ){
- pColset->aiCol[iOut++] = pMerge->aiCol[iMerge];
- iMerge++;
- iIn++;
- }else if( iDiff>0 ){
- iMerge++;
- }else{
- iIn++;
- }
- }
- pColset->nCol = iOut;
-}
-
-/*
-** Recursively apply colset pColset to expression node pNode and all of
-** its decendents. If (*ppFree) is not NULL, it contains a spare copy
-** of pColset. This function may use the spare copy and set (*ppFree) to
-** zero, or it may create copies of pColset using fts5CloneColset().
-*/
-static void fts5ParseSetColset(
+ }
+ }else{
+ pRet = 0;
+ }
+ return pRet;
+}
+
+/*
+** Remove from colset pColset any columns that are not also in colset pMerge.
+*/
+static void fts5MergeColset(Fts5Colset *pColset, Fts5Colset *pMerge){
+ int iIn = 0; /* Next input in pColset */
+ int iMerge = 0; /* Next input in pMerge */
+ int iOut = 0; /* Next output slot in pColset */
+
+ while( iIn<pColset->nCol && iMerge<pMerge->nCol ){
+ int iDiff = pColset->aiCol[iIn] - pMerge->aiCol[iMerge];
+ if( iDiff==0 ){
+ pColset->aiCol[iOut++] = pMerge->aiCol[iMerge];
+ iMerge++;
+ iIn++;
+ }else if( iDiff>0 ){
+ iMerge++;
+ }else{
+ iIn++;
+ }
+ }
+ pColset->nCol = iOut;
+}
+
+/*
+** Recursively apply colset pColset to expression node pNode and all of
+** its decendents. If (*ppFree) is not NULL, it contains a spare copy
+** of pColset. This function may use the spare copy and set (*ppFree) to
+** zero, or it may create copies of pColset using fts5CloneColset().
+*/
+static void fts5ParseSetColset(
Fts5Parse *pParse,
Fts5ExprNode *pNode,
- Fts5Colset *pColset,
- Fts5Colset **ppFree
-){
- if( pParse->rc==SQLITE_OK ){
+ Fts5Colset *pColset,
+ Fts5Colset **ppFree
+){
+ if( pParse->rc==SQLITE_OK ){
assert( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING
- || pNode->eType==FTS5_AND || pNode->eType==FTS5_OR
- || pNode->eType==FTS5_NOT || pNode->eType==FTS5_EOF
- );
- if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
- Fts5ExprNearset *pNear = pNode->pNear;
- if( pNear->pColset ){
- fts5MergeColset(pNear->pColset, pColset);
- if( pNear->pColset->nCol==0 ){
- pNode->eType = FTS5_EOF;
- pNode->xNext = 0;
- }
- }else if( *ppFree ){
- pNear->pColset = pColset;
- *ppFree = 0;
- }else{
- pNear->pColset = fts5CloneColset(&pParse->rc, pColset);
- }
- }else{
- int i;
- assert( pNode->eType!=FTS5_EOF || pNode->nChild==0 );
- for(i=0; i<pNode->nChild; i++){
- fts5ParseSetColset(pParse, pNode->apChild[i], pColset, ppFree);
- }
- }
- }
-}
-
-/*
-** Apply colset pColset to expression node pExpr and all of its descendents.
-*/
-static void sqlite3Fts5ParseSetColset(
+ || pNode->eType==FTS5_AND || pNode->eType==FTS5_OR
+ || pNode->eType==FTS5_NOT || pNode->eType==FTS5_EOF
+ );
+ if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
+ Fts5ExprNearset *pNear = pNode->pNear;
+ if( pNear->pColset ){
+ fts5MergeColset(pNear->pColset, pColset);
+ if( pNear->pColset->nCol==0 ){
+ pNode->eType = FTS5_EOF;
+ pNode->xNext = 0;
+ }
+ }else if( *ppFree ){
+ pNear->pColset = pColset;
+ *ppFree = 0;
+ }else{
+ pNear->pColset = fts5CloneColset(&pParse->rc, pColset);
+ }
+ }else{
+ int i;
+ assert( pNode->eType!=FTS5_EOF || pNode->nChild==0 );
+ for(i=0; i<pNode->nChild; i++){
+ fts5ParseSetColset(pParse, pNode->apChild[i], pColset, ppFree);
+ }
+ }
+ }
+}
+
+/*
+** Apply colset pColset to expression node pExpr and all of its descendents.
+*/
+static void sqlite3Fts5ParseSetColset(
Fts5Parse *pParse,
Fts5ExprNode *pExpr,
Fts5Colset *pColset
-){
- Fts5Colset *pFree = pColset;
- if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
+){
+ Fts5Colset *pFree = pColset;
+ if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
sqlite3Fts5ParseError(pParse,
"fts5: column queries are not supported (detail=none)"
- );
- }else{
- fts5ParseSetColset(pParse, pExpr, pColset, &pFree);
- }
- sqlite3_free(pFree);
-}
-
-static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
- switch( pNode->eType ){
- case FTS5_STRING: {
- Fts5ExprNearset *pNear = pNode->pNear;
+ );
+ }else{
+ fts5ParseSetColset(pParse, pExpr, pColset, &pFree);
+ }
+ sqlite3_free(pFree);
+}
+
+static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
+ switch( pNode->eType ){
+ case FTS5_STRING: {
+ Fts5ExprNearset *pNear = pNode->pNear;
if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1
- && pNear->apPhrase[0]->aTerm[0].pSynonym==0
- && pNear->apPhrase[0]->aTerm[0].bFirst==0
- ){
- pNode->eType = FTS5_TERM;
- pNode->xNext = fts5ExprNodeNext_TERM;
- }else{
- pNode->xNext = fts5ExprNodeNext_STRING;
- }
- break;
- };
-
- case FTS5_OR: {
- pNode->xNext = fts5ExprNodeNext_OR;
- break;
- };
-
- case FTS5_AND: {
- pNode->xNext = fts5ExprNodeNext_AND;
- break;
- };
-
- default: assert( pNode->eType==FTS5_NOT ); {
- pNode->xNext = fts5ExprNodeNext_NOT;
- break;
- };
- }
-}
-
-static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
- if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){
- int nByte = sizeof(Fts5ExprNode*) * pSub->nChild;
- memcpy(&p->apChild[p->nChild], pSub->apChild, nByte);
- p->nChild += pSub->nChild;
- sqlite3_free(pSub);
- }else{
- p->apChild[p->nChild++] = pSub;
- }
-}
-
-/*
+ && pNear->apPhrase[0]->aTerm[0].pSynonym==0
+ && pNear->apPhrase[0]->aTerm[0].bFirst==0
+ ){
+ pNode->eType = FTS5_TERM;
+ pNode->xNext = fts5ExprNodeNext_TERM;
+ }else{
+ pNode->xNext = fts5ExprNodeNext_STRING;
+ }
+ break;
+ };
+
+ case FTS5_OR: {
+ pNode->xNext = fts5ExprNodeNext_OR;
+ break;
+ };
+
+ case FTS5_AND: {
+ pNode->xNext = fts5ExprNodeNext_AND;
+ break;
+ };
+
+ default: assert( pNode->eType==FTS5_NOT ); {
+ pNode->xNext = fts5ExprNodeNext_NOT;
+ break;
+ };
+ }
+}
+
+static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
+ if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){
+ int nByte = sizeof(Fts5ExprNode*) * pSub->nChild;
+ memcpy(&p->apChild[p->nChild], pSub->apChild, nByte);
+ p->nChild += pSub->nChild;
+ sqlite3_free(pSub);
+ }else{
+ p->apChild[p->nChild++] = pSub;
+ }
+}
+
+/*
** This function is used when parsing LIKE or GLOB patterns against
** trigram indexes that specify either detail=column or detail=none.
** It converts a phrase:
@@ -221569,29 +221569,29 @@ static Fts5ExprNode *fts5ParsePhraseToAnd(
}
/*
-** Allocate and return a new expression object. If anything goes wrong (i.e.
-** OOM error), leave an error code in pParse and return NULL.
-*/
-static Fts5ExprNode *sqlite3Fts5ParseNode(
- Fts5Parse *pParse, /* Parse context */
- int eType, /* FTS5_STRING, AND, OR or NOT */
- Fts5ExprNode *pLeft, /* Left hand child expression */
- Fts5ExprNode *pRight, /* Right hand child expression */
- Fts5ExprNearset *pNear /* For STRING expressions, the near cluster */
-){
- Fts5ExprNode *pRet = 0;
-
- if( pParse->rc==SQLITE_OK ){
- int nChild = 0; /* Number of children of returned node */
+** Allocate and return a new expression object. If anything goes wrong (i.e.
+** OOM error), leave an error code in pParse and return NULL.
+*/
+static Fts5ExprNode *sqlite3Fts5ParseNode(
+ Fts5Parse *pParse, /* Parse context */
+ int eType, /* FTS5_STRING, AND, OR or NOT */
+ Fts5ExprNode *pLeft, /* Left hand child expression */
+ Fts5ExprNode *pRight, /* Right hand child expression */
+ Fts5ExprNearset *pNear /* For STRING expressions, the near cluster */
+){
+ Fts5ExprNode *pRet = 0;
+
+ if( pParse->rc==SQLITE_OK ){
+ int nChild = 0; /* Number of children of returned node */
sqlite3_int64 nByte; /* Bytes of space to allocate for this node */
- assert( (eType!=FTS5_STRING && !pNear)
- || (eType==FTS5_STRING && !pLeft && !pRight)
- );
- if( eType==FTS5_STRING && pNear==0 ) return 0;
- if( eType!=FTS5_STRING && pLeft==0 ) return pRight;
- if( eType!=FTS5_STRING && pRight==0 ) return pLeft;
-
+ assert( (eType!=FTS5_STRING && !pNear)
+ || (eType==FTS5_STRING && !pLeft && !pRight)
+ );
+ if( eType==FTS5_STRING && pNear==0 ) return 0;
+ if( eType!=FTS5_STRING && pLeft==0 ) return pRight;
+ if( eType!=FTS5_STRING && pRight==0 ) return pLeft;
+
if( eType==FTS5_STRING
&& pParse->bPhraseToAnd
&& pNear->apPhrase[0]->nTerm>1
@@ -221605,10 +221605,10 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
if( pRight->eType==eType ) nChild += pRight->nChild-1;
}
-
+
nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
-
+
if( pRet ){
pRet->eType = eType;
pRet->pNear = pNear;
@@ -221621,8 +221621,8 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
pRet->xNext = 0;
pRet->eType = FTS5_EOF;
}
- }
-
+ }
+
if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
if( pNear->nPhrase!=1
@@ -221636,232 +221636,232 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
sqlite3_free(pRet);
pRet = 0;
}
- }
+ }
}else{
fts5ExprAddChildren(pRet, pLeft);
fts5ExprAddChildren(pRet, pRight);
- }
- }
- }
- }
-
- if( pRet==0 ){
- assert( pParse->rc!=SQLITE_OK );
- sqlite3Fts5ParseNodeFree(pLeft);
- sqlite3Fts5ParseNodeFree(pRight);
- sqlite3Fts5ParseNearsetFree(pNear);
- }
- return pRet;
-}
-
-static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
- Fts5Parse *pParse, /* Parse context */
- Fts5ExprNode *pLeft, /* Left hand child expression */
- Fts5ExprNode *pRight /* Right hand child expression */
-){
- Fts5ExprNode *pRet = 0;
- Fts5ExprNode *pPrev;
-
- if( pParse->rc ){
- sqlite3Fts5ParseNodeFree(pLeft);
- sqlite3Fts5ParseNodeFree(pRight);
- }else{
-
+ }
+ }
+ }
+ }
+
+ if( pRet==0 ){
+ assert( pParse->rc!=SQLITE_OK );
+ sqlite3Fts5ParseNodeFree(pLeft);
+ sqlite3Fts5ParseNodeFree(pRight);
+ sqlite3Fts5ParseNearsetFree(pNear);
+ }
+ return pRet;
+}
+
+static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
+ Fts5Parse *pParse, /* Parse context */
+ Fts5ExprNode *pLeft, /* Left hand child expression */
+ Fts5ExprNode *pRight /* Right hand child expression */
+){
+ Fts5ExprNode *pRet = 0;
+ Fts5ExprNode *pPrev;
+
+ if( pParse->rc ){
+ sqlite3Fts5ParseNodeFree(pLeft);
+ sqlite3Fts5ParseNodeFree(pRight);
+ }else{
+
assert( pLeft->eType==FTS5_STRING
- || pLeft->eType==FTS5_TERM
- || pLeft->eType==FTS5_EOF
- || pLeft->eType==FTS5_AND
- );
+ || pLeft->eType==FTS5_TERM
+ || pLeft->eType==FTS5_EOF
+ || pLeft->eType==FTS5_AND
+ );
assert( pRight->eType==FTS5_STRING
|| pRight->eType==FTS5_TERM
|| pRight->eType==FTS5_EOF
- );
-
- if( pLeft->eType==FTS5_AND ){
- pPrev = pLeft->apChild[pLeft->nChild-1];
- }else{
- pPrev = pLeft;
- }
+ );
+
+ if( pLeft->eType==FTS5_AND ){
+ pPrev = pLeft->apChild[pLeft->nChild-1];
+ }else{
+ pPrev = pLeft;
+ }
assert( pPrev->eType==FTS5_STRING
|| pPrev->eType==FTS5_TERM
|| pPrev->eType==FTS5_EOF
- );
-
- if( pRight->eType==FTS5_EOF ){
- assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] );
- sqlite3Fts5ParseNodeFree(pRight);
- pRet = pLeft;
- pParse->nPhrase--;
- }
- else if( pPrev->eType==FTS5_EOF ){
- Fts5ExprPhrase **ap;
-
- if( pPrev==pLeft ){
- pRet = pRight;
- }else{
- pLeft->apChild[pLeft->nChild-1] = pRight;
- pRet = pLeft;
- }
-
- ap = &pParse->apPhrase[pParse->nPhrase-1-pRight->pNear->nPhrase];
- assert( ap[0]==pPrev->pNear->apPhrase[0] );
- memmove(ap, &ap[1], sizeof(Fts5ExprPhrase*)*pRight->pNear->nPhrase);
- pParse->nPhrase--;
-
- sqlite3Fts5ParseNodeFree(pPrev);
- }
- else{
- pRet = sqlite3Fts5ParseNode(pParse, FTS5_AND, pLeft, pRight, 0);
- }
- }
-
- return pRet;
-}
-
+ );
+
+ if( pRight->eType==FTS5_EOF ){
+ assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] );
+ sqlite3Fts5ParseNodeFree(pRight);
+ pRet = pLeft;
+ pParse->nPhrase--;
+ }
+ else if( pPrev->eType==FTS5_EOF ){
+ Fts5ExprPhrase **ap;
+
+ if( pPrev==pLeft ){
+ pRet = pRight;
+ }else{
+ pLeft->apChild[pLeft->nChild-1] = pRight;
+ pRet = pLeft;
+ }
+
+ ap = &pParse->apPhrase[pParse->nPhrase-1-pRight->pNear->nPhrase];
+ assert( ap[0]==pPrev->pNear->apPhrase[0] );
+ memmove(ap, &ap[1], sizeof(Fts5ExprPhrase*)*pRight->pNear->nPhrase);
+ pParse->nPhrase--;
+
+ sqlite3Fts5ParseNodeFree(pPrev);
+ }
+ else{
+ pRet = sqlite3Fts5ParseNode(pParse, FTS5_AND, pLeft, pRight, 0);
+ }
+ }
+
+ return pRet;
+}
+
#ifdef SQLITE_TEST
-static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
+static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
sqlite3_int64 nByte = 0;
- Fts5ExprTerm *p;
- char *zQuoted;
-
- /* Determine the maximum amount of space required. */
- for(p=pTerm; p; p=p->pSynonym){
- nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
- }
+ Fts5ExprTerm *p;
+ char *zQuoted;
+
+ /* Determine the maximum amount of space required. */
+ for(p=pTerm; p; p=p->pSynonym){
+ nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
+ }
zQuoted = sqlite3_malloc64(nByte);
-
- if( zQuoted ){
- int i = 0;
- for(p=pTerm; p; p=p->pSynonym){
- char *zIn = p->zTerm;
- zQuoted[i++] = '"';
- while( *zIn ){
- if( *zIn=='"' ) zQuoted[i++] = '"';
- zQuoted[i++] = *zIn++;
- }
- zQuoted[i++] = '"';
- if( p->pSynonym ) zQuoted[i++] = '|';
- }
- if( pTerm->bPrefix ){
- zQuoted[i++] = ' ';
- zQuoted[i++] = '*';
- }
- zQuoted[i++] = '\0';
- }
- return zQuoted;
-}
-
-static char *fts5PrintfAppend(char *zApp, const char *zFmt, ...){
- char *zNew;
- va_list ap;
- va_start(ap, zFmt);
- zNew = sqlite3_vmprintf(zFmt, ap);
- va_end(ap);
- if( zApp && zNew ){
- char *zNew2 = sqlite3_mprintf("%s%s", zApp, zNew);
- sqlite3_free(zNew);
- zNew = zNew2;
- }
- sqlite3_free(zApp);
- return zNew;
-}
-
-/*
+
+ if( zQuoted ){
+ int i = 0;
+ for(p=pTerm; p; p=p->pSynonym){
+ char *zIn = p->zTerm;
+ zQuoted[i++] = '"';
+ while( *zIn ){
+ if( *zIn=='"' ) zQuoted[i++] = '"';
+ zQuoted[i++] = *zIn++;
+ }
+ zQuoted[i++] = '"';
+ if( p->pSynonym ) zQuoted[i++] = '|';
+ }
+ if( pTerm->bPrefix ){
+ zQuoted[i++] = ' ';
+ zQuoted[i++] = '*';
+ }
+ zQuoted[i++] = '\0';
+ }
+ return zQuoted;
+}
+
+static char *fts5PrintfAppend(char *zApp, const char *zFmt, ...){
+ char *zNew;
+ va_list ap;
+ va_start(ap, zFmt);
+ zNew = sqlite3_vmprintf(zFmt, ap);
+ va_end(ap);
+ if( zApp && zNew ){
+ char *zNew2 = sqlite3_mprintf("%s%s", zApp, zNew);
+ sqlite3_free(zNew);
+ zNew = zNew2;
+ }
+ sqlite3_free(zApp);
+ return zNew;
+}
+
+/*
** Compose a tcl-readable representation of expression pExpr. Return a
** pointer to a buffer containing that representation. It is the
** responsibility of the caller to at some point free the buffer using
-** sqlite3_free().
-*/
-static char *fts5ExprPrintTcl(
+** sqlite3_free().
+*/
+static char *fts5ExprPrintTcl(
Fts5Config *pConfig,
- const char *zNearsetCmd,
- Fts5ExprNode *pExpr
-){
- char *zRet = 0;
- if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
- Fts5ExprNearset *pNear = pExpr->pNear;
+ const char *zNearsetCmd,
+ Fts5ExprNode *pExpr
+){
+ char *zRet = 0;
+ if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
+ Fts5ExprNearset *pNear = pExpr->pNear;
+ int i;
+ int iTerm;
+
+ zRet = fts5PrintfAppend(zRet, "%s ", zNearsetCmd);
+ if( zRet==0 ) return 0;
+ if( pNear->pColset ){
+ int *aiCol = pNear->pColset->aiCol;
+ int nCol = pNear->pColset->nCol;
+ if( nCol==1 ){
+ zRet = fts5PrintfAppend(zRet, "-col %d ", aiCol[0]);
+ }else{
+ zRet = fts5PrintfAppend(zRet, "-col {%d", aiCol[0]);
+ for(i=1; i<pNear->pColset->nCol; i++){
+ zRet = fts5PrintfAppend(zRet, " %d", aiCol[i]);
+ }
+ zRet = fts5PrintfAppend(zRet, "} ");
+ }
+ if( zRet==0 ) return 0;
+ }
+
+ if( pNear->nPhrase>1 ){
+ zRet = fts5PrintfAppend(zRet, "-near %d ", pNear->nNear);
+ if( zRet==0 ) return 0;
+ }
+
+ zRet = fts5PrintfAppend(zRet, "--");
+ if( zRet==0 ) return 0;
+
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+
+ zRet = fts5PrintfAppend(zRet, " {");
+ for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){
+ char *zTerm = pPhrase->aTerm[iTerm].zTerm;
+ zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" ", zTerm);
+ if( pPhrase->aTerm[iTerm].bPrefix ){
+ zRet = fts5PrintfAppend(zRet, "*");
+ }
+ }
+
+ if( zRet ) zRet = fts5PrintfAppend(zRet, "}");
+ if( zRet==0 ) return 0;
+ }
+
+ }else{
+ char const *zOp = 0;
int i;
- int iTerm;
-
- zRet = fts5PrintfAppend(zRet, "%s ", zNearsetCmd);
- if( zRet==0 ) return 0;
- if( pNear->pColset ){
- int *aiCol = pNear->pColset->aiCol;
- int nCol = pNear->pColset->nCol;
- if( nCol==1 ){
- zRet = fts5PrintfAppend(zRet, "-col %d ", aiCol[0]);
- }else{
- zRet = fts5PrintfAppend(zRet, "-col {%d", aiCol[0]);
- for(i=1; i<pNear->pColset->nCol; i++){
- zRet = fts5PrintfAppend(zRet, " %d", aiCol[i]);
- }
- zRet = fts5PrintfAppend(zRet, "} ");
- }
- if( zRet==0 ) return 0;
- }
-
- if( pNear->nPhrase>1 ){
- zRet = fts5PrintfAppend(zRet, "-near %d ", pNear->nNear);
- if( zRet==0 ) return 0;
- }
-
- zRet = fts5PrintfAppend(zRet, "--");
- if( zRet==0 ) return 0;
-
- for(i=0; i<pNear->nPhrase; i++){
- Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
-
- zRet = fts5PrintfAppend(zRet, " {");
- for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){
- char *zTerm = pPhrase->aTerm[iTerm].zTerm;
- zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" ", zTerm);
- if( pPhrase->aTerm[iTerm].bPrefix ){
- zRet = fts5PrintfAppend(zRet, "*");
- }
- }
-
- if( zRet ) zRet = fts5PrintfAppend(zRet, "}");
- if( zRet==0 ) return 0;
- }
-
- }else{
- char const *zOp = 0;
- int i;
- switch( pExpr->eType ){
- case FTS5_AND: zOp = "AND"; break;
- case FTS5_NOT: zOp = "NOT"; break;
+ switch( pExpr->eType ){
+ case FTS5_AND: zOp = "AND"; break;
+ case FTS5_NOT: zOp = "NOT"; break;
default:
- assert( pExpr->eType==FTS5_OR );
+ assert( pExpr->eType==FTS5_OR );
zOp = "OR";
- break;
- }
-
- zRet = sqlite3_mprintf("%s", zOp);
- for(i=0; zRet && i<pExpr->nChild; i++){
- char *z = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->apChild[i]);
- if( !z ){
- sqlite3_free(zRet);
- zRet = 0;
- }else{
- zRet = fts5PrintfAppend(zRet, " [%z]", z);
- }
- }
- }
-
- return zRet;
-}
-
-static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
- char *zRet = 0;
- if( pExpr->eType==0 ){
- return sqlite3_mprintf("\"\"");
- }else
- if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
- Fts5ExprNearset *pNear = pExpr->pNear;
+ break;
+ }
+
+ zRet = sqlite3_mprintf("%s", zOp);
+ for(i=0; zRet && i<pExpr->nChild; i++){
+ char *z = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->apChild[i]);
+ if( !z ){
+ sqlite3_free(zRet);
+ zRet = 0;
+ }else{
+ zRet = fts5PrintfAppend(zRet, " [%z]", z);
+ }
+ }
+ }
+
+ return zRet;
+}
+
+static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
+ char *zRet = 0;
+ if( pExpr->eType==0 ){
+ return sqlite3_mprintf("\"\"");
+ }else
+ if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
+ Fts5ExprNearset *pNear = pExpr->pNear;
int i;
- int iTerm;
-
- if( pNear->pColset ){
+ int iTerm;
+
+ if( pNear->pColset ){
int ii;
Fts5Colset *pColset = pNear->pColset;
if( pColset->nCol>1 ) zRet = fts5PrintfAppend(zRet, "{");
@@ -221873,297 +221873,297 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
if( zRet ){
zRet = fts5PrintfAppend(zRet, "%s : ", pColset->nCol>1 ? "}" : "");
}
- if( zRet==0 ) return 0;
- }
-
- if( pNear->nPhrase>1 ){
- zRet = fts5PrintfAppend(zRet, "NEAR(");
- if( zRet==0 ) return 0;
- }
-
- for(i=0; i<pNear->nPhrase; i++){
- Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
- if( i!=0 ){
- zRet = fts5PrintfAppend(zRet, " ");
- if( zRet==0 ) return 0;
- }
- for(iTerm=0; iTerm<pPhrase->nTerm; iTerm++){
- char *zTerm = fts5ExprTermPrint(&pPhrase->aTerm[iTerm]);
- if( zTerm ){
- zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" + ", zTerm);
- sqlite3_free(zTerm);
- }
- if( zTerm==0 || zRet==0 ){
- sqlite3_free(zRet);
- return 0;
- }
- }
- }
-
- if( pNear->nPhrase>1 ){
- zRet = fts5PrintfAppend(zRet, ", %d)", pNear->nNear);
- if( zRet==0 ) return 0;
- }
-
- }else{
- char const *zOp = 0;
- int i;
-
- switch( pExpr->eType ){
- case FTS5_AND: zOp = " AND "; break;
- case FTS5_NOT: zOp = " NOT "; break;
+ if( zRet==0 ) return 0;
+ }
+
+ if( pNear->nPhrase>1 ){
+ zRet = fts5PrintfAppend(zRet, "NEAR(");
+ if( zRet==0 ) return 0;
+ }
+
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+ if( i!=0 ){
+ zRet = fts5PrintfAppend(zRet, " ");
+ if( zRet==0 ) return 0;
+ }
+ for(iTerm=0; iTerm<pPhrase->nTerm; iTerm++){
+ char *zTerm = fts5ExprTermPrint(&pPhrase->aTerm[iTerm]);
+ if( zTerm ){
+ zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" + ", zTerm);
+ sqlite3_free(zTerm);
+ }
+ if( zTerm==0 || zRet==0 ){
+ sqlite3_free(zRet);
+ return 0;
+ }
+ }
+ }
+
+ if( pNear->nPhrase>1 ){
+ zRet = fts5PrintfAppend(zRet, ", %d)", pNear->nNear);
+ if( zRet==0 ) return 0;
+ }
+
+ }else{
+ char const *zOp = 0;
+ int i;
+
+ switch( pExpr->eType ){
+ case FTS5_AND: zOp = " AND "; break;
+ case FTS5_NOT: zOp = " NOT "; break;
default:
- assert( pExpr->eType==FTS5_OR );
+ assert( pExpr->eType==FTS5_OR );
zOp = " OR ";
- break;
- }
-
- for(i=0; i<pExpr->nChild; i++){
- char *z = fts5ExprPrint(pConfig, pExpr->apChild[i]);
- if( z==0 ){
- sqlite3_free(zRet);
- zRet = 0;
- }else{
- int e = pExpr->apChild[i]->eType;
- int b = (e!=FTS5_STRING && e!=FTS5_TERM && e!=FTS5_EOF);
+ break;
+ }
+
+ for(i=0; i<pExpr->nChild; i++){
+ char *z = fts5ExprPrint(pConfig, pExpr->apChild[i]);
+ if( z==0 ){
+ sqlite3_free(zRet);
+ zRet = 0;
+ }else{
+ int e = pExpr->apChild[i]->eType;
+ int b = (e!=FTS5_STRING && e!=FTS5_TERM && e!=FTS5_EOF);
zRet = fts5PrintfAppend(zRet, "%s%s%z%s",
- (i==0 ? "" : zOp),
- (b?"(":""), z, (b?")":"")
- );
- }
- if( zRet==0 ) break;
- }
- }
-
- return zRet;
-}
-
-/*
-** The implementation of user-defined scalar functions fts5_expr() (bTcl==0)
-** and fts5_expr_tcl() (bTcl!=0).
-*/
-static void fts5ExprFunction(
- sqlite3_context *pCtx, /* Function call context */
- int nArg, /* Number of args */
- sqlite3_value **apVal, /* Function arguments */
- int bTcl
-){
- Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
- sqlite3 *db = sqlite3_context_db_handle(pCtx);
- const char *zExpr = 0;
- char *zErr = 0;
- Fts5Expr *pExpr = 0;
- int rc;
- int i;
-
- const char **azConfig; /* Array of arguments for Fts5Config */
- const char *zNearsetCmd = "nearset";
- int nConfig; /* Size of azConfig[] */
- Fts5Config *pConfig = 0;
- int iArg = 1;
-
- if( nArg<1 ){
- zErr = sqlite3_mprintf("wrong number of arguments to function %s",
- bTcl ? "fts5_expr_tcl" : "fts5_expr"
- );
- sqlite3_result_error(pCtx, zErr, -1);
- sqlite3_free(zErr);
- return;
- }
-
- if( bTcl && nArg>1 ){
- zNearsetCmd = (const char*)sqlite3_value_text(apVal[1]);
- iArg = 2;
- }
-
- nConfig = 3 + (nArg-iArg);
+ (i==0 ? "" : zOp),
+ (b?"(":""), z, (b?")":"")
+ );
+ }
+ if( zRet==0 ) break;
+ }
+ }
+
+ return zRet;
+}
+
+/*
+** The implementation of user-defined scalar functions fts5_expr() (bTcl==0)
+** and fts5_expr_tcl() (bTcl!=0).
+*/
+static void fts5ExprFunction(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal, /* Function arguments */
+ int bTcl
+){
+ Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
+ sqlite3 *db = sqlite3_context_db_handle(pCtx);
+ const char *zExpr = 0;
+ char *zErr = 0;
+ Fts5Expr *pExpr = 0;
+ int rc;
+ int i;
+
+ const char **azConfig; /* Array of arguments for Fts5Config */
+ const char *zNearsetCmd = "nearset";
+ int nConfig; /* Size of azConfig[] */
+ Fts5Config *pConfig = 0;
+ int iArg = 1;
+
+ if( nArg<1 ){
+ zErr = sqlite3_mprintf("wrong number of arguments to function %s",
+ bTcl ? "fts5_expr_tcl" : "fts5_expr"
+ );
+ sqlite3_result_error(pCtx, zErr, -1);
+ sqlite3_free(zErr);
+ return;
+ }
+
+ if( bTcl && nArg>1 ){
+ zNearsetCmd = (const char*)sqlite3_value_text(apVal[1]);
+ iArg = 2;
+ }
+
+ nConfig = 3 + (nArg-iArg);
azConfig = (const char**)sqlite3_malloc64(sizeof(char*) * nConfig);
- if( azConfig==0 ){
- sqlite3_result_error_nomem(pCtx);
- return;
- }
- azConfig[0] = 0;
- azConfig[1] = "main";
- azConfig[2] = "tbl";
- for(i=3; iArg<nArg; iArg++){
+ if( azConfig==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ return;
+ }
+ azConfig[0] = 0;
+ azConfig[1] = "main";
+ azConfig[2] = "tbl";
+ for(i=3; iArg<nArg; iArg++){
const char *z = (const char*)sqlite3_value_text(apVal[iArg]);
azConfig[i++] = (z ? z : "");
- }
-
- zExpr = (const char*)sqlite3_value_text(apVal[0]);
+ }
+
+ zExpr = (const char*)sqlite3_value_text(apVal[0]);
if( zExpr==0 ) zExpr = "";
-
- rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
- if( rc==SQLITE_OK ){
+
+ rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
+ if( rc==SQLITE_OK ){
rc = sqlite3Fts5ExprNew(pConfig, 0, pConfig->nCol, zExpr, &pExpr, &zErr);
- }
- if( rc==SQLITE_OK ){
- char *zText;
- if( pExpr->pRoot->xNext==0 ){
- zText = sqlite3_mprintf("");
- }else if( bTcl ){
- zText = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->pRoot);
- }else{
- zText = fts5ExprPrint(pConfig, pExpr->pRoot);
- }
- if( zText==0 ){
- rc = SQLITE_NOMEM;
- }else{
- sqlite3_result_text(pCtx, zText, -1, SQLITE_TRANSIENT);
- sqlite3_free(zText);
- }
- }
-
- if( rc!=SQLITE_OK ){
- if( zErr ){
- sqlite3_result_error(pCtx, zErr, -1);
- sqlite3_free(zErr);
- }else{
- sqlite3_result_error_code(pCtx, rc);
- }
- }
- sqlite3_free((void *)azConfig);
- sqlite3Fts5ConfigFree(pConfig);
- sqlite3Fts5ExprFree(pExpr);
-}
-
-static void fts5ExprFunctionHr(
- sqlite3_context *pCtx, /* Function call context */
- int nArg, /* Number of args */
- sqlite3_value **apVal /* Function arguments */
-){
- fts5ExprFunction(pCtx, nArg, apVal, 0);
-}
-static void fts5ExprFunctionTcl(
- sqlite3_context *pCtx, /* Function call context */
- int nArg, /* Number of args */
- sqlite3_value **apVal /* Function arguments */
-){
- fts5ExprFunction(pCtx, nArg, apVal, 1);
-}
-
-/*
-** The implementation of an SQLite user-defined-function that accepts a
+ }
+ if( rc==SQLITE_OK ){
+ char *zText;
+ if( pExpr->pRoot->xNext==0 ){
+ zText = sqlite3_mprintf("");
+ }else if( bTcl ){
+ zText = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->pRoot);
+ }else{
+ zText = fts5ExprPrint(pConfig, pExpr->pRoot);
+ }
+ if( zText==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_result_text(pCtx, zText, -1, SQLITE_TRANSIENT);
+ sqlite3_free(zText);
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ if( zErr ){
+ sqlite3_result_error(pCtx, zErr, -1);
+ sqlite3_free(zErr);
+ }else{
+ sqlite3_result_error_code(pCtx, rc);
+ }
+ }
+ sqlite3_free((void *)azConfig);
+ sqlite3Fts5ConfigFree(pConfig);
+ sqlite3Fts5ExprFree(pExpr);
+}
+
+static void fts5ExprFunctionHr(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal /* Function arguments */
+){
+ fts5ExprFunction(pCtx, nArg, apVal, 0);
+}
+static void fts5ExprFunctionTcl(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal /* Function arguments */
+){
+ fts5ExprFunction(pCtx, nArg, apVal, 1);
+}
+
+/*
+** The implementation of an SQLite user-defined-function that accepts a
** single integer as an argument. If the integer is an alpha-numeric
-** unicode code point, 1 is returned. Otherwise 0.
-*/
-static void fts5ExprIsAlnum(
- sqlite3_context *pCtx, /* Function call context */
- int nArg, /* Number of args */
- sqlite3_value **apVal /* Function arguments */
-){
- int iCode;
+** unicode code point, 1 is returned. Otherwise 0.
+*/
+static void fts5ExprIsAlnum(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal /* Function arguments */
+){
+ int iCode;
u8 aArr[32];
- if( nArg!=1 ){
+ if( nArg!=1 ){
sqlite3_result_error(pCtx,
- "wrong number of arguments to function fts5_isalnum", -1
- );
- return;
- }
+ "wrong number of arguments to function fts5_isalnum", -1
+ );
+ return;
+ }
memset(aArr, 0, sizeof(aArr));
sqlite3Fts5UnicodeCatParse("L*", aArr);
sqlite3Fts5UnicodeCatParse("N*", aArr);
sqlite3Fts5UnicodeCatParse("Co", aArr);
- iCode = sqlite3_value_int(apVal[0]);
+ iCode = sqlite3_value_int(apVal[0]);
sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory((u32)iCode)]);
-}
-
-static void fts5ExprFold(
- sqlite3_context *pCtx, /* Function call context */
- int nArg, /* Number of args */
- sqlite3_value **apVal /* Function arguments */
-){
- if( nArg!=1 && nArg!=2 ){
+}
+
+static void fts5ExprFold(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal /* Function arguments */
+){
+ if( nArg!=1 && nArg!=2 ){
sqlite3_result_error(pCtx,
- "wrong number of arguments to function fts5_fold", -1
- );
- }else{
- int iCode;
- int bRemoveDiacritics = 0;
- iCode = sqlite3_value_int(apVal[0]);
- if( nArg==2 ) bRemoveDiacritics = sqlite3_value_int(apVal[1]);
- sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics));
- }
-}
+ "wrong number of arguments to function fts5_fold", -1
+ );
+ }else{
+ int iCode;
+ int bRemoveDiacritics = 0;
+ iCode = sqlite3_value_int(apVal[0]);
+ if( nArg==2 ) bRemoveDiacritics = sqlite3_value_int(apVal[1]);
+ sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics));
+ }
+}
#endif /* ifdef SQLITE_TEST */
-
-/*
-** This is called during initialization to register the fts5_expr() scalar
-** UDF with the SQLite handle passed as the only argument.
-*/
-static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
+
+/*
+** This is called during initialization to register the fts5_expr() scalar
+** UDF with the SQLite handle passed as the only argument.
+*/
+static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
#ifdef SQLITE_TEST
- struct Fts5ExprFunc {
- const char *z;
- void (*x)(sqlite3_context*,int,sqlite3_value**);
- } aFunc[] = {
- { "fts5_expr", fts5ExprFunctionHr },
- { "fts5_expr_tcl", fts5ExprFunctionTcl },
- { "fts5_isalnum", fts5ExprIsAlnum },
- { "fts5_fold", fts5ExprFold },
- };
- int i;
- int rc = SQLITE_OK;
- void *pCtx = (void*)pGlobal;
-
- for(i=0; rc==SQLITE_OK && i<ArraySize(aFunc); i++){
- struct Fts5ExprFunc *p = &aFunc[i];
- rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
- }
+ struct Fts5ExprFunc {
+ const char *z;
+ void (*x)(sqlite3_context*,int,sqlite3_value**);
+ } aFunc[] = {
+ { "fts5_expr", fts5ExprFunctionHr },
+ { "fts5_expr_tcl", fts5ExprFunctionTcl },
+ { "fts5_isalnum", fts5ExprIsAlnum },
+ { "fts5_fold", fts5ExprFold },
+ };
+ int i;
+ int rc = SQLITE_OK;
+ void *pCtx = (void*)pGlobal;
+
+ for(i=0; rc==SQLITE_OK && i<ArraySize(aFunc); i++){
+ struct Fts5ExprFunc *p = &aFunc[i];
+ rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
+ }
#else
int rc = SQLITE_OK;
UNUSED_PARAM2(pGlobal,db);
#endif
-
+
/* Avoid warnings indicating that sqlite3Fts5ParserTrace() and
** sqlite3Fts5ParserFallback() are unused */
-#ifndef NDEBUG
- (void)sqlite3Fts5ParserTrace;
-#endif
+#ifndef NDEBUG
+ (void)sqlite3Fts5ParserTrace;
+#endif
(void)sqlite3Fts5ParserFallback;
-
- return rc;
-}
-
-/*
-** Return the number of phrases in expression pExpr.
-*/
-static int sqlite3Fts5ExprPhraseCount(Fts5Expr *pExpr){
- return (pExpr ? pExpr->nPhrase : 0);
-}
-
-/*
-** Return the number of terms in the iPhrase'th phrase in pExpr.
-*/
-static int sqlite3Fts5ExprPhraseSize(Fts5Expr *pExpr, int iPhrase){
- if( iPhrase<0 || iPhrase>=pExpr->nPhrase ) return 0;
- return pExpr->apExprPhrase[iPhrase]->nTerm;
-}
-
-/*
-** This function is used to access the current position list for phrase
-** iPhrase.
-*/
-static int sqlite3Fts5ExprPoslist(Fts5Expr *pExpr, int iPhrase, const u8 **pa){
- int nRet;
- Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
- Fts5ExprNode *pNode = pPhrase->pNode;
- if( pNode->bEof==0 && pNode->iRowid==pExpr->pRoot->iRowid ){
- *pa = pPhrase->poslist.p;
- nRet = pPhrase->poslist.n;
- }else{
- *pa = 0;
- nRet = 0;
- }
- return nRet;
-}
-
-struct Fts5PoslistPopulator {
- Fts5PoslistWriter writer;
- int bOk; /* True if ok to populate */
- int bMiss;
-};
-
+
+ return rc;
+}
+
+/*
+** Return the number of phrases in expression pExpr.
+*/
+static int sqlite3Fts5ExprPhraseCount(Fts5Expr *pExpr){
+ return (pExpr ? pExpr->nPhrase : 0);
+}
+
+/*
+** Return the number of terms in the iPhrase'th phrase in pExpr.
+*/
+static int sqlite3Fts5ExprPhraseSize(Fts5Expr *pExpr, int iPhrase){
+ if( iPhrase<0 || iPhrase>=pExpr->nPhrase ) return 0;
+ return pExpr->apExprPhrase[iPhrase]->nTerm;
+}
+
+/*
+** This function is used to access the current position list for phrase
+** iPhrase.
+*/
+static int sqlite3Fts5ExprPoslist(Fts5Expr *pExpr, int iPhrase, const u8 **pa){
+ int nRet;
+ Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
+ Fts5ExprNode *pNode = pPhrase->pNode;
+ if( pNode->bEof==0 && pNode->iRowid==pExpr->pRoot->iRowid ){
+ *pa = pPhrase->poslist.p;
+ nRet = pPhrase->poslist.n;
+ }else{
+ *pa = 0;
+ nRet = 0;
+ }
+ return nRet;
+}
+
+struct Fts5PoslistPopulator {
+ Fts5PoslistWriter writer;
+ int bOk; /* True if ok to populate */
+ int bMiss;
+};
+
/*
** Clear the position lists associated with all phrases in the expression
** passed as the first argument. Argument bLive is true if the expression
@@ -222173,429 +222173,429 @@ struct Fts5PoslistPopulator {
** fts5 tables. This implies that all phrases must be at most 1 token
** in size, as phrase matches are not supported without detail=full.
*/
-static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
- Fts5PoslistPopulator *pRet;
+static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
+ Fts5PoslistPopulator *pRet;
pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
- if( pRet ){
- int i;
- memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
- for(i=0; i<pExpr->nPhrase; i++){
- Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
- Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
+ if( pRet ){
+ int i;
+ memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
+ for(i=0; i<pExpr->nPhrase; i++){
+ Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
+ Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
assert( pExpr->apExprPhrase[i]->nTerm<=1 );
if( bLive &&
- (pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
- ){
- pRet[i].bMiss = 1;
- }else{
- pBuf->n = 0;
- }
- }
- }
- return pRet;
-}
-
-struct Fts5ExprCtx {
- Fts5Expr *pExpr;
- Fts5PoslistPopulator *aPopulator;
- i64 iOff;
-};
-typedef struct Fts5ExprCtx Fts5ExprCtx;
-
-/*
-** TODO: Make this more efficient!
-*/
-static int fts5ExprColsetTest(Fts5Colset *pColset, int iCol){
- int i;
- for(i=0; i<pColset->nCol; i++){
- if( pColset->aiCol[i]==iCol ) return 1;
- }
- return 0;
-}
-
-static int fts5ExprPopulatePoslistsCb(
- void *pCtx, /* Copy of 2nd argument to xTokenize() */
- int tflags, /* Mask of FTS5_TOKEN_* flags */
- const char *pToken, /* Pointer to buffer containing token */
- int nToken, /* Size of token in bytes */
- int iUnused1, /* Byte offset of token within input text */
- int iUnused2 /* Byte offset of end of token within input text */
-){
- Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx;
- Fts5Expr *pExpr = p->pExpr;
- int i;
-
- UNUSED_PARAM2(iUnused1, iUnused2);
-
- if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
- if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
- for(i=0; i<pExpr->nPhrase; i++){
- Fts5ExprTerm *pTerm;
- if( p->aPopulator[i].bOk==0 ) continue;
- for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
- int nTerm = (int)strlen(pTerm->zTerm);
- if( (nTerm==nToken || (nTerm<nToken && pTerm->bPrefix))
- && memcmp(pTerm->zTerm, pToken, nTerm)==0
- ){
- int rc = sqlite3Fts5PoslistWriterAppend(
- &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
- );
- if( rc ) return rc;
- break;
- }
- }
- }
- return SQLITE_OK;
-}
-
-static int sqlite3Fts5ExprPopulatePoslists(
- Fts5Config *pConfig,
+ (pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
+ ){
+ pRet[i].bMiss = 1;
+ }else{
+ pBuf->n = 0;
+ }
+ }
+ }
+ return pRet;
+}
+
+struct Fts5ExprCtx {
+ Fts5Expr *pExpr;
+ Fts5PoslistPopulator *aPopulator;
+ i64 iOff;
+};
+typedef struct Fts5ExprCtx Fts5ExprCtx;
+
+/*
+** TODO: Make this more efficient!
+*/
+static int fts5ExprColsetTest(Fts5Colset *pColset, int iCol){
+ int i;
+ for(i=0; i<pColset->nCol; i++){
+ if( pColset->aiCol[i]==iCol ) return 1;
+ }
+ return 0;
+}
+
+static int fts5ExprPopulatePoslistsCb(
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Pointer to buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iUnused1, /* Byte offset of token within input text */
+ int iUnused2 /* Byte offset of end of token within input text */
+){
+ Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx;
+ Fts5Expr *pExpr = p->pExpr;
+ int i;
+
+ UNUSED_PARAM2(iUnused1, iUnused2);
+
+ if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
+ for(i=0; i<pExpr->nPhrase; i++){
+ Fts5ExprTerm *pTerm;
+ if( p->aPopulator[i].bOk==0 ) continue;
+ for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
+ int nTerm = (int)strlen(pTerm->zTerm);
+ if( (nTerm==nToken || (nTerm<nToken && pTerm->bPrefix))
+ && memcmp(pTerm->zTerm, pToken, nTerm)==0
+ ){
+ int rc = sqlite3Fts5PoslistWriterAppend(
+ &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
+ );
+ if( rc ) return rc;
+ break;
+ }
+ }
+ }
+ return SQLITE_OK;
+}
+
+static int sqlite3Fts5ExprPopulatePoslists(
+ Fts5Config *pConfig,
Fts5Expr *pExpr,
- Fts5PoslistPopulator *aPopulator,
+ Fts5PoslistPopulator *aPopulator,
int iCol,
- const char *z, int n
-){
- int i;
- Fts5ExprCtx sCtx;
- sCtx.pExpr = pExpr;
- sCtx.aPopulator = aPopulator;
- sCtx.iOff = (((i64)iCol) << 32) - 1;
-
- for(i=0; i<pExpr->nPhrase; i++){
- Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
- Fts5Colset *pColset = pNode->pNear->pColset;
+ const char *z, int n
+){
+ int i;
+ Fts5ExprCtx sCtx;
+ sCtx.pExpr = pExpr;
+ sCtx.aPopulator = aPopulator;
+ sCtx.iOff = (((i64)iCol) << 32) - 1;
+
+ for(i=0; i<pExpr->nPhrase; i++){
+ Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
+ Fts5Colset *pColset = pNode->pNear->pColset;
if( (pColset && 0==fts5ExprColsetTest(pColset, iCol))
- || aPopulator[i].bMiss
- ){
- aPopulator[i].bOk = 0;
- }else{
- aPopulator[i].bOk = 1;
- }
- }
-
+ || aPopulator[i].bMiss
+ ){
+ aPopulator[i].bOk = 0;
+ }else{
+ aPopulator[i].bOk = 1;
+ }
+ }
+
return sqlite3Fts5Tokenize(pConfig,
- FTS5_TOKENIZE_DOCUMENT, z, n, (void*)&sCtx, fts5ExprPopulatePoslistsCb
- );
-}
-
-static void fts5ExprClearPoslists(Fts5ExprNode *pNode){
- if( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING ){
- pNode->pNear->apPhrase[0]->poslist.n = 0;
- }else{
- int i;
- for(i=0; i<pNode->nChild; i++){
- fts5ExprClearPoslists(pNode->apChild[i]);
- }
- }
-}
-
-static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){
- pNode->iRowid = iRowid;
- pNode->bEof = 0;
- switch( pNode->eType ){
- case FTS5_TERM:
- case FTS5_STRING:
- return (pNode->pNear->apPhrase[0]->poslist.n>0);
-
- case FTS5_AND: {
- int i;
- for(i=0; i<pNode->nChild; i++){
- if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid)==0 ){
- fts5ExprClearPoslists(pNode);
- return 0;
- }
- }
- break;
- }
-
- case FTS5_OR: {
- int i;
- int bRet = 0;
- for(i=0; i<pNode->nChild; i++){
- if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid) ){
- bRet = 1;
- }
- }
- return bRet;
- }
-
- default: {
- assert( pNode->eType==FTS5_NOT );
- if( 0==fts5ExprCheckPoslists(pNode->apChild[0], iRowid)
- || 0!=fts5ExprCheckPoslists(pNode->apChild[1], iRowid)
- ){
- fts5ExprClearPoslists(pNode);
- return 0;
- }
- break;
- }
- }
- return 1;
-}
-
-static void sqlite3Fts5ExprCheckPoslists(Fts5Expr *pExpr, i64 iRowid){
- fts5ExprCheckPoslists(pExpr->pRoot, iRowid);
-}
-
-/*
+ FTS5_TOKENIZE_DOCUMENT, z, n, (void*)&sCtx, fts5ExprPopulatePoslistsCb
+ );
+}
+
+static void fts5ExprClearPoslists(Fts5ExprNode *pNode){
+ if( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING ){
+ pNode->pNear->apPhrase[0]->poslist.n = 0;
+ }else{
+ int i;
+ for(i=0; i<pNode->nChild; i++){
+ fts5ExprClearPoslists(pNode->apChild[i]);
+ }
+ }
+}
+
+static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){
+ pNode->iRowid = iRowid;
+ pNode->bEof = 0;
+ switch( pNode->eType ){
+ case FTS5_TERM:
+ case FTS5_STRING:
+ return (pNode->pNear->apPhrase[0]->poslist.n>0);
+
+ case FTS5_AND: {
+ int i;
+ for(i=0; i<pNode->nChild; i++){
+ if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid)==0 ){
+ fts5ExprClearPoslists(pNode);
+ return 0;
+ }
+ }
+ break;
+ }
+
+ case FTS5_OR: {
+ int i;
+ int bRet = 0;
+ for(i=0; i<pNode->nChild; i++){
+ if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid) ){
+ bRet = 1;
+ }
+ }
+ return bRet;
+ }
+
+ default: {
+ assert( pNode->eType==FTS5_NOT );
+ if( 0==fts5ExprCheckPoslists(pNode->apChild[0], iRowid)
+ || 0!=fts5ExprCheckPoslists(pNode->apChild[1], iRowid)
+ ){
+ fts5ExprClearPoslists(pNode);
+ return 0;
+ }
+ break;
+ }
+ }
+ return 1;
+}
+
+static void sqlite3Fts5ExprCheckPoslists(Fts5Expr *pExpr, i64 iRowid){
+ fts5ExprCheckPoslists(pExpr->pRoot, iRowid);
+}
+
+/*
** This function is only called for detail=columns tables.
-*/
-static int sqlite3Fts5ExprPhraseCollist(
+*/
+static int sqlite3Fts5ExprPhraseCollist(
Fts5Expr *pExpr,
int iPhrase,
const u8 **ppCollist,
- int *pnCollist
-){
- Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
- Fts5ExprNode *pNode = pPhrase->pNode;
- int rc = SQLITE_OK;
-
- assert( iPhrase>=0 && iPhrase<pExpr->nPhrase );
- assert( pExpr->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
-
+ int *pnCollist
+){
+ Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
+ Fts5ExprNode *pNode = pPhrase->pNode;
+ int rc = SQLITE_OK;
+
+ assert( iPhrase>=0 && iPhrase<pExpr->nPhrase );
+ assert( pExpr->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
+
if( pNode->bEof==0
&& pNode->iRowid==pExpr->pRoot->iRowid
- && pPhrase->poslist.n>0
- ){
- Fts5ExprTerm *pTerm = &pPhrase->aTerm[0];
- if( pTerm->pSynonym ){
- Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1];
- rc = fts5ExprSynonymList(
- pTerm, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist
- );
- }else{
- *ppCollist = pPhrase->aTerm[0].pIter->pData;
- *pnCollist = pPhrase->aTerm[0].pIter->nData;
- }
- }else{
- *ppCollist = 0;
- *pnCollist = 0;
- }
-
- return rc;
-}
-
-/*
-** 2014 August 11
-**
-** 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.
-**
-******************************************************************************
-**
-*/
-
-
-
-/* #include "fts5Int.h" */
-
-typedef struct Fts5HashEntry Fts5HashEntry;
-
-/*
-** This file contains the implementation of an in-memory hash table used
-** to accumuluate "term -> doclist" content before it is flused to a level-0
-** segment.
-*/
-
-
-struct Fts5Hash {
- int eDetail; /* Copy of Fts5Config.eDetail */
- int *pnByte; /* Pointer to bytes counter */
- int nEntry; /* Number of entries currently in hash */
- int nSlot; /* Size of aSlot[] array */
- Fts5HashEntry *pScan; /* Current ordered scan item */
- Fts5HashEntry **aSlot; /* Array of hash slots */
-};
-
-/*
+ && pPhrase->poslist.n>0
+ ){
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[0];
+ if( pTerm->pSynonym ){
+ Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1];
+ rc = fts5ExprSynonymList(
+ pTerm, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist
+ );
+ }else{
+ *ppCollist = pPhrase->aTerm[0].pIter->pData;
+ *pnCollist = pPhrase->aTerm[0].pIter->nData;
+ }
+ }else{
+ *ppCollist = 0;
+ *pnCollist = 0;
+ }
+
+ return rc;
+}
+
+/*
+** 2014 August 11
+**
+** 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.
+**
+******************************************************************************
+**
+*/
+
+
+
+/* #include "fts5Int.h" */
+
+typedef struct Fts5HashEntry Fts5HashEntry;
+
+/*
+** This file contains the implementation of an in-memory hash table used
+** to accumuluate "term -> doclist" content before it is flused to a level-0
+** segment.
+*/
+
+
+struct Fts5Hash {
+ int eDetail; /* Copy of Fts5Config.eDetail */
+ int *pnByte; /* Pointer to bytes counter */
+ int nEntry; /* Number of entries currently in hash */
+ int nSlot; /* Size of aSlot[] array */
+ Fts5HashEntry *pScan; /* Current ordered scan item */
+ Fts5HashEntry **aSlot; /* Array of hash slots */
+};
+
+/*
** Each entry in the hash table is represented by an object of the
** following type. Each object, its key (a nul-terminated string) and
** its current data are stored in a single memory allocation. The
-** key immediately follows the object in memory. The position list
-** data immediately follows the key data in memory.
-**
-** The data that follows the key is in a similar, but not identical format
-** to the doclist data stored in the database. It is:
-**
-** * Rowid, as a varint
-** * Position list, without 0x00 terminator.
-** * Size of previous position list and rowid, as a 4 byte
-** big-endian integer.
-**
-** iRowidOff:
-** Offset of last rowid written to data area. Relative to first byte of
-** structure.
-**
-** nData:
-** Bytes of data written since iRowidOff.
-*/
-struct Fts5HashEntry {
- Fts5HashEntry *pHashNext; /* Next hash entry with same hash-key */
- Fts5HashEntry *pScanNext; /* Next entry in sorted order */
-
- int nAlloc; /* Total size of allocation */
- int iSzPoslist; /* Offset of space for 4-byte poslist size */
- int nData; /* Total bytes of data (incl. structure) */
- int nKey; /* Length of key in bytes */
- u8 bDel; /* Set delete-flag @ iSzPoslist */
- u8 bContent; /* Set content-flag (detail=none mode) */
- i16 iCol; /* Column of last value written */
- int iPos; /* Position of last value written */
- i64 iRowid; /* Rowid of last value written */
-};
-
-/*
-** Eqivalent to:
-**
-** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; }
-*/
-#define fts5EntryKey(p) ( ((char *)(&(p)[1])) )
-
-
-/*
-** Allocate a new hash table.
-*/
-static int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte){
- int rc = SQLITE_OK;
- Fts5Hash *pNew;
-
- *ppNew = pNew = (Fts5Hash*)sqlite3_malloc(sizeof(Fts5Hash));
- if( pNew==0 ){
- rc = SQLITE_NOMEM;
- }else{
+** key immediately follows the object in memory. The position list
+** data immediately follows the key data in memory.
+**
+** The data that follows the key is in a similar, but not identical format
+** to the doclist data stored in the database. It is:
+**
+** * Rowid, as a varint
+** * Position list, without 0x00 terminator.
+** * Size of previous position list and rowid, as a 4 byte
+** big-endian integer.
+**
+** iRowidOff:
+** Offset of last rowid written to data area. Relative to first byte of
+** structure.
+**
+** nData:
+** Bytes of data written since iRowidOff.
+*/
+struct Fts5HashEntry {
+ Fts5HashEntry *pHashNext; /* Next hash entry with same hash-key */
+ Fts5HashEntry *pScanNext; /* Next entry in sorted order */
+
+ int nAlloc; /* Total size of allocation */
+ int iSzPoslist; /* Offset of space for 4-byte poslist size */
+ int nData; /* Total bytes of data (incl. structure) */
+ int nKey; /* Length of key in bytes */
+ u8 bDel; /* Set delete-flag @ iSzPoslist */
+ u8 bContent; /* Set content-flag (detail=none mode) */
+ i16 iCol; /* Column of last value written */
+ int iPos; /* Position of last value written */
+ i64 iRowid; /* Rowid of last value written */
+};
+
+/*
+** Eqivalent to:
+**
+** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; }
+*/
+#define fts5EntryKey(p) ( ((char *)(&(p)[1])) )
+
+
+/*
+** Allocate a new hash table.
+*/
+static int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte){
+ int rc = SQLITE_OK;
+ Fts5Hash *pNew;
+
+ *ppNew = pNew = (Fts5Hash*)sqlite3_malloc(sizeof(Fts5Hash));
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
sqlite3_int64 nByte;
- memset(pNew, 0, sizeof(Fts5Hash));
- pNew->pnByte = pnByte;
- pNew->eDetail = pConfig->eDetail;
-
- pNew->nSlot = 1024;
- nByte = sizeof(Fts5HashEntry*) * pNew->nSlot;
+ memset(pNew, 0, sizeof(Fts5Hash));
+ pNew->pnByte = pnByte;
+ pNew->eDetail = pConfig->eDetail;
+
+ pNew->nSlot = 1024;
+ nByte = sizeof(Fts5HashEntry*) * pNew->nSlot;
pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc64(nByte);
- if( pNew->aSlot==0 ){
- sqlite3_free(pNew);
- *ppNew = 0;
- rc = SQLITE_NOMEM;
- }else{
+ if( pNew->aSlot==0 ){
+ sqlite3_free(pNew);
+ *ppNew = 0;
+ rc = SQLITE_NOMEM;
+ }else{
memset(pNew->aSlot, 0, (size_t)nByte);
- }
- }
- return rc;
-}
-
-/*
-** Free a hash table object.
-*/
-static void sqlite3Fts5HashFree(Fts5Hash *pHash){
- if( pHash ){
- sqlite3Fts5HashClear(pHash);
- sqlite3_free(pHash->aSlot);
- sqlite3_free(pHash);
- }
-}
-
-/*
-** Empty (but do not delete) a hash table.
-*/
-static void sqlite3Fts5HashClear(Fts5Hash *pHash){
- int i;
- for(i=0; i<pHash->nSlot; i++){
- Fts5HashEntry *pNext;
- Fts5HashEntry *pSlot;
- for(pSlot=pHash->aSlot[i]; pSlot; pSlot=pNext){
- pNext = pSlot->pHashNext;
- sqlite3_free(pSlot);
- }
- }
- memset(pHash->aSlot, 0, pHash->nSlot * sizeof(Fts5HashEntry*));
- pHash->nEntry = 0;
-}
-
-static unsigned int fts5HashKey(int nSlot, const u8 *p, int n){
- int i;
- unsigned int h = 13;
- for(i=n-1; i>=0; i--){
- h = (h << 3) ^ h ^ p[i];
- }
- return (h % nSlot);
-}
-
-static unsigned int fts5HashKey2(int nSlot, u8 b, const u8 *p, int n){
- int i;
- unsigned int h = 13;
- for(i=n-1; i>=0; i--){
- h = (h << 3) ^ h ^ p[i];
- }
- h = (h << 3) ^ h ^ b;
- return (h % nSlot);
-}
-
-/*
-** Resize the hash table by doubling the number of slots.
-*/
-static int fts5HashResize(Fts5Hash *pHash){
- int nNew = pHash->nSlot*2;
- int i;
- Fts5HashEntry **apNew;
- Fts5HashEntry **apOld = pHash->aSlot;
-
+ }
+ }
+ return rc;
+}
+
+/*
+** Free a hash table object.
+*/
+static void sqlite3Fts5HashFree(Fts5Hash *pHash){
+ if( pHash ){
+ sqlite3Fts5HashClear(pHash);
+ sqlite3_free(pHash->aSlot);
+ sqlite3_free(pHash);
+ }
+}
+
+/*
+** Empty (but do not delete) a hash table.
+*/
+static void sqlite3Fts5HashClear(Fts5Hash *pHash){
+ int i;
+ for(i=0; i<pHash->nSlot; i++){
+ Fts5HashEntry *pNext;
+ Fts5HashEntry *pSlot;
+ for(pSlot=pHash->aSlot[i]; pSlot; pSlot=pNext){
+ pNext = pSlot->pHashNext;
+ sqlite3_free(pSlot);
+ }
+ }
+ memset(pHash->aSlot, 0, pHash->nSlot * sizeof(Fts5HashEntry*));
+ pHash->nEntry = 0;
+}
+
+static unsigned int fts5HashKey(int nSlot, const u8 *p, int n){
+ int i;
+ unsigned int h = 13;
+ for(i=n-1; i>=0; i--){
+ h = (h << 3) ^ h ^ p[i];
+ }
+ return (h % nSlot);
+}
+
+static unsigned int fts5HashKey2(int nSlot, u8 b, const u8 *p, int n){
+ int i;
+ unsigned int h = 13;
+ for(i=n-1; i>=0; i--){
+ h = (h << 3) ^ h ^ p[i];
+ }
+ h = (h << 3) ^ h ^ b;
+ return (h % nSlot);
+}
+
+/*
+** Resize the hash table by doubling the number of slots.
+*/
+static int fts5HashResize(Fts5Hash *pHash){
+ int nNew = pHash->nSlot*2;
+ int i;
+ Fts5HashEntry **apNew;
+ Fts5HashEntry **apOld = pHash->aSlot;
+
apNew = (Fts5HashEntry**)sqlite3_malloc64(nNew*sizeof(Fts5HashEntry*));
- if( !apNew ) return SQLITE_NOMEM;
- memset(apNew, 0, nNew*sizeof(Fts5HashEntry*));
-
- for(i=0; i<pHash->nSlot; i++){
- while( apOld[i] ){
- unsigned int iHash;
- Fts5HashEntry *p = apOld[i];
- apOld[i] = p->pHashNext;
- iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p),
- (int)strlen(fts5EntryKey(p)));
- p->pHashNext = apNew[iHash];
- apNew[iHash] = p;
- }
- }
-
- sqlite3_free(apOld);
- pHash->nSlot = nNew;
- pHash->aSlot = apNew;
- return SQLITE_OK;
-}
-
+ if( !apNew ) return SQLITE_NOMEM;
+ memset(apNew, 0, nNew*sizeof(Fts5HashEntry*));
+
+ for(i=0; i<pHash->nSlot; i++){
+ while( apOld[i] ){
+ unsigned int iHash;
+ Fts5HashEntry *p = apOld[i];
+ apOld[i] = p->pHashNext;
+ iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p),
+ (int)strlen(fts5EntryKey(p)));
+ p->pHashNext = apNew[iHash];
+ apNew[iHash] = p;
+ }
+ }
+
+ sqlite3_free(apOld);
+ pHash->nSlot = nNew;
+ pHash->aSlot = apNew;
+ return SQLITE_OK;
+}
+
static int fts5HashAddPoslistSize(
Fts5Hash *pHash,
Fts5HashEntry *p,
Fts5HashEntry *p2
){
int nRet = 0;
- if( p->iSzPoslist ){
+ if( p->iSzPoslist ){
u8 *pPtr = p2 ? (u8*)p2 : (u8*)p;
int nData = p->nData;
- if( pHash->eDetail==FTS5_DETAIL_NONE ){
+ if( pHash->eDetail==FTS5_DETAIL_NONE ){
assert( nData==p->iSzPoslist );
- if( p->bDel ){
+ if( p->bDel ){
pPtr[nData++] = 0x00;
- if( p->bContent ){
+ if( p->bContent ){
pPtr[nData++] = 0x00;
- }
- }
- }else{
+ }
+ }
+ }else{
int nSz = (nData - p->iSzPoslist - 1); /* Size in bytes */
- int nPos = nSz*2 + p->bDel; /* Value of nPos field */
-
- assert( p->bDel==0 || p->bDel==1 );
- if( nPos<=127 ){
- pPtr[p->iSzPoslist] = (u8)nPos;
- }else{
- int nByte = sqlite3Fts5GetVarintLen((u32)nPos);
- memmove(&pPtr[p->iSzPoslist + nByte], &pPtr[p->iSzPoslist + 1], nSz);
- sqlite3Fts5PutVarint(&pPtr[p->iSzPoslist], nPos);
+ int nPos = nSz*2 + p->bDel; /* Value of nPos field */
+
+ assert( p->bDel==0 || p->bDel==1 );
+ if( nPos<=127 ){
+ pPtr[p->iSzPoslist] = (u8)nPos;
+ }else{
+ int nByte = sqlite3Fts5GetVarintLen((u32)nPos);
+ memmove(&pPtr[p->iSzPoslist + nByte], &pPtr[p->iSzPoslist + 1], nSz);
+ sqlite3Fts5PutVarint(&pPtr[p->iSzPoslist], nPos);
nData += (nByte-1);
- }
- }
-
+ }
+ }
+
nRet = nData - p->nData;
if( p2==0 ){
p->iSzPoslist = 0;
@@ -222603,282 +222603,282 @@ static int fts5HashAddPoslistSize(
p->bContent = 0;
p->nData = nData;
}
- }
+ }
return nRet;
-}
-
-/*
-** Add an entry to the in-memory hash table. The key is the concatenation
-** of bByte and (pToken/nToken). The value is (iRowid/iCol/iPos).
-**
-** (bByte || pToken) -> (iRowid,iCol,iPos)
-**
-** Or, if iCol is negative, then the value is a delete marker.
-*/
-static int sqlite3Fts5HashWrite(
- Fts5Hash *pHash,
- i64 iRowid, /* Rowid for this entry */
- int iCol, /* Column token appears in (-ve -> delete) */
- int iPos, /* Position of token within column */
- char bByte, /* First byte of token */
- const char *pToken, int nToken /* Token to add or remove to or from index */
-){
- unsigned int iHash;
- Fts5HashEntry *p;
- u8 *pPtr;
- int nIncr = 0; /* Amount to increment (*pHash->pnByte) by */
- int bNew; /* If non-delete entry should be written */
-
- bNew = (pHash->eDetail==FTS5_DETAIL_FULL);
-
- /* Attempt to locate an existing hash entry */
- iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
- for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
- char *zKey = fts5EntryKey(p);
+}
+
+/*
+** Add an entry to the in-memory hash table. The key is the concatenation
+** of bByte and (pToken/nToken). The value is (iRowid/iCol/iPos).
+**
+** (bByte || pToken) -> (iRowid,iCol,iPos)
+**
+** Or, if iCol is negative, then the value is a delete marker.
+*/
+static int sqlite3Fts5HashWrite(
+ Fts5Hash *pHash,
+ i64 iRowid, /* Rowid for this entry */
+ int iCol, /* Column token appears in (-ve -> delete) */
+ int iPos, /* Position of token within column */
+ char bByte, /* First byte of token */
+ const char *pToken, int nToken /* Token to add or remove to or from index */
+){
+ unsigned int iHash;
+ Fts5HashEntry *p;
+ u8 *pPtr;
+ int nIncr = 0; /* Amount to increment (*pHash->pnByte) by */
+ int bNew; /* If non-delete entry should be written */
+
+ bNew = (pHash->eDetail==FTS5_DETAIL_FULL);
+
+ /* Attempt to locate an existing hash entry */
+ iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
+ for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
+ char *zKey = fts5EntryKey(p);
if( zKey[0]==bByte
- && p->nKey==nToken
+ && p->nKey==nToken
&& memcmp(&zKey[1], pToken, nToken)==0
- ){
- break;
- }
- }
-
- /* If an existing hash entry cannot be found, create a new one. */
- if( p==0 ){
- /* Figure out how much space to allocate */
- char *zKey;
+ ){
+ break;
+ }
+ }
+
+ /* If an existing hash entry cannot be found, create a new one. */
+ if( p==0 ){
+ /* Figure out how much space to allocate */
+ char *zKey;
sqlite3_int64 nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
- if( nByte<128 ) nByte = 128;
-
- /* Grow the Fts5Hash.aSlot[] array if necessary. */
- if( (pHash->nEntry*2)>=pHash->nSlot ){
- int rc = fts5HashResize(pHash);
- if( rc!=SQLITE_OK ) return rc;
- iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
- }
-
- /* Allocate new Fts5HashEntry and add it to the hash table. */
+ if( nByte<128 ) nByte = 128;
+
+ /* Grow the Fts5Hash.aSlot[] array if necessary. */
+ if( (pHash->nEntry*2)>=pHash->nSlot ){
+ int rc = fts5HashResize(pHash);
+ if( rc!=SQLITE_OK ) return rc;
+ iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
+ }
+
+ /* Allocate new Fts5HashEntry and add it to the hash table. */
p = (Fts5HashEntry*)sqlite3_malloc64(nByte);
- if( !p ) return SQLITE_NOMEM;
- memset(p, 0, sizeof(Fts5HashEntry));
+ if( !p ) return SQLITE_NOMEM;
+ memset(p, 0, sizeof(Fts5HashEntry));
p->nAlloc = (int)nByte;
- zKey = fts5EntryKey(p);
- zKey[0] = bByte;
- memcpy(&zKey[1], pToken, nToken);
- assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) );
- p->nKey = nToken;
- zKey[nToken+1] = '\0';
- p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry);
- p->pHashNext = pHash->aSlot[iHash];
- pHash->aSlot[iHash] = p;
- pHash->nEntry++;
-
- /* Add the first rowid field to the hash-entry */
- p->nData += sqlite3Fts5PutVarint(&((u8*)p)[p->nData], iRowid);
- p->iRowid = iRowid;
-
- p->iSzPoslist = p->nData;
- if( pHash->eDetail!=FTS5_DETAIL_NONE ){
- p->nData += 1;
- p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
- }
-
- }else{
-
+ zKey = fts5EntryKey(p);
+ zKey[0] = bByte;
+ memcpy(&zKey[1], pToken, nToken);
+ assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) );
+ p->nKey = nToken;
+ zKey[nToken+1] = '\0';
+ p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry);
+ p->pHashNext = pHash->aSlot[iHash];
+ pHash->aSlot[iHash] = p;
+ pHash->nEntry++;
+
+ /* Add the first rowid field to the hash-entry */
+ p->nData += sqlite3Fts5PutVarint(&((u8*)p)[p->nData], iRowid);
+ p->iRowid = iRowid;
+
+ p->iSzPoslist = p->nData;
+ if( pHash->eDetail!=FTS5_DETAIL_NONE ){
+ p->nData += 1;
+ p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
+ }
+
+ }else{
+
/* Appending to an existing hash-entry. Check that there is enough
** space to append the largest possible new entry. Worst case scenario
- ** is:
- **
- ** + 9 bytes for a new rowid,
- ** + 4 byte reserved for the "poslist size" varint.
- ** + 1 byte for a "new column" byte,
- ** + 3 bytes for a new column number (16-bit max) as a varint,
- ** + 5 bytes for the new position offset (32-bit max).
- */
- if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){
+ ** is:
+ **
+ ** + 9 bytes for a new rowid,
+ ** + 4 byte reserved for the "poslist size" varint.
+ ** + 1 byte for a "new column" byte,
+ ** + 3 bytes for a new column number (16-bit max) as a varint,
+ ** + 5 bytes for the new position offset (32-bit max).
+ */
+ if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){
sqlite3_int64 nNew = p->nAlloc * 2;
- Fts5HashEntry *pNew;
- Fts5HashEntry **pp;
+ Fts5HashEntry *pNew;
+ Fts5HashEntry **pp;
pNew = (Fts5HashEntry*)sqlite3_realloc64(p, nNew);
- if( pNew==0 ) return SQLITE_NOMEM;
+ if( pNew==0 ) return SQLITE_NOMEM;
pNew->nAlloc = (int)nNew;
- for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext);
- *pp = pNew;
- p = pNew;
- }
- nIncr -= p->nData;
- }
- assert( (p->nAlloc - p->nData) >= (9 + 4 + 1 + 3 + 5) );
-
- pPtr = (u8*)p;
-
- /* If this is a new rowid, append the 4-byte size field for the previous
- ** entry, and the new rowid for this entry. */
- if( iRowid!=p->iRowid ){
+ for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext);
+ *pp = pNew;
+ p = pNew;
+ }
+ nIncr -= p->nData;
+ }
+ assert( (p->nAlloc - p->nData) >= (9 + 4 + 1 + 3 + 5) );
+
+ pPtr = (u8*)p;
+
+ /* If this is a new rowid, append the 4-byte size field for the previous
+ ** entry, and the new rowid for this entry. */
+ if( iRowid!=p->iRowid ){
u64 iDiff = (u64)iRowid - (u64)p->iRowid;
fts5HashAddPoslistSize(pHash, p, 0);
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iDiff);
- p->iRowid = iRowid;
- bNew = 1;
- p->iSzPoslist = p->nData;
- if( pHash->eDetail!=FTS5_DETAIL_NONE ){
- p->nData += 1;
- p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
- p->iPos = 0;
- }
- }
-
- if( iCol>=0 ){
- if( pHash->eDetail==FTS5_DETAIL_NONE ){
- p->bContent = 1;
- }else{
- /* Append a new column value, if necessary */
+ p->iRowid = iRowid;
+ bNew = 1;
+ p->iSzPoslist = p->nData;
+ if( pHash->eDetail!=FTS5_DETAIL_NONE ){
+ p->nData += 1;
+ p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
+ p->iPos = 0;
+ }
+ }
+
+ if( iCol>=0 ){
+ if( pHash->eDetail==FTS5_DETAIL_NONE ){
+ p->bContent = 1;
+ }else{
+ /* Append a new column value, if necessary */
assert_nc( iCol>=p->iCol );
- if( iCol!=p->iCol ){
- if( pHash->eDetail==FTS5_DETAIL_FULL ){
- pPtr[p->nData++] = 0x01;
- p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
- p->iCol = (i16)iCol;
- p->iPos = 0;
- }else{
- bNew = 1;
- p->iCol = (i16)(iPos = iCol);
- }
- }
-
- /* Append the new position offset, if necessary */
- if( bNew ){
- p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iPos - p->iPos + 2);
- p->iPos = iPos;
- }
- }
- }else{
- /* This is a delete. Set the delete flag. */
- p->bDel = 1;
- }
-
- nIncr += p->nData;
- *pHash->pnByte += nIncr;
- return SQLITE_OK;
-}
-
-
-/*
-** Arguments pLeft and pRight point to linked-lists of hash-entry objects,
-** each sorted in key order. This function merges the two lists into a
-** single list and returns a pointer to its first element.
-*/
-static Fts5HashEntry *fts5HashEntryMerge(
- Fts5HashEntry *pLeft,
- Fts5HashEntry *pRight
-){
- Fts5HashEntry *p1 = pLeft;
- Fts5HashEntry *p2 = pRight;
- Fts5HashEntry *pRet = 0;
- Fts5HashEntry **ppOut = &pRet;
-
- while( p1 || p2 ){
- if( p1==0 ){
- *ppOut = p2;
- p2 = 0;
- }else if( p2==0 ){
- *ppOut = p1;
- p1 = 0;
- }else{
- int i = 0;
- char *zKey1 = fts5EntryKey(p1);
- char *zKey2 = fts5EntryKey(p2);
- while( zKey1[i]==zKey2[i] ) i++;
-
- if( ((u8)zKey1[i])>((u8)zKey2[i]) ){
- /* p2 is smaller */
- *ppOut = p2;
- ppOut = &p2->pScanNext;
- p2 = p2->pScanNext;
- }else{
- /* p1 is smaller */
- *ppOut = p1;
- ppOut = &p1->pScanNext;
- p1 = p1->pScanNext;
- }
- *ppOut = 0;
- }
- }
-
- return pRet;
-}
-
-/*
-** Extract all tokens from hash table iHash and link them into a list
-** in sorted order. The hash table is cleared before returning. It is
-** the responsibility of the caller to free the elements of the returned
-** list.
-*/
-static int fts5HashEntrySort(
+ if( iCol!=p->iCol ){
+ if( pHash->eDetail==FTS5_DETAIL_FULL ){
+ pPtr[p->nData++] = 0x01;
+ p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
+ p->iCol = (i16)iCol;
+ p->iPos = 0;
+ }else{
+ bNew = 1;
+ p->iCol = (i16)(iPos = iCol);
+ }
+ }
+
+ /* Append the new position offset, if necessary */
+ if( bNew ){
+ p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iPos - p->iPos + 2);
+ p->iPos = iPos;
+ }
+ }
+ }else{
+ /* This is a delete. Set the delete flag. */
+ p->bDel = 1;
+ }
+
+ nIncr += p->nData;
+ *pHash->pnByte += nIncr;
+ return SQLITE_OK;
+}
+
+
+/*
+** Arguments pLeft and pRight point to linked-lists of hash-entry objects,
+** each sorted in key order. This function merges the two lists into a
+** single list and returns a pointer to its first element.
+*/
+static Fts5HashEntry *fts5HashEntryMerge(
+ Fts5HashEntry *pLeft,
+ Fts5HashEntry *pRight
+){
+ Fts5HashEntry *p1 = pLeft;
+ Fts5HashEntry *p2 = pRight;
+ Fts5HashEntry *pRet = 0;
+ Fts5HashEntry **ppOut = &pRet;
+
+ while( p1 || p2 ){
+ if( p1==0 ){
+ *ppOut = p2;
+ p2 = 0;
+ }else if( p2==0 ){
+ *ppOut = p1;
+ p1 = 0;
+ }else{
+ int i = 0;
+ char *zKey1 = fts5EntryKey(p1);
+ char *zKey2 = fts5EntryKey(p2);
+ while( zKey1[i]==zKey2[i] ) i++;
+
+ if( ((u8)zKey1[i])>((u8)zKey2[i]) ){
+ /* p2 is smaller */
+ *ppOut = p2;
+ ppOut = &p2->pScanNext;
+ p2 = p2->pScanNext;
+ }else{
+ /* p1 is smaller */
+ *ppOut = p1;
+ ppOut = &p1->pScanNext;
+ p1 = p1->pScanNext;
+ }
+ *ppOut = 0;
+ }
+ }
+
+ return pRet;
+}
+
+/*
+** Extract all tokens from hash table iHash and link them into a list
+** in sorted order. The hash table is cleared before returning. It is
+** the responsibility of the caller to free the elements of the returned
+** list.
+*/
+static int fts5HashEntrySort(
Fts5Hash *pHash,
- const char *pTerm, int nTerm, /* Query prefix, if any */
- Fts5HashEntry **ppSorted
-){
- const int nMergeSlot = 32;
- Fts5HashEntry **ap;
- Fts5HashEntry *pList;
- int iSlot;
- int i;
-
- *ppSorted = 0;
+ const char *pTerm, int nTerm, /* Query prefix, if any */
+ Fts5HashEntry **ppSorted
+){
+ const int nMergeSlot = 32;
+ Fts5HashEntry **ap;
+ Fts5HashEntry *pList;
+ int iSlot;
+ int i;
+
+ *ppSorted = 0;
ap = sqlite3_malloc64(sizeof(Fts5HashEntry*) * nMergeSlot);
- if( !ap ) return SQLITE_NOMEM;
- memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot);
-
- for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
- Fts5HashEntry *pIter;
- for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
+ if( !ap ) return SQLITE_NOMEM;
+ memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot);
+
+ for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
+ Fts5HashEntry *pIter;
+ for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
if( pTerm==0
|| (pIter->nKey+1>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm))
){
- Fts5HashEntry *pEntry = pIter;
- pEntry->pScanNext = 0;
- for(i=0; ap[i]; i++){
- pEntry = fts5HashEntryMerge(pEntry, ap[i]);
- ap[i] = 0;
- }
- ap[i] = pEntry;
- }
- }
- }
-
- pList = 0;
- for(i=0; i<nMergeSlot; i++){
- pList = fts5HashEntryMerge(pList, ap[i]);
- }
-
- pHash->nEntry = 0;
- sqlite3_free(ap);
- *ppSorted = pList;
- return SQLITE_OK;
-}
-
-/*
-** Query the hash table for a doclist associated with term pTerm/nTerm.
-*/
-static int sqlite3Fts5HashQuery(
- Fts5Hash *pHash, /* Hash table to query */
+ Fts5HashEntry *pEntry = pIter;
+ pEntry->pScanNext = 0;
+ for(i=0; ap[i]; i++){
+ pEntry = fts5HashEntryMerge(pEntry, ap[i]);
+ ap[i] = 0;
+ }
+ ap[i] = pEntry;
+ }
+ }
+ }
+
+ pList = 0;
+ for(i=0; i<nMergeSlot; i++){
+ pList = fts5HashEntryMerge(pList, ap[i]);
+ }
+
+ pHash->nEntry = 0;
+ sqlite3_free(ap);
+ *ppSorted = pList;
+ return SQLITE_OK;
+}
+
+/*
+** Query the hash table for a doclist associated with term pTerm/nTerm.
+*/
+static int sqlite3Fts5HashQuery(
+ Fts5Hash *pHash, /* Hash table to query */
int nPre,
- const char *pTerm, int nTerm, /* Query term */
+ const char *pTerm, int nTerm, /* Query term */
void **ppOut, /* OUT: Pointer to new object */
- int *pnDoclist /* OUT: Size of doclist in bytes */
-){
- unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm);
- char *zKey = 0;
- Fts5HashEntry *p;
-
- for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
- zKey = fts5EntryKey(p);
+ int *pnDoclist /* OUT: Size of doclist in bytes */
+){
+ unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm);
+ char *zKey = 0;
+ Fts5HashEntry *p;
+
+ for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
+ zKey = fts5EntryKey(p);
assert( p->nKey+1==(int)strlen(zKey) );
if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break;
- }
-
- if( p ){
+ }
+
+ if( p ){
int nHashPre = sizeof(Fts5HashEntry) + nTerm + 1;
int nList = p->nData - nHashPre;
u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10));
@@ -222891,878 +222891,878 @@ static int sqlite3Fts5HashQuery(
*pnDoclist = 0;
return SQLITE_NOMEM;
}
- }else{
+ }else{
*ppOut = 0;
- *pnDoclist = 0;
- }
-
- return SQLITE_OK;
-}
-
-static int sqlite3Fts5HashScanInit(
- Fts5Hash *p, /* Hash table to query */
- const char *pTerm, int nTerm /* Query prefix */
-){
- return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan);
-}
-
-static void sqlite3Fts5HashScanNext(Fts5Hash *p){
- assert( !sqlite3Fts5HashScanEof(p) );
- p->pScan = p->pScan->pScanNext;
-}
-
-static int sqlite3Fts5HashScanEof(Fts5Hash *p){
- return (p->pScan==0);
-}
-
-static void sqlite3Fts5HashScanEntry(
- Fts5Hash *pHash,
- const char **pzTerm, /* OUT: term (nul-terminated) */
- const u8 **ppDoclist, /* OUT: pointer to doclist */
- int *pnDoclist /* OUT: size of doclist in bytes */
-){
- Fts5HashEntry *p;
- if( (p = pHash->pScan) ){
- char *zKey = fts5EntryKey(p);
- int nTerm = (int)strlen(zKey);
+ *pnDoclist = 0;
+ }
+
+ return SQLITE_OK;
+}
+
+static int sqlite3Fts5HashScanInit(
+ Fts5Hash *p, /* Hash table to query */
+ const char *pTerm, int nTerm /* Query prefix */
+){
+ return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan);
+}
+
+static void sqlite3Fts5HashScanNext(Fts5Hash *p){
+ assert( !sqlite3Fts5HashScanEof(p) );
+ p->pScan = p->pScan->pScanNext;
+}
+
+static int sqlite3Fts5HashScanEof(Fts5Hash *p){
+ return (p->pScan==0);
+}
+
+static void sqlite3Fts5HashScanEntry(
+ Fts5Hash *pHash,
+ const char **pzTerm, /* OUT: term (nul-terminated) */
+ const u8 **ppDoclist, /* OUT: pointer to doclist */
+ int *pnDoclist /* OUT: size of doclist in bytes */
+){
+ Fts5HashEntry *p;
+ if( (p = pHash->pScan) ){
+ char *zKey = fts5EntryKey(p);
+ int nTerm = (int)strlen(zKey);
fts5HashAddPoslistSize(pHash, p, 0);
- *pzTerm = zKey;
- *ppDoclist = (const u8*)&zKey[nTerm+1];
- *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
- }else{
- *pzTerm = 0;
- *ppDoclist = 0;
- *pnDoclist = 0;
- }
-}
-
-/*
-** 2014 May 31
-**
-** 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.
-**
-******************************************************************************
-**
+ *pzTerm = zKey;
+ *ppDoclist = (const u8*)&zKey[nTerm+1];
+ *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
+ }else{
+ *pzTerm = 0;
+ *ppDoclist = 0;
+ *pnDoclist = 0;
+ }
+}
+
+/*
+** 2014 May 31
+**
+** 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.
+**
+******************************************************************************
+**
** Low level access to the FTS index stored in the database file. The
-** routines in this file file implement all read and write access to the
-** %_data table. Other parts of the system access this functionality via
-** the interface defined in fts5Int.h.
-*/
-
-
-/* #include "fts5Int.h" */
-
-/*
-** Overview:
-**
-** The %_data table contains all the FTS indexes for an FTS5 virtual table.
-** As well as the main term index, there may be up to 31 prefix indexes.
-** The format is similar to FTS3/4, except that:
-**
+** routines in this file file implement all read and write access to the
+** %_data table. Other parts of the system access this functionality via
+** the interface defined in fts5Int.h.
+*/
+
+
+/* #include "fts5Int.h" */
+
+/*
+** Overview:
+**
+** The %_data table contains all the FTS indexes for an FTS5 virtual table.
+** As well as the main term index, there may be up to 31 prefix indexes.
+** The format is similar to FTS3/4, except that:
+**
** * all segment b-tree leaf data is stored in fixed size page records
** (e.g. 1000 bytes). A single doclist may span multiple pages. Care is
** taken to ensure it is possible to iterate in either direction through
** the entries in a doclist, or to seek to a specific entry within a
-** doclist, without loading it into memory.
-**
-** * large doclists that span many pages have associated "doclist index"
-** records that contain a copy of the first rowid on each page spanned by
-** the doclist. This is used to speed up seek operations, and merges of
-** large doclists with very small doclists.
-**
-** * extra fields in the "structure record" record the state of ongoing
-** incremental merge operations.
-**
-*/
-
-
-#define FTS5_OPT_WORK_UNIT 1000 /* Number of leaf pages per optimize step */
-#define FTS5_WORK_UNIT 64 /* Number of leaf pages in unit of work */
-
-#define FTS5_MIN_DLIDX_SIZE 4 /* Add dlidx if this many empty pages */
-
-#define FTS5_MAIN_PREFIX '0'
-
-#if FTS5_MAX_PREFIX_INDEXES > 31
-# error "FTS5_MAX_PREFIX_INDEXES is too large"
-#endif
-
-/*
-** Details:
-**
-** The %_data table managed by this module,
-**
-** CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB);
-**
-** , contains the following 5 types of records. See the comments surrounding
+** doclist, without loading it into memory.
+**
+** * large doclists that span many pages have associated "doclist index"
+** records that contain a copy of the first rowid on each page spanned by
+** the doclist. This is used to speed up seek operations, and merges of
+** large doclists with very small doclists.
+**
+** * extra fields in the "structure record" record the state of ongoing
+** incremental merge operations.
+**
+*/
+
+
+#define FTS5_OPT_WORK_UNIT 1000 /* Number of leaf pages per optimize step */
+#define FTS5_WORK_UNIT 64 /* Number of leaf pages in unit of work */
+
+#define FTS5_MIN_DLIDX_SIZE 4 /* Add dlidx if this many empty pages */
+
+#define FTS5_MAIN_PREFIX '0'
+
+#if FTS5_MAX_PREFIX_INDEXES > 31
+# error "FTS5_MAX_PREFIX_INDEXES is too large"
+#endif
+
+/*
+** Details:
+**
+** The %_data table managed by this module,
+**
+** CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB);
+**
+** , contains the following 5 types of records. See the comments surrounding
** the FTS5_*_ROWID macros below for a description of how %_data rowids are
-** assigned to each fo them.
-**
-** 1. Structure Records:
-**
-** The set of segments that make up an index - the index structure - are
-** recorded in a single record within the %_data table. The record consists
+** assigned to each fo them.
+**
+** 1. Structure Records:
+**
+** The set of segments that make up an index - the index structure - are
+** recorded in a single record within the %_data table. The record consists
** of a single 32-bit configuration cookie value followed by a list of
-** SQLite varints. If the FTS table features more than one index (because
-** there are one or more prefix indexes), it is guaranteed that all share
-** the same cookie value.
-**
-** Immediately following the configuration cookie, the record begins with
-** three varints:
-**
-** + number of levels,
-** + total number of segments on all levels,
-** + value of write counter.
-**
-** Then, for each level from 0 to nMax:
-**
-** + number of input segments in ongoing merge.
-** + total number of segments in level.
-** + for each segment from oldest to newest:
-** + segment id (always > 0)
-** + first leaf page number (often 1, always greater than 0)
-** + final leaf page number
-**
-** 2. The Averages Record:
-**
-** A single record within the %_data table. The data is a list of varints.
-** The first value is the number of rows in the index. Then, for each column
-** from left to right, the total number of tokens in the column for all
-** rows of the table.
-**
-** 3. Segment leaves:
-**
-** TERM/DOCLIST FORMAT:
-**
+** SQLite varints. If the FTS table features more than one index (because
+** there are one or more prefix indexes), it is guaranteed that all share
+** the same cookie value.
+**
+** Immediately following the configuration cookie, the record begins with
+** three varints:
+**
+** + number of levels,
+** + total number of segments on all levels,
+** + value of write counter.
+**
+** Then, for each level from 0 to nMax:
+**
+** + number of input segments in ongoing merge.
+** + total number of segments in level.
+** + for each segment from oldest to newest:
+** + segment id (always > 0)
+** + first leaf page number (often 1, always greater than 0)
+** + final leaf page number
+**
+** 2. The Averages Record:
+**
+** A single record within the %_data table. The data is a list of varints.
+** The first value is the number of rows in the index. Then, for each column
+** from left to right, the total number of tokens in the column for all
+** rows of the table.
+**
+** 3. Segment leaves:
+**
+** TERM/DOCLIST FORMAT:
+**
** Most of each segment leaf is taken up by term/doclist data. The
-** general format of term/doclist, starting with the first term
-** on the leaf page, is:
-**
-** varint : size of first term
-** blob: first term data
-** doclist: first doclist
-** zero-or-more {
-** varint: number of bytes in common with previous term
-** varint: number of bytes of new term data (nNew)
-** blob: nNew bytes of new term data
-** doclist: next doclist
-** }
-**
-** doclist format:
-**
-** varint: first rowid
-** poslist: first poslist
-** zero-or-more {
-** varint: rowid delta (always > 0)
-** poslist: next poslist
-** }
-**
-** poslist format:
-**
-** varint: size of poslist in bytes multiplied by 2, not including
-** this field. Plus 1 if this entry carries the "delete" flag.
-** collist: collist for column 0
-** zero-or-more {
-** 0x01 byte
-** varint: column number (I)
-** collist: collist for column I
-** }
-**
-** collist format:
-**
-** varint: first offset + 2
-** zero-or-more {
-** varint: offset delta + 2
-** }
-**
-** PAGE FORMAT
-**
+** general format of term/doclist, starting with the first term
+** on the leaf page, is:
+**
+** varint : size of first term
+** blob: first term data
+** doclist: first doclist
+** zero-or-more {
+** varint: number of bytes in common with previous term
+** varint: number of bytes of new term data (nNew)
+** blob: nNew bytes of new term data
+** doclist: next doclist
+** }
+**
+** doclist format:
+**
+** varint: first rowid
+** poslist: first poslist
+** zero-or-more {
+** varint: rowid delta (always > 0)
+** poslist: next poslist
+** }
+**
+** poslist format:
+**
+** varint: size of poslist in bytes multiplied by 2, not including
+** this field. Plus 1 if this entry carries the "delete" flag.
+** collist: collist for column 0
+** zero-or-more {
+** 0x01 byte
+** varint: column number (I)
+** collist: collist for column I
+** }
+**
+** collist format:
+**
+** varint: first offset + 2
+** zero-or-more {
+** varint: offset delta + 2
+** }
+**
+** PAGE FORMAT
+**
** Each leaf page begins with a 4-byte header containing 2 16-bit
-** unsigned integer fields in big-endian format. They are:
-**
-** * The byte offset of the first rowid on the page, if it exists
-** and occurs before the first term (otherwise 0).
-**
-** * The byte offset of the start of the page footer. If the page
-** footer is 0 bytes in size, then this field is the same as the
-** size of the leaf page in bytes.
-**
-** The page footer consists of a single varint for each term located
-** on the page. Each varint is the byte offset of the current term
-** within the page, delta-compressed against the previous value. In
-** other words, the first varint in the footer is the byte offset of
-** the first term, the second is the byte offset of the second less that
-** of the first, and so on.
-**
-** The term/doclist format described above is accurate if the entire
-** term/doclist data fits on a single leaf page. If this is not the case,
-** the format is changed in two ways:
-**
-** + if the first rowid on a page occurs before the first term, it
-** is stored as a literal value:
-**
-** varint: first rowid
-**
-** + the first term on each page is stored in the same way as the
-** very first term of the segment:
-**
-** varint : size of first term
-** blob: first term data
-**
-** 5. Segment doclist indexes:
-**
-** Doclist indexes are themselves b-trees, however they usually consist of
+** unsigned integer fields in big-endian format. They are:
+**
+** * The byte offset of the first rowid on the page, if it exists
+** and occurs before the first term (otherwise 0).
+**
+** * The byte offset of the start of the page footer. If the page
+** footer is 0 bytes in size, then this field is the same as the
+** size of the leaf page in bytes.
+**
+** The page footer consists of a single varint for each term located
+** on the page. Each varint is the byte offset of the current term
+** within the page, delta-compressed against the previous value. In
+** other words, the first varint in the footer is the byte offset of
+** the first term, the second is the byte offset of the second less that
+** of the first, and so on.
+**
+** The term/doclist format described above is accurate if the entire
+** term/doclist data fits on a single leaf page. If this is not the case,
+** the format is changed in two ways:
+**
+** + if the first rowid on a page occurs before the first term, it
+** is stored as a literal value:
+**
+** varint: first rowid
+**
+** + the first term on each page is stored in the same way as the
+** very first term of the segment:
+**
+** varint : size of first term
+** blob: first term data
+**
+** 5. Segment doclist indexes:
+**
+** Doclist indexes are themselves b-trees, however they usually consist of
** a single leaf record only. The format of each doclist index leaf page
-** is:
-**
-** * Flags byte. Bits are:
-** 0x01: Clear if leaf is also the root page, otherwise set.
-**
-** * Page number of fts index leaf page. As a varint.
-**
-** * First rowid on page indicated by previous field. As a varint.
-**
+** is:
+**
+** * Flags byte. Bits are:
+** 0x01: Clear if leaf is also the root page, otherwise set.
+**
+** * Page number of fts index leaf page. As a varint.
+**
+** * First rowid on page indicated by previous field. As a varint.
+**
** * A list of varints, one for each subsequent termless page. A
** positive delta if the termless page contains at least one rowid,
-** or an 0x00 byte otherwise.
-**
-** Internal doclist index nodes are:
-**
-** * Flags byte. Bits are:
-** 0x01: Clear for root page, otherwise set.
-**
-** * Page number of first child page. As a varint.
-**
-** * Copy of first rowid on page indicated by previous field. As a varint.
-**
-** * A list of delta-encoded varints - the first rowid on each subsequent
+** or an 0x00 byte otherwise.
+**
+** Internal doclist index nodes are:
+**
+** * Flags byte. Bits are:
+** 0x01: Clear for root page, otherwise set.
+**
+** * Page number of first child page. As a varint.
+**
+** * Copy of first rowid on page indicated by previous field. As a varint.
+**
+** * A list of delta-encoded varints - the first rowid on each subsequent
** child page.
-**
-*/
-
-/*
-** Rowids for the averages and structure records in the %_data table.
-*/
-#define FTS5_AVERAGES_ROWID 1 /* Rowid used for the averages record */
-#define FTS5_STRUCTURE_ROWID 10 /* The structure record */
-
-/*
-** Macros determining the rowids used by segment leaves and dlidx leaves
-** and nodes. All nodes and leaves are stored in the %_data table with large
-** positive rowids.
-**
-** Each segment has a unique non-zero 16-bit id.
-**
+**
+*/
+
+/*
+** Rowids for the averages and structure records in the %_data table.
+*/
+#define FTS5_AVERAGES_ROWID 1 /* Rowid used for the averages record */
+#define FTS5_STRUCTURE_ROWID 10 /* The structure record */
+
+/*
+** Macros determining the rowids used by segment leaves and dlidx leaves
+** and nodes. All nodes and leaves are stored in the %_data table with large
+** positive rowids.
+**
+** Each segment has a unique non-zero 16-bit id.
+**
** The rowid for each segment leaf is found by passing the segment id and
-** the leaf page number to the FTS5_SEGMENT_ROWID macro. Leaves are numbered
-** sequentially starting from 1.
-*/
-#define FTS5_DATA_ID_B 16 /* Max seg id number 65535 */
-#define FTS5_DATA_DLI_B 1 /* Doclist-index flag (1 bit) */
-#define FTS5_DATA_HEIGHT_B 5 /* Max dlidx tree height of 32 */
-#define FTS5_DATA_PAGE_B 31 /* Max page number of 2147483648 */
-
-#define fts5_dri(segid, dlidx, height, pgno) ( \
- ((i64)(segid) << (FTS5_DATA_PAGE_B+FTS5_DATA_HEIGHT_B+FTS5_DATA_DLI_B)) + \
- ((i64)(dlidx) << (FTS5_DATA_PAGE_B + FTS5_DATA_HEIGHT_B)) + \
- ((i64)(height) << (FTS5_DATA_PAGE_B)) + \
- ((i64)(pgno)) \
-)
-
-#define FTS5_SEGMENT_ROWID(segid, pgno) fts5_dri(segid, 0, 0, pgno)
-#define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno)
-
-#ifdef SQLITE_DEBUG
-static int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; }
-#endif
-
-
-/*
-** Each time a blob is read from the %_data table, it is padded with this
-** many zero bytes. This makes it easier to decode the various record formats
-** without overreading if the records are corrupt.
-*/
-#define FTS5_DATA_ZERO_PADDING 8
-#define FTS5_DATA_PADDING 20
-
-typedef struct Fts5Data Fts5Data;
-typedef struct Fts5DlidxIter Fts5DlidxIter;
-typedef struct Fts5DlidxLvl Fts5DlidxLvl;
-typedef struct Fts5DlidxWriter Fts5DlidxWriter;
-typedef struct Fts5Iter Fts5Iter;
-typedef struct Fts5PageWriter Fts5PageWriter;
-typedef struct Fts5SegIter Fts5SegIter;
-typedef struct Fts5DoclistIter Fts5DoclistIter;
-typedef struct Fts5SegWriter Fts5SegWriter;
-typedef struct Fts5Structure Fts5Structure;
-typedef struct Fts5StructureLevel Fts5StructureLevel;
-typedef struct Fts5StructureSegment Fts5StructureSegment;
-
-struct Fts5Data {
- u8 *p; /* Pointer to buffer containing record */
- int nn; /* Size of record in bytes */
- int szLeaf; /* Size of leaf without page-index */
-};
-
-/*
-** One object per %_data table.
-*/
-struct Fts5Index {
- Fts5Config *pConfig; /* Virtual table configuration */
- char *zDataTbl; /* Name of %_data table */
- int nWorkUnit; /* Leaf pages in a "unit" of work */
-
- /*
- ** Variables related to the accumulation of tokens and doclists within the
- ** in-memory hash tables before they are flushed to disk.
- */
- Fts5Hash *pHash; /* Hash table for in-memory data */
- int nPendingData; /* Current bytes of pending data */
- i64 iWriteRowid; /* Rowid for current doc being written */
- int bDelete; /* Current write is a delete */
-
- /* Error state. */
- int rc; /* Current error code */
-
- /* State used by the fts5DataXXX() functions. */
- sqlite3_blob *pReader; /* RO incr-blob open on %_data table */
- sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */
- sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */
- sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */
- sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */
- sqlite3_stmt *pIdxSelect;
- int nRead; /* Total number of blocks read */
-
- sqlite3_stmt *pDataVersion;
- i64 iStructVersion; /* data_version when pStruct read */
- Fts5Structure *pStruct; /* Current db structure (or NULL) */
-};
-
-struct Fts5DoclistIter {
- u8 *aEof; /* Pointer to 1 byte past end of doclist */
-
- /* Output variables. aPoslist==0 at EOF */
- i64 iRowid;
- u8 *aPoslist;
- int nPoslist;
- int nSize;
-};
-
-/*
-** The contents of the "structure" record for each index are represented
+** the leaf page number to the FTS5_SEGMENT_ROWID macro. Leaves are numbered
+** sequentially starting from 1.
+*/
+#define FTS5_DATA_ID_B 16 /* Max seg id number 65535 */
+#define FTS5_DATA_DLI_B 1 /* Doclist-index flag (1 bit) */
+#define FTS5_DATA_HEIGHT_B 5 /* Max dlidx tree height of 32 */
+#define FTS5_DATA_PAGE_B 31 /* Max page number of 2147483648 */
+
+#define fts5_dri(segid, dlidx, height, pgno) ( \
+ ((i64)(segid) << (FTS5_DATA_PAGE_B+FTS5_DATA_HEIGHT_B+FTS5_DATA_DLI_B)) + \
+ ((i64)(dlidx) << (FTS5_DATA_PAGE_B + FTS5_DATA_HEIGHT_B)) + \
+ ((i64)(height) << (FTS5_DATA_PAGE_B)) + \
+ ((i64)(pgno)) \
+)
+
+#define FTS5_SEGMENT_ROWID(segid, pgno) fts5_dri(segid, 0, 0, pgno)
+#define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno)
+
+#ifdef SQLITE_DEBUG
+static int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; }
+#endif
+
+
+/*
+** Each time a blob is read from the %_data table, it is padded with this
+** many zero bytes. This makes it easier to decode the various record formats
+** without overreading if the records are corrupt.
+*/
+#define FTS5_DATA_ZERO_PADDING 8
+#define FTS5_DATA_PADDING 20
+
+typedef struct Fts5Data Fts5Data;
+typedef struct Fts5DlidxIter Fts5DlidxIter;
+typedef struct Fts5DlidxLvl Fts5DlidxLvl;
+typedef struct Fts5DlidxWriter Fts5DlidxWriter;
+typedef struct Fts5Iter Fts5Iter;
+typedef struct Fts5PageWriter Fts5PageWriter;
+typedef struct Fts5SegIter Fts5SegIter;
+typedef struct Fts5DoclistIter Fts5DoclistIter;
+typedef struct Fts5SegWriter Fts5SegWriter;
+typedef struct Fts5Structure Fts5Structure;
+typedef struct Fts5StructureLevel Fts5StructureLevel;
+typedef struct Fts5StructureSegment Fts5StructureSegment;
+
+struct Fts5Data {
+ u8 *p; /* Pointer to buffer containing record */
+ int nn; /* Size of record in bytes */
+ int szLeaf; /* Size of leaf without page-index */
+};
+
+/*
+** One object per %_data table.
+*/
+struct Fts5Index {
+ Fts5Config *pConfig; /* Virtual table configuration */
+ char *zDataTbl; /* Name of %_data table */
+ int nWorkUnit; /* Leaf pages in a "unit" of work */
+
+ /*
+ ** Variables related to the accumulation of tokens and doclists within the
+ ** in-memory hash tables before they are flushed to disk.
+ */
+ Fts5Hash *pHash; /* Hash table for in-memory data */
+ int nPendingData; /* Current bytes of pending data */
+ i64 iWriteRowid; /* Rowid for current doc being written */
+ int bDelete; /* Current write is a delete */
+
+ /* Error state. */
+ int rc; /* Current error code */
+
+ /* State used by the fts5DataXXX() functions. */
+ sqlite3_blob *pReader; /* RO incr-blob open on %_data table */
+ sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */
+ sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */
+ sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */
+ sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */
+ sqlite3_stmt *pIdxSelect;
+ int nRead; /* Total number of blocks read */
+
+ sqlite3_stmt *pDataVersion;
+ i64 iStructVersion; /* data_version when pStruct read */
+ Fts5Structure *pStruct; /* Current db structure (or NULL) */
+};
+
+struct Fts5DoclistIter {
+ u8 *aEof; /* Pointer to 1 byte past end of doclist */
+
+ /* Output variables. aPoslist==0 at EOF */
+ i64 iRowid;
+ u8 *aPoslist;
+ int nPoslist;
+ int nSize;
+};
+
+/*
+** The contents of the "structure" record for each index are represented
** using an Fts5Structure record in memory. Which uses instances of the
-** other Fts5StructureXXX types as components.
-*/
-struct Fts5StructureSegment {
- int iSegid; /* Segment id */
- int pgnoFirst; /* First leaf page number in segment */
- int pgnoLast; /* Last leaf page number in segment */
-};
-struct Fts5StructureLevel {
- int nMerge; /* Number of segments in incr-merge */
- int nSeg; /* Total number of segments on level */
- Fts5StructureSegment *aSeg; /* Array of segments. aSeg[0] is oldest. */
-};
-struct Fts5Structure {
- int nRef; /* Object reference count */
- u64 nWriteCounter; /* Total leaves written to level 0 */
- int nSegment; /* Total segments in this structure */
- int nLevel; /* Number of levels in this index */
- Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */
-};
-
-/*
-** An object of type Fts5SegWriter is used to write to segments.
-*/
-struct Fts5PageWriter {
- int pgno; /* Page number for this page */
- int iPrevPgidx; /* Previous value written into pgidx */
- Fts5Buffer buf; /* Buffer containing leaf data */
- Fts5Buffer pgidx; /* Buffer containing page-index */
- Fts5Buffer term; /* Buffer containing previous term on page */
-};
-struct Fts5DlidxWriter {
- int pgno; /* Page number for this page */
- int bPrevValid; /* True if iPrev is valid */
- i64 iPrev; /* Previous rowid value written to page */
- Fts5Buffer buf; /* Buffer containing page data */
-};
-struct Fts5SegWriter {
- int iSegid; /* Segid to write to */
- Fts5PageWriter writer; /* PageWriter object */
- i64 iPrevRowid; /* Previous rowid written to current leaf */
- u8 bFirstRowidInDoclist; /* True if next rowid is first in doclist */
- u8 bFirstRowidInPage; /* True if next rowid is first in page */
- /* TODO1: Can use (writer.pgidx.n==0) instead of bFirstTermInPage */
- u8 bFirstTermInPage; /* True if next term will be first in leaf */
- int nLeafWritten; /* Number of leaf pages written */
- int nEmpty; /* Number of contiguous term-less nodes */
-
- int nDlidx; /* Allocated size of aDlidx[] array */
- Fts5DlidxWriter *aDlidx; /* Array of Fts5DlidxWriter objects */
-
- /* Values to insert into the %_idx table */
- Fts5Buffer btterm; /* Next term to insert into %_idx table */
- int iBtPage; /* Page number corresponding to btterm */
-};
-
-typedef struct Fts5CResult Fts5CResult;
-struct Fts5CResult {
- u16 iFirst; /* aSeg[] index of firstest iterator */
- u8 bTermEq; /* True if the terms are equal */
-};
-
-/*
-** Object for iterating through a single segment, visiting each term/rowid
-** pair in the segment.
-**
-** pSeg:
-** The segment to iterate through.
-**
-** iLeafPgno:
-** Current leaf page number within segment.
-**
-** iLeafOffset:
+** other Fts5StructureXXX types as components.
+*/
+struct Fts5StructureSegment {
+ int iSegid; /* Segment id */
+ int pgnoFirst; /* First leaf page number in segment */
+ int pgnoLast; /* Last leaf page number in segment */
+};
+struct Fts5StructureLevel {
+ int nMerge; /* Number of segments in incr-merge */
+ int nSeg; /* Total number of segments on level */
+ Fts5StructureSegment *aSeg; /* Array of segments. aSeg[0] is oldest. */
+};
+struct Fts5Structure {
+ int nRef; /* Object reference count */
+ u64 nWriteCounter; /* Total leaves written to level 0 */
+ int nSegment; /* Total segments in this structure */
+ int nLevel; /* Number of levels in this index */
+ Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */
+};
+
+/*
+** An object of type Fts5SegWriter is used to write to segments.
+*/
+struct Fts5PageWriter {
+ int pgno; /* Page number for this page */
+ int iPrevPgidx; /* Previous value written into pgidx */
+ Fts5Buffer buf; /* Buffer containing leaf data */
+ Fts5Buffer pgidx; /* Buffer containing page-index */
+ Fts5Buffer term; /* Buffer containing previous term on page */
+};
+struct Fts5DlidxWriter {
+ int pgno; /* Page number for this page */
+ int bPrevValid; /* True if iPrev is valid */
+ i64 iPrev; /* Previous rowid value written to page */
+ Fts5Buffer buf; /* Buffer containing page data */
+};
+struct Fts5SegWriter {
+ int iSegid; /* Segid to write to */
+ Fts5PageWriter writer; /* PageWriter object */
+ i64 iPrevRowid; /* Previous rowid written to current leaf */
+ u8 bFirstRowidInDoclist; /* True if next rowid is first in doclist */
+ u8 bFirstRowidInPage; /* True if next rowid is first in page */
+ /* TODO1: Can use (writer.pgidx.n==0) instead of bFirstTermInPage */
+ u8 bFirstTermInPage; /* True if next term will be first in leaf */
+ int nLeafWritten; /* Number of leaf pages written */
+ int nEmpty; /* Number of contiguous term-less nodes */
+
+ int nDlidx; /* Allocated size of aDlidx[] array */
+ Fts5DlidxWriter *aDlidx; /* Array of Fts5DlidxWriter objects */
+
+ /* Values to insert into the %_idx table */
+ Fts5Buffer btterm; /* Next term to insert into %_idx table */
+ int iBtPage; /* Page number corresponding to btterm */
+};
+
+typedef struct Fts5CResult Fts5CResult;
+struct Fts5CResult {
+ u16 iFirst; /* aSeg[] index of firstest iterator */
+ u8 bTermEq; /* True if the terms are equal */
+};
+
+/*
+** Object for iterating through a single segment, visiting each term/rowid
+** pair in the segment.
+**
+** pSeg:
+** The segment to iterate through.
+**
+** iLeafPgno:
+** Current leaf page number within segment.
+**
+** iLeafOffset:
** Byte offset within the current leaf that is the first byte of the
-** position list data (one byte passed the position-list size field).
-** rowid field of the current entry. Usually this is the size field of the
+** position list data (one byte passed the position-list size field).
+** rowid field of the current entry. Usually this is the size field of the
** position list data. The exception is if the rowid for the current entry
-** is the last thing on the leaf page.
-**
-** pLeaf:
-** Buffer containing current leaf page data. Set to NULL at EOF.
-**
-** iTermLeafPgno, iTermLeafOffset:
-** Leaf page number containing the last term read from the segment. And
-** the offset immediately following the term data.
-**
-** flags:
-** Mask of FTS5_SEGITER_XXX values. Interpreted as follows:
-**
-** FTS5_SEGITER_ONETERM:
+** is the last thing on the leaf page.
+**
+** pLeaf:
+** Buffer containing current leaf page data. Set to NULL at EOF.
+**
+** iTermLeafPgno, iTermLeafOffset:
+** Leaf page number containing the last term read from the segment. And
+** the offset immediately following the term data.
+**
+** flags:
+** Mask of FTS5_SEGITER_XXX values. Interpreted as follows:
+**
+** FTS5_SEGITER_ONETERM:
** If set, set the iterator to point to EOF after the current doclist
-** has been exhausted. Do not proceed to the next term in the segment.
-**
-** FTS5_SEGITER_REVERSE:
-** This flag is only ever set if FTS5_SEGITER_ONETERM is also set. If
-** it is set, iterate through rowid in descending order instead of the
-** default ascending order.
-**
-** iRowidOffset/nRowidOffset/aRowidOffset:
-** These are used if the FTS5_SEGITER_REVERSE flag is set.
-**
-** For each rowid on the page corresponding to the current term, the
-** corresponding aRowidOffset[] entry is set to the byte offset of the
-** start of the "position-list-size" field within the page.
-**
-** iTermIdx:
-** Index of current term on iTermLeafPgno.
-*/
-struct Fts5SegIter {
- Fts5StructureSegment *pSeg; /* Segment to iterate through */
- int flags; /* Mask of configuration flags */
- int iLeafPgno; /* Current leaf page number */
- Fts5Data *pLeaf; /* Current leaf data */
- Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */
+** has been exhausted. Do not proceed to the next term in the segment.
+**
+** FTS5_SEGITER_REVERSE:
+** This flag is only ever set if FTS5_SEGITER_ONETERM is also set. If
+** it is set, iterate through rowid in descending order instead of the
+** default ascending order.
+**
+** iRowidOffset/nRowidOffset/aRowidOffset:
+** These are used if the FTS5_SEGITER_REVERSE flag is set.
+**
+** For each rowid on the page corresponding to the current term, the
+** corresponding aRowidOffset[] entry is set to the byte offset of the
+** start of the "position-list-size" field within the page.
+**
+** iTermIdx:
+** Index of current term on iTermLeafPgno.
+*/
+struct Fts5SegIter {
+ Fts5StructureSegment *pSeg; /* Segment to iterate through */
+ int flags; /* Mask of configuration flags */
+ int iLeafPgno; /* Current leaf page number */
+ Fts5Data *pLeaf; /* Current leaf data */
+ Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */
i64 iLeafOffset; /* Byte offset within current leaf */
-
- /* Next method */
- void (*xNext)(Fts5Index*, Fts5SegIter*, int*);
-
+
+ /* Next method */
+ void (*xNext)(Fts5Index*, Fts5SegIter*, int*);
+
/* The page and offset from which the current term was read. The offset
- ** is the offset of the first rowid in the current doclist. */
- int iTermLeafPgno;
- int iTermLeafOffset;
-
- int iPgidxOff; /* Next offset in pgidx */
- int iEndofDoclist;
-
- /* The following are only used if the FTS5_SEGITER_REVERSE flag is set. */
- int iRowidOffset; /* Current entry in aRowidOffset[] */
- int nRowidOffset; /* Allocated size of aRowidOffset[] array */
- int *aRowidOffset; /* Array of offset to rowid fields */
-
- Fts5DlidxIter *pDlidx; /* If there is a doclist-index */
-
- /* Variables populated based on current entry. */
- Fts5Buffer term; /* Current term */
- i64 iRowid; /* Current rowid */
- int nPos; /* Number of bytes in current position list */
- u8 bDel; /* True if the delete flag is set */
-};
-
-/*
+ ** is the offset of the first rowid in the current doclist. */
+ int iTermLeafPgno;
+ int iTermLeafOffset;
+
+ int iPgidxOff; /* Next offset in pgidx */
+ int iEndofDoclist;
+
+ /* The following are only used if the FTS5_SEGITER_REVERSE flag is set. */
+ int iRowidOffset; /* Current entry in aRowidOffset[] */
+ int nRowidOffset; /* Allocated size of aRowidOffset[] array */
+ int *aRowidOffset; /* Array of offset to rowid fields */
+
+ Fts5DlidxIter *pDlidx; /* If there is a doclist-index */
+
+ /* Variables populated based on current entry. */
+ Fts5Buffer term; /* Current term */
+ i64 iRowid; /* Current rowid */
+ int nPos; /* Number of bytes in current position list */
+ u8 bDel; /* True if the delete flag is set */
+};
+
+/*
** Argument is a pointer to an Fts5Data structure that contains a
-** leaf page.
-*/
-#define ASSERT_SZLEAF_OK(x) assert( \
- (x)->szLeaf==(x)->nn || (x)->szLeaf==fts5GetU16(&(x)->p[2]) \
-)
-
-#define FTS5_SEGITER_ONETERM 0x01
-#define FTS5_SEGITER_REVERSE 0x02
-
-/*
-** Argument is a pointer to an Fts5Data structure that contains a leaf
-** page. This macro evaluates to true if the leaf contains no terms, or
-** false if it contains at least one term.
-*/
-#define fts5LeafIsTermless(x) ((x)->szLeaf >= (x)->nn)
-
-#define fts5LeafTermOff(x, i) (fts5GetU16(&(x)->p[(x)->szLeaf + (i)*2]))
-
-#define fts5LeafFirstRowidOff(x) (fts5GetU16((x)->p))
-
-/*
-** Object for iterating through the merged results of one or more segments,
-** visiting each term/rowid pair in the merged data.
-**
-** nSeg is always a power of two greater than or equal to the number of
-** segments that this object is merging data from. Both the aSeg[] and
-** aFirst[] arrays are sized at nSeg entries. The aSeg[] array is padded
-** with zeroed objects - these are handled as if they were iterators opened
-** on empty segments.
-**
-** The results of comparing segments aSeg[N] and aSeg[N+1], where N is an
+** leaf page.
+*/
+#define ASSERT_SZLEAF_OK(x) assert( \
+ (x)->szLeaf==(x)->nn || (x)->szLeaf==fts5GetU16(&(x)->p[2]) \
+)
+
+#define FTS5_SEGITER_ONETERM 0x01
+#define FTS5_SEGITER_REVERSE 0x02
+
+/*
+** Argument is a pointer to an Fts5Data structure that contains a leaf
+** page. This macro evaluates to true if the leaf contains no terms, or
+** false if it contains at least one term.
+*/
+#define fts5LeafIsTermless(x) ((x)->szLeaf >= (x)->nn)
+
+#define fts5LeafTermOff(x, i) (fts5GetU16(&(x)->p[(x)->szLeaf + (i)*2]))
+
+#define fts5LeafFirstRowidOff(x) (fts5GetU16((x)->p))
+
+/*
+** Object for iterating through the merged results of one or more segments,
+** visiting each term/rowid pair in the merged data.
+**
+** nSeg is always a power of two greater than or equal to the number of
+** segments that this object is merging data from. Both the aSeg[] and
+** aFirst[] arrays are sized at nSeg entries. The aSeg[] array is padded
+** with zeroed objects - these are handled as if they were iterators opened
+** on empty segments.
+**
+** The results of comparing segments aSeg[N] and aSeg[N+1], where N is an
** even number, is stored in aFirst[(nSeg+N)/2]. The "result" of the
-** comparison in this context is the index of the iterator that currently
-** points to the smaller term/rowid combination. Iterators at EOF are
-** considered to be greater than all other iterators.
-**
-** aFirst[1] contains the index in aSeg[] of the iterator that points to
+** comparison in this context is the index of the iterator that currently
+** points to the smaller term/rowid combination. Iterators at EOF are
+** considered to be greater than all other iterators.
+**
+** aFirst[1] contains the index in aSeg[] of the iterator that points to
** the smallest key overall. aFirst[0] is unused.
-**
-** poslist:
-** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
-** There is no way to tell if this is populated or not.
-*/
-struct Fts5Iter {
- Fts5IndexIter base; /* Base class containing output vars */
-
- Fts5Index *pIndex; /* Index that owns this iterator */
- Fts5Buffer poslist; /* Buffer containing current poslist */
- Fts5Colset *pColset; /* Restrict matches to these columns */
-
- /* Invoked to set output variables. */
- void (*xSetOutputs)(Fts5Iter*, Fts5SegIter*);
-
- int nSeg; /* Size of aSeg[] array */
- int bRev; /* True to iterate in reverse order */
- u8 bSkipEmpty; /* True to skip deleted entries */
-
- i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */
- Fts5CResult *aFirst; /* Current merge state (see above) */
- Fts5SegIter aSeg[1]; /* Array of segment iterators */
-};
-
-
-/*
-** An instance of the following type is used to iterate through the contents
-** of a doclist-index record.
-**
-** pData:
-** Record containing the doclist-index data.
-**
-** bEof:
-** Set to true once iterator has reached EOF.
-**
-** iOff:
-** Set to the current offset within record pData.
-*/
-struct Fts5DlidxLvl {
- Fts5Data *pData; /* Data for current page of this level */
- int iOff; /* Current offset into pData */
- int bEof; /* At EOF already */
- int iFirstOff; /* Used by reverse iterators */
-
- /* Output variables */
- int iLeafPgno; /* Page number of current leaf page */
- i64 iRowid; /* First rowid on leaf iLeafPgno */
-};
-struct Fts5DlidxIter {
- int nLvl;
- int iSegid;
- Fts5DlidxLvl aLvl[1];
-};
-
-static void fts5PutU16(u8 *aOut, u16 iVal){
- aOut[0] = (iVal>>8);
- aOut[1] = (iVal&0xFF);
-}
-
-static u16 fts5GetU16(const u8 *aIn){
- return ((u16)aIn[0] << 8) + aIn[1];
-}
-
-/*
-** Allocate and return a buffer at least nByte bytes in size.
-**
-** If an OOM error is encountered, return NULL and set the error code in
-** the Fts5Index handle passed as the first argument.
-*/
+**
+** poslist:
+** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
+** There is no way to tell if this is populated or not.
+*/
+struct Fts5Iter {
+ Fts5IndexIter base; /* Base class containing output vars */
+
+ Fts5Index *pIndex; /* Index that owns this iterator */
+ Fts5Buffer poslist; /* Buffer containing current poslist */
+ Fts5Colset *pColset; /* Restrict matches to these columns */
+
+ /* Invoked to set output variables. */
+ void (*xSetOutputs)(Fts5Iter*, Fts5SegIter*);
+
+ int nSeg; /* Size of aSeg[] array */
+ int bRev; /* True to iterate in reverse order */
+ u8 bSkipEmpty; /* True to skip deleted entries */
+
+ i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */
+ Fts5CResult *aFirst; /* Current merge state (see above) */
+ Fts5SegIter aSeg[1]; /* Array of segment iterators */
+};
+
+
+/*
+** An instance of the following type is used to iterate through the contents
+** of a doclist-index record.
+**
+** pData:
+** Record containing the doclist-index data.
+**
+** bEof:
+** Set to true once iterator has reached EOF.
+**
+** iOff:
+** Set to the current offset within record pData.
+*/
+struct Fts5DlidxLvl {
+ Fts5Data *pData; /* Data for current page of this level */
+ int iOff; /* Current offset into pData */
+ int bEof; /* At EOF already */
+ int iFirstOff; /* Used by reverse iterators */
+
+ /* Output variables */
+ int iLeafPgno; /* Page number of current leaf page */
+ i64 iRowid; /* First rowid on leaf iLeafPgno */
+};
+struct Fts5DlidxIter {
+ int nLvl;
+ int iSegid;
+ Fts5DlidxLvl aLvl[1];
+};
+
+static void fts5PutU16(u8 *aOut, u16 iVal){
+ aOut[0] = (iVal>>8);
+ aOut[1] = (iVal&0xFF);
+}
+
+static u16 fts5GetU16(const u8 *aIn){
+ return ((u16)aIn[0] << 8) + aIn[1];
+}
+
+/*
+** Allocate and return a buffer at least nByte bytes in size.
+**
+** If an OOM error is encountered, return NULL and set the error code in
+** the Fts5Index handle passed as the first argument.
+*/
static void *fts5IdxMalloc(Fts5Index *p, sqlite3_int64 nByte){
- return sqlite3Fts5MallocZero(&p->rc, nByte);
-}
-
-/*
-** Compare the contents of the pLeft buffer with the pRight/nRight blob.
-**
-** Return -ve if pLeft is smaller than pRight, 0 if they are equal or
-** +ve if pRight is smaller than pLeft. In other words:
-**
-** res = *pLeft - *pRight
-*/
-#ifdef SQLITE_DEBUG
-static int fts5BufferCompareBlob(
- Fts5Buffer *pLeft, /* Left hand side of comparison */
- const u8 *pRight, int nRight /* Right hand side of comparison */
-){
- int nCmp = MIN(pLeft->n, nRight);
- int res = memcmp(pLeft->p, pRight, nCmp);
- return (res==0 ? (pLeft->n - nRight) : res);
-}
-#endif
-
-/*
-** Compare the contents of the two buffers using memcmp(). If one buffer
-** is a prefix of the other, it is considered the lesser.
-**
-** Return -ve if pLeft is smaller than pRight, 0 if they are equal or
-** +ve if pRight is smaller than pLeft. In other words:
-**
-** res = *pLeft - *pRight
-*/
-static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
+ return sqlite3Fts5MallocZero(&p->rc, nByte);
+}
+
+/*
+** Compare the contents of the pLeft buffer with the pRight/nRight blob.
+**
+** Return -ve if pLeft is smaller than pRight, 0 if they are equal or
+** +ve if pRight is smaller than pLeft. In other words:
+**
+** res = *pLeft - *pRight
+*/
+#ifdef SQLITE_DEBUG
+static int fts5BufferCompareBlob(
+ Fts5Buffer *pLeft, /* Left hand side of comparison */
+ const u8 *pRight, int nRight /* Right hand side of comparison */
+){
+ int nCmp = MIN(pLeft->n, nRight);
+ int res = memcmp(pLeft->p, pRight, nCmp);
+ return (res==0 ? (pLeft->n - nRight) : res);
+}
+#endif
+
+/*
+** Compare the contents of the two buffers using memcmp(). If one buffer
+** is a prefix of the other, it is considered the lesser.
+**
+** Return -ve if pLeft is smaller than pRight, 0 if they are equal or
+** +ve if pRight is smaller than pLeft. In other words:
+**
+** res = *pLeft - *pRight
+*/
+static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
int nCmp, res;
nCmp = MIN(pLeft->n, pRight->n);
assert( nCmp<=0 || pLeft->p!=0 );
assert( nCmp<=0 || pRight->p!=0 );
res = fts5Memcmp(pLeft->p, pRight->p, nCmp);
- return (res==0 ? (pLeft->n - pRight->n) : res);
-}
-
-static int fts5LeafFirstTermOff(Fts5Data *pLeaf){
- int ret;
- fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret);
- return ret;
-}
-
-/*
-** Close the read-only blob handle, if it is open.
-*/
+ return (res==0 ? (pLeft->n - pRight->n) : res);
+}
+
+static int fts5LeafFirstTermOff(Fts5Data *pLeaf){
+ int ret;
+ fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret);
+ return ret;
+}
+
+/*
+** Close the read-only blob handle, if it is open.
+*/
static void sqlite3Fts5IndexCloseReader(Fts5Index *p){
- if( p->pReader ){
- sqlite3_blob *pReader = p->pReader;
- p->pReader = 0;
- sqlite3_blob_close(pReader);
- }
-}
-
-/*
-** Retrieve a record from the %_data table.
-**
+ if( p->pReader ){
+ sqlite3_blob *pReader = p->pReader;
+ p->pReader = 0;
+ sqlite3_blob_close(pReader);
+ }
+}
+
+/*
+** Retrieve a record from the %_data table.
+**
** If an error occurs, NULL is returned and an error left in the
-** Fts5Index object.
-*/
-static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
- Fts5Data *pRet = 0;
- if( p->rc==SQLITE_OK ){
- int rc = SQLITE_OK;
-
- if( p->pReader ){
- /* This call may return SQLITE_ABORT if there has been a savepoint
- ** rollback since it was last used. In this case a new blob handle
- ** is required. */
- sqlite3_blob *pBlob = p->pReader;
- p->pReader = 0;
- rc = sqlite3_blob_reopen(pBlob, iRowid);
- assert( p->pReader==0 );
- p->pReader = pBlob;
- if( rc!=SQLITE_OK ){
+** Fts5Index object.
+*/
+static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
+ Fts5Data *pRet = 0;
+ if( p->rc==SQLITE_OK ){
+ int rc = SQLITE_OK;
+
+ if( p->pReader ){
+ /* This call may return SQLITE_ABORT if there has been a savepoint
+ ** rollback since it was last used. In this case a new blob handle
+ ** is required. */
+ sqlite3_blob *pBlob = p->pReader;
+ p->pReader = 0;
+ rc = sqlite3_blob_reopen(pBlob, iRowid);
+ assert( p->pReader==0 );
+ p->pReader = pBlob;
+ if( rc!=SQLITE_OK ){
sqlite3Fts5IndexCloseReader(p);
- }
- if( rc==SQLITE_ABORT ) rc = SQLITE_OK;
- }
-
+ }
+ if( rc==SQLITE_ABORT ) rc = SQLITE_OK;
+ }
+
/* If the blob handle is not open at this point, open it and seek
- ** to the requested entry. */
- if( p->pReader==0 && rc==SQLITE_OK ){
- Fts5Config *pConfig = p->pConfig;
+ ** to the requested entry. */
+ if( p->pReader==0 && rc==SQLITE_OK ){
+ Fts5Config *pConfig = p->pConfig;
rc = sqlite3_blob_open(pConfig->db,
- pConfig->zDb, p->zDataTbl, "block", iRowid, 0, &p->pReader
- );
- }
-
- /* If either of the sqlite3_blob_open() or sqlite3_blob_reopen() calls
- ** above returned SQLITE_ERROR, return SQLITE_CORRUPT_VTAB instead.
- ** All the reasons those functions might return SQLITE_ERROR - missing
+ pConfig->zDb, p->zDataTbl, "block", iRowid, 0, &p->pReader
+ );
+ }
+
+ /* If either of the sqlite3_blob_open() or sqlite3_blob_reopen() calls
+ ** above returned SQLITE_ERROR, return SQLITE_CORRUPT_VTAB instead.
+ ** All the reasons those functions might return SQLITE_ERROR - missing
** table, missing row, non-blob/text in block column - indicate
- ** backing store corruption. */
- if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT;
-
- if( rc==SQLITE_OK ){
- u8 *aOut = 0; /* Read blob data into this buffer */
- int nByte = sqlite3_blob_bytes(p->pReader);
+ ** backing store corruption. */
+ if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT;
+
+ if( rc==SQLITE_OK ){
+ u8 *aOut = 0; /* Read blob data into this buffer */
+ int nByte = sqlite3_blob_bytes(p->pReader);
sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
- if( pRet ){
- pRet->nn = nByte;
- aOut = pRet->p = (u8*)&pRet[1];
- }else{
- rc = SQLITE_NOMEM;
- }
-
- if( rc==SQLITE_OK ){
- rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0);
- }
- if( rc!=SQLITE_OK ){
- sqlite3_free(pRet);
- pRet = 0;
- }else{
- /* TODO1: Fix this */
+ if( pRet ){
+ pRet->nn = nByte;
+ aOut = pRet->p = (u8*)&pRet[1];
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0);
+ }
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(pRet);
+ pRet = 0;
+ }else{
+ /* TODO1: Fix this */
pRet->p[nByte] = 0x00;
pRet->p[nByte+1] = 0x00;
- pRet->szLeaf = fts5GetU16(&pRet->p[2]);
- }
- }
- p->rc = rc;
- p->nRead++;
- }
-
- assert( (pRet==0)==(p->rc!=SQLITE_OK) );
- return pRet;
-}
-
-
-/*
-** Release a reference to data record returned by an earlier call to
-** fts5DataRead().
-*/
-static void fts5DataRelease(Fts5Data *pData){
- sqlite3_free(pData);
-}
-
-static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
- Fts5Data *pRet = fts5DataRead(p, iRowid);
- if( pRet ){
+ pRet->szLeaf = fts5GetU16(&pRet->p[2]);
+ }
+ }
+ p->rc = rc;
+ p->nRead++;
+ }
+
+ assert( (pRet==0)==(p->rc!=SQLITE_OK) );
+ return pRet;
+}
+
+
+/*
+** Release a reference to data record returned by an earlier call to
+** fts5DataRead().
+*/
+static void fts5DataRelease(Fts5Data *pData){
+ sqlite3_free(pData);
+}
+
+static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
+ Fts5Data *pRet = fts5DataRead(p, iRowid);
+ if( pRet ){
if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){
- p->rc = FTS5_CORRUPT;
- fts5DataRelease(pRet);
- pRet = 0;
- }
- }
- return pRet;
-}
-
-static int fts5IndexPrepareStmt(
- Fts5Index *p,
- sqlite3_stmt **ppStmt,
- char *zSql
-){
- if( p->rc==SQLITE_OK ){
- if( zSql ){
- p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
+ p->rc = FTS5_CORRUPT;
+ fts5DataRelease(pRet);
+ pRet = 0;
+ }
+ }
+ return pRet;
+}
+
+static int fts5IndexPrepareStmt(
+ Fts5Index *p,
+ sqlite3_stmt **ppStmt,
+ char *zSql
+){
+ if( p->rc==SQLITE_OK ){
+ if( zSql ){
+ p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB,
ppStmt, 0);
- }else{
- p->rc = SQLITE_NOMEM;
- }
- }
- sqlite3_free(zSql);
- return p->rc;
-}
-
-
-/*
-** INSERT OR REPLACE a record into the %_data table.
-*/
-static void fts5DataWrite(Fts5Index *p, i64 iRowid, const u8 *pData, int nData){
- if( p->rc!=SQLITE_OK ) return;
-
- if( p->pWriter==0 ){
- Fts5Config *pConfig = p->pConfig;
- fts5IndexPrepareStmt(p, &p->pWriter, sqlite3_mprintf(
+ }else{
+ p->rc = SQLITE_NOMEM;
+ }
+ }
+ sqlite3_free(zSql);
+ return p->rc;
+}
+
+
+/*
+** INSERT OR REPLACE a record into the %_data table.
+*/
+static void fts5DataWrite(Fts5Index *p, i64 iRowid, const u8 *pData, int nData){
+ if( p->rc!=SQLITE_OK ) return;
+
+ if( p->pWriter==0 ){
+ Fts5Config *pConfig = p->pConfig;
+ fts5IndexPrepareStmt(p, &p->pWriter, sqlite3_mprintf(
"REPLACE INTO '%q'.'%q_data'(id, block) VALUES(?,?)",
- pConfig->zDb, pConfig->zName
- ));
- if( p->rc ) return;
- }
-
- sqlite3_bind_int64(p->pWriter, 1, iRowid);
- sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC);
- sqlite3_step(p->pWriter);
- p->rc = sqlite3_reset(p->pWriter);
+ pConfig->zDb, pConfig->zName
+ ));
+ if( p->rc ) return;
+ }
+
+ sqlite3_bind_int64(p->pWriter, 1, iRowid);
+ sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC);
+ sqlite3_step(p->pWriter);
+ p->rc = sqlite3_reset(p->pWriter);
sqlite3_bind_null(p->pWriter, 2);
-}
-
-/*
-** Execute the following SQL:
-**
-** DELETE FROM %_data WHERE id BETWEEN $iFirst AND $iLast
-*/
-static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){
- if( p->rc!=SQLITE_OK ) return;
-
- if( p->pDeleter==0 ){
- Fts5Config *pConfig = p->pConfig;
- char *zSql = sqlite3_mprintf(
+}
+
+/*
+** Execute the following SQL:
+**
+** DELETE FROM %_data WHERE id BETWEEN $iFirst AND $iLast
+*/
+static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){
+ if( p->rc!=SQLITE_OK ) return;
+
+ if( p->pDeleter==0 ){
+ Fts5Config *pConfig = p->pConfig;
+ char *zSql = sqlite3_mprintf(
"DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?",
- pConfig->zDb, pConfig->zName
- );
+ pConfig->zDb, pConfig->zName
+ );
if( fts5IndexPrepareStmt(p, &p->pDeleter, zSql) ) return;
- }
-
- sqlite3_bind_int64(p->pDeleter, 1, iFirst);
- sqlite3_bind_int64(p->pDeleter, 2, iLast);
- sqlite3_step(p->pDeleter);
- p->rc = sqlite3_reset(p->pDeleter);
-}
-
-/*
-** Remove all records associated with segment iSegid.
-*/
-static void fts5DataRemoveSegment(Fts5Index *p, int iSegid){
- i64 iFirst = FTS5_SEGMENT_ROWID(iSegid, 0);
- i64 iLast = FTS5_SEGMENT_ROWID(iSegid+1, 0)-1;
- fts5DataDelete(p, iFirst, iLast);
- if( p->pIdxDeleter==0 ){
- Fts5Config *pConfig = p->pConfig;
- fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf(
- "DELETE FROM '%q'.'%q_idx' WHERE segid=?",
- pConfig->zDb, pConfig->zName
- ));
- }
- if( p->rc==SQLITE_OK ){
- sqlite3_bind_int(p->pIdxDeleter, 1, iSegid);
- sqlite3_step(p->pIdxDeleter);
- p->rc = sqlite3_reset(p->pIdxDeleter);
- }
-}
-
-/*
+ }
+
+ sqlite3_bind_int64(p->pDeleter, 1, iFirst);
+ sqlite3_bind_int64(p->pDeleter, 2, iLast);
+ sqlite3_step(p->pDeleter);
+ p->rc = sqlite3_reset(p->pDeleter);
+}
+
+/*
+** Remove all records associated with segment iSegid.
+*/
+static void fts5DataRemoveSegment(Fts5Index *p, int iSegid){
+ i64 iFirst = FTS5_SEGMENT_ROWID(iSegid, 0);
+ i64 iLast = FTS5_SEGMENT_ROWID(iSegid+1, 0)-1;
+ fts5DataDelete(p, iFirst, iLast);
+ if( p->pIdxDeleter==0 ){
+ Fts5Config *pConfig = p->pConfig;
+ fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf(
+ "DELETE FROM '%q'.'%q_idx' WHERE segid=?",
+ pConfig->zDb, pConfig->zName
+ ));
+ }
+ if( p->rc==SQLITE_OK ){
+ sqlite3_bind_int(p->pIdxDeleter, 1, iSegid);
+ sqlite3_step(p->pIdxDeleter);
+ p->rc = sqlite3_reset(p->pIdxDeleter);
+ }
+}
+
+/*
** Release a reference to an Fts5Structure object returned by an earlier
-** call to fts5StructureRead() or fts5StructureDecode().
-*/
-static void fts5StructureRelease(Fts5Structure *pStruct){
- if( pStruct && 0>=(--pStruct->nRef) ){
- int i;
- assert( pStruct->nRef==0 );
- for(i=0; i<pStruct->nLevel; i++){
- sqlite3_free(pStruct->aLevel[i].aSeg);
- }
- sqlite3_free(pStruct);
- }
-}
-
-static void fts5StructureRef(Fts5Structure *pStruct){
- pStruct->nRef++;
-}
-
+** call to fts5StructureRead() or fts5StructureDecode().
+*/
+static void fts5StructureRelease(Fts5Structure *pStruct){
+ if( pStruct && 0>=(--pStruct->nRef) ){
+ int i;
+ assert( pStruct->nRef==0 );
+ for(i=0; i<pStruct->nLevel; i++){
+ sqlite3_free(pStruct->aLevel[i].aSeg);
+ }
+ sqlite3_free(pStruct);
+ }
+}
+
+static void fts5StructureRef(Fts5Structure *pStruct){
+ pStruct->nRef++;
+}
+
static void *sqlite3Fts5StructureRef(Fts5Index *p){
fts5StructureRef(p->pStruct);
return (void*)p->pStruct;
@@ -223779,7 +223779,7 @@ static int sqlite3Fts5StructureTest(Fts5Index *p, void *pStruct){
return SQLITE_OK;
}
-/*
+/*
** Ensure that structure object (*pp) is writable.
**
** This function is a no-op if (*pRc) is not SQLITE_OK when it is called. If
@@ -223816,81 +223816,81 @@ static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){
}
/*
-** Deserialize and return the structure record currently stored in serialized
-** form within buffer pData/nData.
-**
-** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array
-** are over-allocated by one slot. This allows the structure contents
-** to be more easily edited.
-**
-** If an error occurs, *ppOut is set to NULL and an SQLite error code
-** returned. Otherwise, *ppOut is set to point to the new object and
-** SQLITE_OK returned.
-*/
-static int fts5StructureDecode(
- const u8 *pData, /* Buffer containing serialized structure */
- int nData, /* Size of buffer pData in bytes */
- int *piCookie, /* Configuration cookie value */
- Fts5Structure **ppOut /* OUT: Deserialized object */
-){
- int rc = SQLITE_OK;
- int i = 0;
- int iLvl;
- int nLevel = 0;
- int nSegment = 0;
+** Deserialize and return the structure record currently stored in serialized
+** form within buffer pData/nData.
+**
+** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array
+** are over-allocated by one slot. This allows the structure contents
+** to be more easily edited.
+**
+** If an error occurs, *ppOut is set to NULL and an SQLite error code
+** returned. Otherwise, *ppOut is set to point to the new object and
+** SQLITE_OK returned.
+*/
+static int fts5StructureDecode(
+ const u8 *pData, /* Buffer containing serialized structure */
+ int nData, /* Size of buffer pData in bytes */
+ int *piCookie, /* Configuration cookie value */
+ Fts5Structure **ppOut /* OUT: Deserialized object */
+){
+ int rc = SQLITE_OK;
+ int i = 0;
+ int iLvl;
+ int nLevel = 0;
+ int nSegment = 0;
sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */
- Fts5Structure *pRet = 0; /* Structure object to return */
-
- /* Grab the cookie value */
- if( piCookie ) *piCookie = sqlite3Fts5Get32(pData);
- i = 4;
-
- /* Read the total number of levels and segments from the start of the
- ** structure record. */
- i += fts5GetVarint32(&pData[i], nLevel);
- i += fts5GetVarint32(&pData[i], nSegment);
+ Fts5Structure *pRet = 0; /* Structure object to return */
+
+ /* Grab the cookie value */
+ if( piCookie ) *piCookie = sqlite3Fts5Get32(pData);
+ i = 4;
+
+ /* Read the total number of levels and segments from the start of the
+ ** structure record. */
+ i += fts5GetVarint32(&pData[i], nLevel);
+ i += fts5GetVarint32(&pData[i], nSegment);
if( nLevel>FTS5_MAX_SEGMENT || nLevel<0
|| nSegment>FTS5_MAX_SEGMENT || nSegment<0
){
return FTS5_CORRUPT;
}
- nByte = (
- sizeof(Fts5Structure) + /* Main structure */
- sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */
- );
- pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte);
-
- if( pRet ){
- pRet->nRef = 1;
- pRet->nLevel = nLevel;
- pRet->nSegment = nSegment;
- i += sqlite3Fts5GetVarint(&pData[i], &pRet->nWriteCounter);
-
- for(iLvl=0; rc==SQLITE_OK && iLvl<nLevel; iLvl++){
- Fts5StructureLevel *pLvl = &pRet->aLevel[iLvl];
- int nTotal = 0;
- int iSeg;
-
- if( i>=nData ){
- rc = FTS5_CORRUPT;
- }else{
- i += fts5GetVarint32(&pData[i], pLvl->nMerge);
- i += fts5GetVarint32(&pData[i], nTotal);
+ nByte = (
+ sizeof(Fts5Structure) + /* Main structure */
+ sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */
+ );
+ pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte);
+
+ if( pRet ){
+ pRet->nRef = 1;
+ pRet->nLevel = nLevel;
+ pRet->nSegment = nSegment;
+ i += sqlite3Fts5GetVarint(&pData[i], &pRet->nWriteCounter);
+
+ for(iLvl=0; rc==SQLITE_OK && iLvl<nLevel; iLvl++){
+ Fts5StructureLevel *pLvl = &pRet->aLevel[iLvl];
+ int nTotal = 0;
+ int iSeg;
+
+ if( i>=nData ){
+ rc = FTS5_CORRUPT;
+ }else{
+ i += fts5GetVarint32(&pData[i], pLvl->nMerge);
+ i += fts5GetVarint32(&pData[i], nTotal);
if( nTotal<pLvl->nMerge ) rc = FTS5_CORRUPT;
pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc,
- nTotal * sizeof(Fts5StructureSegment)
- );
+ nTotal * sizeof(Fts5StructureSegment)
+ );
nSegment -= nTotal;
- }
-
- if( rc==SQLITE_OK ){
- pLvl->nSeg = nTotal;
- for(iSeg=0; iSeg<nTotal; iSeg++){
+ }
+
+ if( rc==SQLITE_OK ){
+ pLvl->nSeg = nTotal;
+ for(iSeg=0; iSeg<nTotal; iSeg++){
Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
- if( i>=nData ){
- rc = FTS5_CORRUPT;
- break;
- }
+ if( i>=nData ){
+ rc = FTS5_CORRUPT;
+ break;
+ }
i += fts5GetVarint32(&pData[i], pSeg->iSegid);
i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst);
i += fts5GetVarint32(&pData[i], pSeg->pgnoLast);
@@ -223898,2246 +223898,2246 @@ static int fts5StructureDecode(
rc = FTS5_CORRUPT;
break;
}
- }
+ }
if( iLvl>0 && pLvl[-1].nMerge && nTotal==0 ) rc = FTS5_CORRUPT;
if( iLvl==nLevel-1 && pLvl->nMerge ) rc = FTS5_CORRUPT;
- }
- }
+ }
+ }
if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT;
- if( rc!=SQLITE_OK ){
- fts5StructureRelease(pRet);
- pRet = 0;
- }
- }
-
- *ppOut = pRet;
- return rc;
-}
-
-/*
+ if( rc!=SQLITE_OK ){
+ fts5StructureRelease(pRet);
+ pRet = 0;
+ }
+ }
+
+ *ppOut = pRet;
+ return rc;
+}
+
+/*
** Add a level to the Fts5Structure.aLevel[] array of structure object
** (*ppStruct).
-*/
-static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
+*/
+static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
fts5StructureMakeWritable(pRc, ppStruct);
- if( *pRc==SQLITE_OK ){
- Fts5Structure *pStruct = *ppStruct;
- int nLevel = pStruct->nLevel;
+ if( *pRc==SQLITE_OK ){
+ Fts5Structure *pStruct = *ppStruct;
+ int nLevel = pStruct->nLevel;
sqlite3_int64 nByte = (
- sizeof(Fts5Structure) + /* Main structure */
- sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */
- );
-
+ sizeof(Fts5Structure) + /* Main structure */
+ sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */
+ );
+
pStruct = sqlite3_realloc64(pStruct, nByte);
- if( pStruct ){
- memset(&pStruct->aLevel[nLevel], 0, sizeof(Fts5StructureLevel));
- pStruct->nLevel++;
- *ppStruct = pStruct;
- }else{
- *pRc = SQLITE_NOMEM;
- }
- }
-}
-
-/*
-** Extend level iLvl so that there is room for at least nExtra more
-** segments.
-*/
-static void fts5StructureExtendLevel(
+ if( pStruct ){
+ memset(&pStruct->aLevel[nLevel], 0, sizeof(Fts5StructureLevel));
+ pStruct->nLevel++;
+ *ppStruct = pStruct;
+ }else{
+ *pRc = SQLITE_NOMEM;
+ }
+ }
+}
+
+/*
+** Extend level iLvl so that there is room for at least nExtra more
+** segments.
+*/
+static void fts5StructureExtendLevel(
int *pRc,
Fts5Structure *pStruct,
int iLvl,
int nExtra,
- int bInsert
-){
- if( *pRc==SQLITE_OK ){
- Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
- Fts5StructureSegment *aNew;
+ int bInsert
+){
+ if( *pRc==SQLITE_OK ){
+ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
+ Fts5StructureSegment *aNew;
sqlite3_int64 nByte;
-
- nByte = (pLvl->nSeg + nExtra) * sizeof(Fts5StructureSegment);
+
+ nByte = (pLvl->nSeg + nExtra) * sizeof(Fts5StructureSegment);
aNew = sqlite3_realloc64(pLvl->aSeg, nByte);
- if( aNew ){
- if( bInsert==0 ){
- memset(&aNew[pLvl->nSeg], 0, sizeof(Fts5StructureSegment) * nExtra);
- }else{
- int nMove = pLvl->nSeg * sizeof(Fts5StructureSegment);
- memmove(&aNew[nExtra], aNew, nMove);
- memset(aNew, 0, sizeof(Fts5StructureSegment) * nExtra);
- }
- pLvl->aSeg = aNew;
- }else{
- *pRc = SQLITE_NOMEM;
- }
- }
-}
-
-static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){
- Fts5Structure *pRet = 0;
- Fts5Config *pConfig = p->pConfig;
- int iCookie; /* Configuration cookie */
- Fts5Data *pData;
-
- pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
- if( p->rc==SQLITE_OK ){
- /* TODO: Do we need this if the leaf-index is appended? Probably... */
- memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
- p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
+ if( aNew ){
+ if( bInsert==0 ){
+ memset(&aNew[pLvl->nSeg], 0, sizeof(Fts5StructureSegment) * nExtra);
+ }else{
+ int nMove = pLvl->nSeg * sizeof(Fts5StructureSegment);
+ memmove(&aNew[nExtra], aNew, nMove);
+ memset(aNew, 0, sizeof(Fts5StructureSegment) * nExtra);
+ }
+ pLvl->aSeg = aNew;
+ }else{
+ *pRc = SQLITE_NOMEM;
+ }
+ }
+}
+
+static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){
+ Fts5Structure *pRet = 0;
+ Fts5Config *pConfig = p->pConfig;
+ int iCookie; /* Configuration cookie */
+ Fts5Data *pData;
+
+ pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
+ if( p->rc==SQLITE_OK ){
+ /* TODO: Do we need this if the leaf-index is appended? Probably... */
+ memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
+ p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
if( p->rc==SQLITE_OK && (pConfig->pgsz==0 || pConfig->iCookie!=iCookie) ){
- p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
- }
- fts5DataRelease(pData);
- if( p->rc!=SQLITE_OK ){
- fts5StructureRelease(pRet);
- pRet = 0;
- }
- }
-
- return pRet;
-}
-
-static i64 fts5IndexDataVersion(Fts5Index *p){
- i64 iVersion = 0;
-
- if( p->rc==SQLITE_OK ){
- if( p->pDataVersion==0 ){
+ p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
+ }
+ fts5DataRelease(pData);
+ if( p->rc!=SQLITE_OK ){
+ fts5StructureRelease(pRet);
+ pRet = 0;
+ }
+ }
+
+ return pRet;
+}
+
+static i64 fts5IndexDataVersion(Fts5Index *p){
+ i64 iVersion = 0;
+
+ if( p->rc==SQLITE_OK ){
+ if( p->pDataVersion==0 ){
p->rc = fts5IndexPrepareStmt(p, &p->pDataVersion,
- sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb)
- );
- if( p->rc ) return 0;
- }
-
- if( SQLITE_ROW==sqlite3_step(p->pDataVersion) ){
- iVersion = sqlite3_column_int64(p->pDataVersion, 0);
- }
- p->rc = sqlite3_reset(p->pDataVersion);
- }
-
- return iVersion;
-}
-
-/*
-** Read, deserialize and return the structure record.
-**
-** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array
+ sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb)
+ );
+ if( p->rc ) return 0;
+ }
+
+ if( SQLITE_ROW==sqlite3_step(p->pDataVersion) ){
+ iVersion = sqlite3_column_int64(p->pDataVersion, 0);
+ }
+ p->rc = sqlite3_reset(p->pDataVersion);
+ }
+
+ return iVersion;
+}
+
+/*
+** Read, deserialize and return the structure record.
+**
+** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array
** are over-allocated as described for function fts5StructureDecode()
-** above.
-**
-** If an error occurs, NULL is returned and an error code left in the
-** Fts5Index handle. If an error has already occurred when this function
-** is called, it is a no-op.
-*/
-static Fts5Structure *fts5StructureRead(Fts5Index *p){
-
- if( p->pStruct==0 ){
- p->iStructVersion = fts5IndexDataVersion(p);
- if( p->rc==SQLITE_OK ){
- p->pStruct = fts5StructureReadUncached(p);
- }
- }
-
-#if 0
- else{
- Fts5Structure *pTest = fts5StructureReadUncached(p);
- if( pTest ){
- int i, j;
- assert_nc( p->pStruct->nSegment==pTest->nSegment );
- assert_nc( p->pStruct->nLevel==pTest->nLevel );
- for(i=0; i<pTest->nLevel; i++){
- assert_nc( p->pStruct->aLevel[i].nMerge==pTest->aLevel[i].nMerge );
- assert_nc( p->pStruct->aLevel[i].nSeg==pTest->aLevel[i].nSeg );
- for(j=0; j<pTest->aLevel[i].nSeg; j++){
- Fts5StructureSegment *p1 = &pTest->aLevel[i].aSeg[j];
- Fts5StructureSegment *p2 = &p->pStruct->aLevel[i].aSeg[j];
- assert_nc( p1->iSegid==p2->iSegid );
- assert_nc( p1->pgnoFirst==p2->pgnoFirst );
- assert_nc( p1->pgnoLast==p2->pgnoLast );
- }
- }
- fts5StructureRelease(pTest);
- }
- }
-#endif
-
- if( p->rc!=SQLITE_OK ) return 0;
- assert( p->iStructVersion!=0 );
- assert( p->pStruct!=0 );
- fts5StructureRef(p->pStruct);
- return p->pStruct;
-}
-
-static void fts5StructureInvalidate(Fts5Index *p){
- if( p->pStruct ){
- fts5StructureRelease(p->pStruct);
- p->pStruct = 0;
- }
-}
-
-/*
-** Return the total number of segments in index structure pStruct. This
-** function is only ever used as part of assert() conditions.
-*/
-#ifdef SQLITE_DEBUG
-static int fts5StructureCountSegments(Fts5Structure *pStruct){
- int nSegment = 0; /* Total number of segments */
- if( pStruct ){
- int iLvl; /* Used to iterate through levels */
- for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
- nSegment += pStruct->aLevel[iLvl].nSeg;
- }
- }
-
- return nSegment;
-}
-#endif
-
-#define fts5BufferSafeAppendBlob(pBuf, pBlob, nBlob) { \
- assert( (pBuf)->nSpace>=((pBuf)->n+nBlob) ); \
- memcpy(&(pBuf)->p[(pBuf)->n], pBlob, nBlob); \
- (pBuf)->n += nBlob; \
-}
-
-#define fts5BufferSafeAppendVarint(pBuf, iVal) { \
- (pBuf)->n += sqlite3Fts5PutVarint(&(pBuf)->p[(pBuf)->n], (iVal)); \
- assert( (pBuf)->nSpace>=(pBuf)->n ); \
-}
-
-
-/*
-** Serialize and store the "structure" record.
-**
-** If an error occurs, leave an error code in the Fts5Index object. If an
-** error has already occurred, this function is a no-op.
-*/
-static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){
- if( p->rc==SQLITE_OK ){
- Fts5Buffer buf; /* Buffer to serialize record into */
- int iLvl; /* Used to iterate through levels */
- int iCookie; /* Cookie value to store */
-
- assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
- memset(&buf, 0, sizeof(Fts5Buffer));
-
- /* Append the current configuration cookie */
- iCookie = p->pConfig->iCookie;
- if( iCookie<0 ) iCookie = 0;
-
- if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){
- sqlite3Fts5Put32(buf.p, iCookie);
- buf.n = 4;
- fts5BufferSafeAppendVarint(&buf, pStruct->nLevel);
- fts5BufferSafeAppendVarint(&buf, pStruct->nSegment);
- fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter);
- }
-
- for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
- int iSeg; /* Used to iterate through segments */
- Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
- fts5BufferAppendVarint(&p->rc, &buf, pLvl->nMerge);
- fts5BufferAppendVarint(&p->rc, &buf, pLvl->nSeg);
- assert( pLvl->nMerge<=pLvl->nSeg );
-
- for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
- fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].iSegid);
- fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoFirst);
- fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoLast);
- }
- }
-
- fts5DataWrite(p, FTS5_STRUCTURE_ROWID, buf.p, buf.n);
- fts5BufferFree(&buf);
- }
-}
-
-#if 0
-static void fts5DebugStructure(int*,Fts5Buffer*,Fts5Structure*);
-static void fts5PrintStructure(const char *zCaption, Fts5Structure *pStruct){
- int rc = SQLITE_OK;
- Fts5Buffer buf;
- memset(&buf, 0, sizeof(buf));
- fts5DebugStructure(&rc, &buf, pStruct);
- fprintf(stdout, "%s: %s\n", zCaption, buf.p);
- fflush(stdout);
- fts5BufferFree(&buf);
-}
-#else
-# define fts5PrintStructure(x,y)
-#endif
-
-static int fts5SegmentSize(Fts5StructureSegment *pSeg){
- return 1 + pSeg->pgnoLast - pSeg->pgnoFirst;
-}
-
-/*
+** above.
+**
+** If an error occurs, NULL is returned and an error code left in the
+** Fts5Index handle. If an error has already occurred when this function
+** is called, it is a no-op.
+*/
+static Fts5Structure *fts5StructureRead(Fts5Index *p){
+
+ if( p->pStruct==0 ){
+ p->iStructVersion = fts5IndexDataVersion(p);
+ if( p->rc==SQLITE_OK ){
+ p->pStruct = fts5StructureReadUncached(p);
+ }
+ }
+
+#if 0
+ else{
+ Fts5Structure *pTest = fts5StructureReadUncached(p);
+ if( pTest ){
+ int i, j;
+ assert_nc( p->pStruct->nSegment==pTest->nSegment );
+ assert_nc( p->pStruct->nLevel==pTest->nLevel );
+ for(i=0; i<pTest->nLevel; i++){
+ assert_nc( p->pStruct->aLevel[i].nMerge==pTest->aLevel[i].nMerge );
+ assert_nc( p->pStruct->aLevel[i].nSeg==pTest->aLevel[i].nSeg );
+ for(j=0; j<pTest->aLevel[i].nSeg; j++){
+ Fts5StructureSegment *p1 = &pTest->aLevel[i].aSeg[j];
+ Fts5StructureSegment *p2 = &p->pStruct->aLevel[i].aSeg[j];
+ assert_nc( p1->iSegid==p2->iSegid );
+ assert_nc( p1->pgnoFirst==p2->pgnoFirst );
+ assert_nc( p1->pgnoLast==p2->pgnoLast );
+ }
+ }
+ fts5StructureRelease(pTest);
+ }
+ }
+#endif
+
+ if( p->rc!=SQLITE_OK ) return 0;
+ assert( p->iStructVersion!=0 );
+ assert( p->pStruct!=0 );
+ fts5StructureRef(p->pStruct);
+ return p->pStruct;
+}
+
+static void fts5StructureInvalidate(Fts5Index *p){
+ if( p->pStruct ){
+ fts5StructureRelease(p->pStruct);
+ p->pStruct = 0;
+ }
+}
+
+/*
+** Return the total number of segments in index structure pStruct. This
+** function is only ever used as part of assert() conditions.
+*/
+#ifdef SQLITE_DEBUG
+static int fts5StructureCountSegments(Fts5Structure *pStruct){
+ int nSegment = 0; /* Total number of segments */
+ if( pStruct ){
+ int iLvl; /* Used to iterate through levels */
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+ nSegment += pStruct->aLevel[iLvl].nSeg;
+ }
+ }
+
+ return nSegment;
+}
+#endif
+
+#define fts5BufferSafeAppendBlob(pBuf, pBlob, nBlob) { \
+ assert( (pBuf)->nSpace>=((pBuf)->n+nBlob) ); \
+ memcpy(&(pBuf)->p[(pBuf)->n], pBlob, nBlob); \
+ (pBuf)->n += nBlob; \
+}
+
+#define fts5BufferSafeAppendVarint(pBuf, iVal) { \
+ (pBuf)->n += sqlite3Fts5PutVarint(&(pBuf)->p[(pBuf)->n], (iVal)); \
+ assert( (pBuf)->nSpace>=(pBuf)->n ); \
+}
+
+
+/*
+** Serialize and store the "structure" record.
+**
+** If an error occurs, leave an error code in the Fts5Index object. If an
+** error has already occurred, this function is a no-op.
+*/
+static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){
+ if( p->rc==SQLITE_OK ){
+ Fts5Buffer buf; /* Buffer to serialize record into */
+ int iLvl; /* Used to iterate through levels */
+ int iCookie; /* Cookie value to store */
+
+ assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
+ memset(&buf, 0, sizeof(Fts5Buffer));
+
+ /* Append the current configuration cookie */
+ iCookie = p->pConfig->iCookie;
+ if( iCookie<0 ) iCookie = 0;
+
+ if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){
+ sqlite3Fts5Put32(buf.p, iCookie);
+ buf.n = 4;
+ fts5BufferSafeAppendVarint(&buf, pStruct->nLevel);
+ fts5BufferSafeAppendVarint(&buf, pStruct->nSegment);
+ fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter);
+ }
+
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+ int iSeg; /* Used to iterate through segments */
+ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
+ fts5BufferAppendVarint(&p->rc, &buf, pLvl->nMerge);
+ fts5BufferAppendVarint(&p->rc, &buf, pLvl->nSeg);
+ assert( pLvl->nMerge<=pLvl->nSeg );
+
+ for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
+ fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].iSegid);
+ fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoFirst);
+ fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoLast);
+ }
+ }
+
+ fts5DataWrite(p, FTS5_STRUCTURE_ROWID, buf.p, buf.n);
+ fts5BufferFree(&buf);
+ }
+}
+
+#if 0
+static void fts5DebugStructure(int*,Fts5Buffer*,Fts5Structure*);
+static void fts5PrintStructure(const char *zCaption, Fts5Structure *pStruct){
+ int rc = SQLITE_OK;
+ Fts5Buffer buf;
+ memset(&buf, 0, sizeof(buf));
+ fts5DebugStructure(&rc, &buf, pStruct);
+ fprintf(stdout, "%s: %s\n", zCaption, buf.p);
+ fflush(stdout);
+ fts5BufferFree(&buf);
+}
+#else
+# define fts5PrintStructure(x,y)
+#endif
+
+static int fts5SegmentSize(Fts5StructureSegment *pSeg){
+ return 1 + pSeg->pgnoLast - pSeg->pgnoFirst;
+}
+
+/*
** Return a copy of index structure pStruct. Except, promote as many
** segments as possible to level iPromote. If an OOM occurs, NULL is
-** returned.
-*/
-static void fts5StructurePromoteTo(
- Fts5Index *p,
- int iPromote,
- int szPromote,
- Fts5Structure *pStruct
-){
- int il, is;
- Fts5StructureLevel *pOut = &pStruct->aLevel[iPromote];
-
- if( pOut->nMerge==0 ){
- for(il=iPromote+1; il<pStruct->nLevel; il++){
- Fts5StructureLevel *pLvl = &pStruct->aLevel[il];
- if( pLvl->nMerge ) return;
- for(is=pLvl->nSeg-1; is>=0; is--){
- int sz = fts5SegmentSize(&pLvl->aSeg[is]);
- if( sz>szPromote ) return;
- fts5StructureExtendLevel(&p->rc, pStruct, iPromote, 1, 1);
- if( p->rc ) return;
- memcpy(pOut->aSeg, &pLvl->aSeg[is], sizeof(Fts5StructureSegment));
- pOut->nSeg++;
- pLvl->nSeg--;
- }
- }
- }
-}
-
-/*
-** A new segment has just been written to level iLvl of index structure
-** pStruct. This function determines if any segments should be promoted
-** as a result. Segments are promoted in two scenarios:
-**
-** a) If the segment just written is smaller than one or more segments
-** within the previous populated level, it is promoted to the previous
-** populated level.
-**
-** b) If the segment just written is larger than the newest segment on
-** the next populated level, then that segment, and any other adjacent
+** returned.
+*/
+static void fts5StructurePromoteTo(
+ Fts5Index *p,
+ int iPromote,
+ int szPromote,
+ Fts5Structure *pStruct
+){
+ int il, is;
+ Fts5StructureLevel *pOut = &pStruct->aLevel[iPromote];
+
+ if( pOut->nMerge==0 ){
+ for(il=iPromote+1; il<pStruct->nLevel; il++){
+ Fts5StructureLevel *pLvl = &pStruct->aLevel[il];
+ if( pLvl->nMerge ) return;
+ for(is=pLvl->nSeg-1; is>=0; is--){
+ int sz = fts5SegmentSize(&pLvl->aSeg[is]);
+ if( sz>szPromote ) return;
+ fts5StructureExtendLevel(&p->rc, pStruct, iPromote, 1, 1);
+ if( p->rc ) return;
+ memcpy(pOut->aSeg, &pLvl->aSeg[is], sizeof(Fts5StructureSegment));
+ pOut->nSeg++;
+ pLvl->nSeg--;
+ }
+ }
+ }
+}
+
+/*
+** A new segment has just been written to level iLvl of index structure
+** pStruct. This function determines if any segments should be promoted
+** as a result. Segments are promoted in two scenarios:
+**
+** a) If the segment just written is smaller than one or more segments
+** within the previous populated level, it is promoted to the previous
+** populated level.
+**
+** b) If the segment just written is larger than the newest segment on
+** the next populated level, then that segment, and any other adjacent
** segments that are also smaller than the one just written, are
** promoted.
-**
-** If one or more segments are promoted, the structure object is updated
-** to reflect this.
-*/
-static void fts5StructurePromote(
- Fts5Index *p, /* FTS5 backend object */
- int iLvl, /* Index level just updated */
- Fts5Structure *pStruct /* Index structure */
-){
- if( p->rc==SQLITE_OK ){
- int iTst;
- int iPromote = -1;
- int szPromote = 0; /* Promote anything this size or smaller */
- Fts5StructureSegment *pSeg; /* Segment just written */
- int szSeg; /* Size of segment just written */
- int nSeg = pStruct->aLevel[iLvl].nSeg;
-
- if( nSeg==0 ) return;
- pSeg = &pStruct->aLevel[iLvl].aSeg[pStruct->aLevel[iLvl].nSeg-1];
- szSeg = (1 + pSeg->pgnoLast - pSeg->pgnoFirst);
-
- /* Check for condition (a) */
- for(iTst=iLvl-1; iTst>=0 && pStruct->aLevel[iTst].nSeg==0; iTst--);
- if( iTst>=0 ){
- int i;
- int szMax = 0;
- Fts5StructureLevel *pTst = &pStruct->aLevel[iTst];
- assert( pTst->nMerge==0 );
- for(i=0; i<pTst->nSeg; i++){
- int sz = pTst->aSeg[i].pgnoLast - pTst->aSeg[i].pgnoFirst + 1;
- if( sz>szMax ) szMax = sz;
- }
- if( szMax>=szSeg ){
+**
+** If one or more segments are promoted, the structure object is updated
+** to reflect this.
+*/
+static void fts5StructurePromote(
+ Fts5Index *p, /* FTS5 backend object */
+ int iLvl, /* Index level just updated */
+ Fts5Structure *pStruct /* Index structure */
+){
+ if( p->rc==SQLITE_OK ){
+ int iTst;
+ int iPromote = -1;
+ int szPromote = 0; /* Promote anything this size or smaller */
+ Fts5StructureSegment *pSeg; /* Segment just written */
+ int szSeg; /* Size of segment just written */
+ int nSeg = pStruct->aLevel[iLvl].nSeg;
+
+ if( nSeg==0 ) return;
+ pSeg = &pStruct->aLevel[iLvl].aSeg[pStruct->aLevel[iLvl].nSeg-1];
+ szSeg = (1 + pSeg->pgnoLast - pSeg->pgnoFirst);
+
+ /* Check for condition (a) */
+ for(iTst=iLvl-1; iTst>=0 && pStruct->aLevel[iTst].nSeg==0; iTst--);
+ if( iTst>=0 ){
+ int i;
+ int szMax = 0;
+ Fts5StructureLevel *pTst = &pStruct->aLevel[iTst];
+ assert( pTst->nMerge==0 );
+ for(i=0; i<pTst->nSeg; i++){
+ int sz = pTst->aSeg[i].pgnoLast - pTst->aSeg[i].pgnoFirst + 1;
+ if( sz>szMax ) szMax = sz;
+ }
+ if( szMax>=szSeg ){
/* Condition (a) is true. Promote the newest segment on level
- ** iLvl to level iTst. */
- iPromote = iTst;
- szPromote = szMax;
- }
- }
-
- /* If condition (a) is not met, assume (b) is true. StructurePromoteTo()
- ** is a no-op if it is not. */
- if( iPromote<0 ){
- iPromote = iLvl;
- szPromote = szSeg;
- }
- fts5StructurePromoteTo(p, iPromote, szPromote, pStruct);
- }
-}
-
-
-/*
+ ** iLvl to level iTst. */
+ iPromote = iTst;
+ szPromote = szMax;
+ }
+ }
+
+ /* If condition (a) is not met, assume (b) is true. StructurePromoteTo()
+ ** is a no-op if it is not. */
+ if( iPromote<0 ){
+ iPromote = iLvl;
+ szPromote = szSeg;
+ }
+ fts5StructurePromoteTo(p, iPromote, szPromote, pStruct);
+ }
+}
+
+
+/*
** Advance the iterator passed as the only argument. If the end of the
-** doclist-index page is reached, return non-zero.
-*/
-static int fts5DlidxLvlNext(Fts5DlidxLvl *pLvl){
- Fts5Data *pData = pLvl->pData;
-
- if( pLvl->iOff==0 ){
- assert( pLvl->bEof==0 );
- pLvl->iOff = 1;
- pLvl->iOff += fts5GetVarint32(&pData->p[1], pLvl->iLeafPgno);
- pLvl->iOff += fts5GetVarint(&pData->p[pLvl->iOff], (u64*)&pLvl->iRowid);
- pLvl->iFirstOff = pLvl->iOff;
- }else{
- int iOff;
- for(iOff=pLvl->iOff; iOff<pData->nn; iOff++){
+** doclist-index page is reached, return non-zero.
+*/
+static int fts5DlidxLvlNext(Fts5DlidxLvl *pLvl){
+ Fts5Data *pData = pLvl->pData;
+
+ if( pLvl->iOff==0 ){
+ assert( pLvl->bEof==0 );
+ pLvl->iOff = 1;
+ pLvl->iOff += fts5GetVarint32(&pData->p[1], pLvl->iLeafPgno);
+ pLvl->iOff += fts5GetVarint(&pData->p[pLvl->iOff], (u64*)&pLvl->iRowid);
+ pLvl->iFirstOff = pLvl->iOff;
+ }else{
+ int iOff;
+ for(iOff=pLvl->iOff; iOff<pData->nn; iOff++){
if( pData->p[iOff] ) break;
- }
-
- if( iOff<pData->nn ){
- i64 iVal;
- pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1;
- iOff += fts5GetVarint(&pData->p[iOff], (u64*)&iVal);
- pLvl->iRowid += iVal;
- pLvl->iOff = iOff;
- }else{
- pLvl->bEof = 1;
- }
- }
-
- return pLvl->bEof;
-}
-
-/*
-** Advance the iterator passed as the only argument.
-*/
-static int fts5DlidxIterNextR(Fts5Index *p, Fts5DlidxIter *pIter, int iLvl){
- Fts5DlidxLvl *pLvl = &pIter->aLvl[iLvl];
-
- assert( iLvl<pIter->nLvl );
- if( fts5DlidxLvlNext(pLvl) ){
- if( (iLvl+1) < pIter->nLvl ){
- fts5DlidxIterNextR(p, pIter, iLvl+1);
- if( pLvl[1].bEof==0 ){
- fts5DataRelease(pLvl->pData);
- memset(pLvl, 0, sizeof(Fts5DlidxLvl));
+ }
+
+ if( iOff<pData->nn ){
+ i64 iVal;
+ pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1;
+ iOff += fts5GetVarint(&pData->p[iOff], (u64*)&iVal);
+ pLvl->iRowid += iVal;
+ pLvl->iOff = iOff;
+ }else{
+ pLvl->bEof = 1;
+ }
+ }
+
+ return pLvl->bEof;
+}
+
+/*
+** Advance the iterator passed as the only argument.
+*/
+static int fts5DlidxIterNextR(Fts5Index *p, Fts5DlidxIter *pIter, int iLvl){
+ Fts5DlidxLvl *pLvl = &pIter->aLvl[iLvl];
+
+ assert( iLvl<pIter->nLvl );
+ if( fts5DlidxLvlNext(pLvl) ){
+ if( (iLvl+1) < pIter->nLvl ){
+ fts5DlidxIterNextR(p, pIter, iLvl+1);
+ if( pLvl[1].bEof==0 ){
+ fts5DataRelease(pLvl->pData);
+ memset(pLvl, 0, sizeof(Fts5DlidxLvl));
pLvl->pData = fts5DataRead(p,
- FTS5_DLIDX_ROWID(pIter->iSegid, iLvl, pLvl[1].iLeafPgno)
- );
- if( pLvl->pData ) fts5DlidxLvlNext(pLvl);
- }
- }
- }
-
- return pIter->aLvl[0].bEof;
-}
-static int fts5DlidxIterNext(Fts5Index *p, Fts5DlidxIter *pIter){
- return fts5DlidxIterNextR(p, pIter, 0);
-}
-
-/*
-** The iterator passed as the first argument has the following fields set
-** as follows. This function sets up the rest of the iterator so that it
-** points to the first rowid in the doclist-index.
-**
-** pData:
+ FTS5_DLIDX_ROWID(pIter->iSegid, iLvl, pLvl[1].iLeafPgno)
+ );
+ if( pLvl->pData ) fts5DlidxLvlNext(pLvl);
+ }
+ }
+ }
+
+ return pIter->aLvl[0].bEof;
+}
+static int fts5DlidxIterNext(Fts5Index *p, Fts5DlidxIter *pIter){
+ return fts5DlidxIterNextR(p, pIter, 0);
+}
+
+/*
+** The iterator passed as the first argument has the following fields set
+** as follows. This function sets up the rest of the iterator so that it
+** points to the first rowid in the doclist-index.
+**
+** pData:
** pointer to doclist-index record,
-**
-** When this function is called pIter->iLeafPgno is the page number the
-** doclist is associated with (the one featuring the term).
-*/
-static int fts5DlidxIterFirst(Fts5DlidxIter *pIter){
- int i;
- for(i=0; i<pIter->nLvl; i++){
- fts5DlidxLvlNext(&pIter->aLvl[i]);
- }
- return pIter->aLvl[0].bEof;
-}
-
-
-static int fts5DlidxIterEof(Fts5Index *p, Fts5DlidxIter *pIter){
- return p->rc!=SQLITE_OK || pIter->aLvl[0].bEof;
-}
-
-static void fts5DlidxIterLast(Fts5Index *p, Fts5DlidxIter *pIter){
- int i;
-
- /* Advance each level to the last entry on the last page */
- for(i=pIter->nLvl-1; p->rc==SQLITE_OK && i>=0; i--){
- Fts5DlidxLvl *pLvl = &pIter->aLvl[i];
- while( fts5DlidxLvlNext(pLvl)==0 );
- pLvl->bEof = 0;
-
- if( i>0 ){
- Fts5DlidxLvl *pChild = &pLvl[-1];
- fts5DataRelease(pChild->pData);
- memset(pChild, 0, sizeof(Fts5DlidxLvl));
+**
+** When this function is called pIter->iLeafPgno is the page number the
+** doclist is associated with (the one featuring the term).
+*/
+static int fts5DlidxIterFirst(Fts5DlidxIter *pIter){
+ int i;
+ for(i=0; i<pIter->nLvl; i++){
+ fts5DlidxLvlNext(&pIter->aLvl[i]);
+ }
+ return pIter->aLvl[0].bEof;
+}
+
+
+static int fts5DlidxIterEof(Fts5Index *p, Fts5DlidxIter *pIter){
+ return p->rc!=SQLITE_OK || pIter->aLvl[0].bEof;
+}
+
+static void fts5DlidxIterLast(Fts5Index *p, Fts5DlidxIter *pIter){
+ int i;
+
+ /* Advance each level to the last entry on the last page */
+ for(i=pIter->nLvl-1; p->rc==SQLITE_OK && i>=0; i--){
+ Fts5DlidxLvl *pLvl = &pIter->aLvl[i];
+ while( fts5DlidxLvlNext(pLvl)==0 );
+ pLvl->bEof = 0;
+
+ if( i>0 ){
+ Fts5DlidxLvl *pChild = &pLvl[-1];
+ fts5DataRelease(pChild->pData);
+ memset(pChild, 0, sizeof(Fts5DlidxLvl));
pChild->pData = fts5DataRead(p,
- FTS5_DLIDX_ROWID(pIter->iSegid, i-1, pLvl->iLeafPgno)
- );
- }
- }
-}
-
-/*
-** Move the iterator passed as the only argument to the previous entry.
-*/
-static int fts5DlidxLvlPrev(Fts5DlidxLvl *pLvl){
- int iOff = pLvl->iOff;
-
- assert( pLvl->bEof==0 );
- if( iOff<=pLvl->iFirstOff ){
- pLvl->bEof = 1;
- }else{
- u8 *a = pLvl->pData->p;
- i64 iVal;
- int iLimit;
- int ii;
- int nZero = 0;
-
+ FTS5_DLIDX_ROWID(pIter->iSegid, i-1, pLvl->iLeafPgno)
+ );
+ }
+ }
+}
+
+/*
+** Move the iterator passed as the only argument to the previous entry.
+*/
+static int fts5DlidxLvlPrev(Fts5DlidxLvl *pLvl){
+ int iOff = pLvl->iOff;
+
+ assert( pLvl->bEof==0 );
+ if( iOff<=pLvl->iFirstOff ){
+ pLvl->bEof = 1;
+ }else{
+ u8 *a = pLvl->pData->p;
+ i64 iVal;
+ int iLimit;
+ int ii;
+ int nZero = 0;
+
/* Currently iOff points to the first byte of a varint. This block
** decrements iOff until it points to the first byte of the previous
- ** varint. Taking care not to read any memory locations that occur
- ** before the buffer in memory. */
- iLimit = (iOff>9 ? iOff-9 : 0);
- for(iOff--; iOff>iLimit; iOff--){
- if( (a[iOff-1] & 0x80)==0 ) break;
- }
-
- fts5GetVarint(&a[iOff], (u64*)&iVal);
- pLvl->iRowid -= iVal;
- pLvl->iLeafPgno--;
-
- /* Skip backwards past any 0x00 varints. */
- for(ii=iOff-1; ii>=pLvl->iFirstOff && a[ii]==0x00; ii--){
- nZero++;
- }
- if( ii>=pLvl->iFirstOff && (a[ii] & 0x80) ){
- /* The byte immediately before the last 0x00 byte has the 0x80 bit
- ** set. So the last 0x00 is only a varint 0 if there are 8 more 0x80
- ** bytes before a[ii]. */
- int bZero = 0; /* True if last 0x00 counts */
- if( (ii-8)>=pLvl->iFirstOff ){
- int j;
- for(j=1; j<=8 && (a[ii-j] & 0x80); j++);
- bZero = (j>8);
- }
- if( bZero==0 ) nZero--;
- }
- pLvl->iLeafPgno -= nZero;
- pLvl->iOff = iOff - nZero;
- }
-
- return pLvl->bEof;
-}
-
-static int fts5DlidxIterPrevR(Fts5Index *p, Fts5DlidxIter *pIter, int iLvl){
- Fts5DlidxLvl *pLvl = &pIter->aLvl[iLvl];
-
- assert( iLvl<pIter->nLvl );
- if( fts5DlidxLvlPrev(pLvl) ){
- if( (iLvl+1) < pIter->nLvl ){
- fts5DlidxIterPrevR(p, pIter, iLvl+1);
- if( pLvl[1].bEof==0 ){
- fts5DataRelease(pLvl->pData);
- memset(pLvl, 0, sizeof(Fts5DlidxLvl));
+ ** varint. Taking care not to read any memory locations that occur
+ ** before the buffer in memory. */
+ iLimit = (iOff>9 ? iOff-9 : 0);
+ for(iOff--; iOff>iLimit; iOff--){
+ if( (a[iOff-1] & 0x80)==0 ) break;
+ }
+
+ fts5GetVarint(&a[iOff], (u64*)&iVal);
+ pLvl->iRowid -= iVal;
+ pLvl->iLeafPgno--;
+
+ /* Skip backwards past any 0x00 varints. */
+ for(ii=iOff-1; ii>=pLvl->iFirstOff && a[ii]==0x00; ii--){
+ nZero++;
+ }
+ if( ii>=pLvl->iFirstOff && (a[ii] & 0x80) ){
+ /* The byte immediately before the last 0x00 byte has the 0x80 bit
+ ** set. So the last 0x00 is only a varint 0 if there are 8 more 0x80
+ ** bytes before a[ii]. */
+ int bZero = 0; /* True if last 0x00 counts */
+ if( (ii-8)>=pLvl->iFirstOff ){
+ int j;
+ for(j=1; j<=8 && (a[ii-j] & 0x80); j++);
+ bZero = (j>8);
+ }
+ if( bZero==0 ) nZero--;
+ }
+ pLvl->iLeafPgno -= nZero;
+ pLvl->iOff = iOff - nZero;
+ }
+
+ return pLvl->bEof;
+}
+
+static int fts5DlidxIterPrevR(Fts5Index *p, Fts5DlidxIter *pIter, int iLvl){
+ Fts5DlidxLvl *pLvl = &pIter->aLvl[iLvl];
+
+ assert( iLvl<pIter->nLvl );
+ if( fts5DlidxLvlPrev(pLvl) ){
+ if( (iLvl+1) < pIter->nLvl ){
+ fts5DlidxIterPrevR(p, pIter, iLvl+1);
+ if( pLvl[1].bEof==0 ){
+ fts5DataRelease(pLvl->pData);
+ memset(pLvl, 0, sizeof(Fts5DlidxLvl));
pLvl->pData = fts5DataRead(p,
- FTS5_DLIDX_ROWID(pIter->iSegid, iLvl, pLvl[1].iLeafPgno)
- );
- if( pLvl->pData ){
- while( fts5DlidxLvlNext(pLvl)==0 );
- pLvl->bEof = 0;
- }
- }
- }
- }
-
- return pIter->aLvl[0].bEof;
-}
-static int fts5DlidxIterPrev(Fts5Index *p, Fts5DlidxIter *pIter){
- return fts5DlidxIterPrevR(p, pIter, 0);
-}
-
-/*
-** Free a doclist-index iterator object allocated by fts5DlidxIterInit().
-*/
-static void fts5DlidxIterFree(Fts5DlidxIter *pIter){
- if( pIter ){
- int i;
- for(i=0; i<pIter->nLvl; i++){
- fts5DataRelease(pIter->aLvl[i].pData);
- }
- sqlite3_free(pIter);
- }
-}
-
-static Fts5DlidxIter *fts5DlidxIterInit(
- Fts5Index *p, /* Fts5 Backend to iterate within */
- int bRev, /* True for ORDER BY ASC */
- int iSegid, /* Segment id */
- int iLeafPg /* Leaf page number to load dlidx for */
-){
- Fts5DlidxIter *pIter = 0;
- int i;
- int bDone = 0;
-
- for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
+ FTS5_DLIDX_ROWID(pIter->iSegid, iLvl, pLvl[1].iLeafPgno)
+ );
+ if( pLvl->pData ){
+ while( fts5DlidxLvlNext(pLvl)==0 );
+ pLvl->bEof = 0;
+ }
+ }
+ }
+ }
+
+ return pIter->aLvl[0].bEof;
+}
+static int fts5DlidxIterPrev(Fts5Index *p, Fts5DlidxIter *pIter){
+ return fts5DlidxIterPrevR(p, pIter, 0);
+}
+
+/*
+** Free a doclist-index iterator object allocated by fts5DlidxIterInit().
+*/
+static void fts5DlidxIterFree(Fts5DlidxIter *pIter){
+ if( pIter ){
+ int i;
+ for(i=0; i<pIter->nLvl; i++){
+ fts5DataRelease(pIter->aLvl[i].pData);
+ }
+ sqlite3_free(pIter);
+ }
+}
+
+static Fts5DlidxIter *fts5DlidxIterInit(
+ Fts5Index *p, /* Fts5 Backend to iterate within */
+ int bRev, /* True for ORDER BY ASC */
+ int iSegid, /* Segment id */
+ int iLeafPg /* Leaf page number to load dlidx for */
+){
+ Fts5DlidxIter *pIter = 0;
+ int i;
+ int bDone = 0;
+
+ for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
sqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl);
- Fts5DlidxIter *pNew;
-
+ Fts5DlidxIter *pNew;
+
pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte);
- if( pNew==0 ){
- p->rc = SQLITE_NOMEM;
- }else{
- i64 iRowid = FTS5_DLIDX_ROWID(iSegid, i, iLeafPg);
- Fts5DlidxLvl *pLvl = &pNew->aLvl[i];
- pIter = pNew;
- memset(pLvl, 0, sizeof(Fts5DlidxLvl));
- pLvl->pData = fts5DataRead(p, iRowid);
- if( pLvl->pData && (pLvl->pData->p[0] & 0x0001)==0 ){
- bDone = 1;
- }
- pIter->nLvl = i+1;
- }
- }
-
- if( p->rc==SQLITE_OK ){
- pIter->iSegid = iSegid;
- if( bRev==0 ){
- fts5DlidxIterFirst(pIter);
- }else{
- fts5DlidxIterLast(p, pIter);
- }
- }
-
- if( p->rc!=SQLITE_OK ){
- fts5DlidxIterFree(pIter);
- pIter = 0;
- }
-
- return pIter;
-}
-
-static i64 fts5DlidxIterRowid(Fts5DlidxIter *pIter){
- return pIter->aLvl[0].iRowid;
-}
-static int fts5DlidxIterPgno(Fts5DlidxIter *pIter){
- return pIter->aLvl[0].iLeafPgno;
-}
-
-/*
-** Load the next leaf page into the segment iterator.
-*/
-static void fts5SegIterNextPage(
- Fts5Index *p, /* FTS5 backend object */
- Fts5SegIter *pIter /* Iterator to advance to next page */
-){
- Fts5Data *pLeaf;
- Fts5StructureSegment *pSeg = pIter->pSeg;
- fts5DataRelease(pIter->pLeaf);
- pIter->iLeafPgno++;
- if( pIter->pNextLeaf ){
- pIter->pLeaf = pIter->pNextLeaf;
- pIter->pNextLeaf = 0;
- }else if( pIter->iLeafPgno<=pSeg->pgnoLast ){
+ if( pNew==0 ){
+ p->rc = SQLITE_NOMEM;
+ }else{
+ i64 iRowid = FTS5_DLIDX_ROWID(iSegid, i, iLeafPg);
+ Fts5DlidxLvl *pLvl = &pNew->aLvl[i];
+ pIter = pNew;
+ memset(pLvl, 0, sizeof(Fts5DlidxLvl));
+ pLvl->pData = fts5DataRead(p, iRowid);
+ if( pLvl->pData && (pLvl->pData->p[0] & 0x0001)==0 ){
+ bDone = 1;
+ }
+ pIter->nLvl = i+1;
+ }
+ }
+
+ if( p->rc==SQLITE_OK ){
+ pIter->iSegid = iSegid;
+ if( bRev==0 ){
+ fts5DlidxIterFirst(pIter);
+ }else{
+ fts5DlidxIterLast(p, pIter);
+ }
+ }
+
+ if( p->rc!=SQLITE_OK ){
+ fts5DlidxIterFree(pIter);
+ pIter = 0;
+ }
+
+ return pIter;
+}
+
+static i64 fts5DlidxIterRowid(Fts5DlidxIter *pIter){
+ return pIter->aLvl[0].iRowid;
+}
+static int fts5DlidxIterPgno(Fts5DlidxIter *pIter){
+ return pIter->aLvl[0].iLeafPgno;
+}
+
+/*
+** Load the next leaf page into the segment iterator.
+*/
+static void fts5SegIterNextPage(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegIter *pIter /* Iterator to advance to next page */
+){
+ Fts5Data *pLeaf;
+ Fts5StructureSegment *pSeg = pIter->pSeg;
+ fts5DataRelease(pIter->pLeaf);
+ pIter->iLeafPgno++;
+ if( pIter->pNextLeaf ){
+ pIter->pLeaf = pIter->pNextLeaf;
+ pIter->pNextLeaf = 0;
+ }else if( pIter->iLeafPgno<=pSeg->pgnoLast ){
pIter->pLeaf = fts5LeafRead(p,
- FTS5_SEGMENT_ROWID(pSeg->iSegid, pIter->iLeafPgno)
- );
- }else{
- pIter->pLeaf = 0;
- }
- pLeaf = pIter->pLeaf;
-
- if( pLeaf ){
- pIter->iPgidxOff = pLeaf->szLeaf;
- if( fts5LeafIsTermless(pLeaf) ){
- pIter->iEndofDoclist = pLeaf->nn+1;
- }else{
- pIter->iPgidxOff += fts5GetVarint32(&pLeaf->p[pIter->iPgidxOff],
- pIter->iEndofDoclist
- );
- }
- }
-}
-
-/*
-** Argument p points to a buffer containing a varint to be interpreted as a
-** position list size field. Read the varint and return the number of bytes
-** read. Before returning, set *pnSz to the number of bytes in the position
-** list, and *pbDel to true if the delete flag is set, or false otherwise.
-*/
-static int fts5GetPoslistSize(const u8 *p, int *pnSz, int *pbDel){
- int nSz;
- int n = 0;
- fts5FastGetVarint32(p, n, nSz);
- assert_nc( nSz>=0 );
- *pnSz = nSz/2;
- *pbDel = nSz & 0x0001;
- return n;
-}
-
-/*
-** Fts5SegIter.iLeafOffset currently points to the first byte of a
-** position-list size field. Read the value of the field and store it
-** in the following variables:
-**
-** Fts5SegIter.nPos
-** Fts5SegIter.bDel
-**
+ FTS5_SEGMENT_ROWID(pSeg->iSegid, pIter->iLeafPgno)
+ );
+ }else{
+ pIter->pLeaf = 0;
+ }
+ pLeaf = pIter->pLeaf;
+
+ if( pLeaf ){
+ pIter->iPgidxOff = pLeaf->szLeaf;
+ if( fts5LeafIsTermless(pLeaf) ){
+ pIter->iEndofDoclist = pLeaf->nn+1;
+ }else{
+ pIter->iPgidxOff += fts5GetVarint32(&pLeaf->p[pIter->iPgidxOff],
+ pIter->iEndofDoclist
+ );
+ }
+ }
+}
+
+/*
+** Argument p points to a buffer containing a varint to be interpreted as a
+** position list size field. Read the varint and return the number of bytes
+** read. Before returning, set *pnSz to the number of bytes in the position
+** list, and *pbDel to true if the delete flag is set, or false otherwise.
+*/
+static int fts5GetPoslistSize(const u8 *p, int *pnSz, int *pbDel){
+ int nSz;
+ int n = 0;
+ fts5FastGetVarint32(p, n, nSz);
+ assert_nc( nSz>=0 );
+ *pnSz = nSz/2;
+ *pbDel = nSz & 0x0001;
+ return n;
+}
+
+/*
+** Fts5SegIter.iLeafOffset currently points to the first byte of a
+** position-list size field. Read the value of the field and store it
+** in the following variables:
+**
+** Fts5SegIter.nPos
+** Fts5SegIter.bDel
+**
** Leave Fts5SegIter.iLeafOffset pointing to the first byte of the
-** position list content (if any).
-*/
-static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){
- if( p->rc==SQLITE_OK ){
- int iOff = pIter->iLeafOffset; /* Offset to read at */
- ASSERT_SZLEAF_OK(pIter->pLeaf);
- if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
- int iEod = MIN(pIter->iEndofDoclist, pIter->pLeaf->szLeaf);
- pIter->bDel = 0;
- pIter->nPos = 1;
- if( iOff<iEod && pIter->pLeaf->p[iOff]==0 ){
- pIter->bDel = 1;
- iOff++;
- if( iOff<iEod && pIter->pLeaf->p[iOff]==0 ){
- pIter->nPos = 1;
- iOff++;
- }else{
- pIter->nPos = 0;
- }
- }
- }else{
- int nSz;
- fts5FastGetVarint32(pIter->pLeaf->p, iOff, nSz);
- pIter->bDel = (nSz & 0x0001);
- pIter->nPos = nSz>>1;
- assert_nc( pIter->nPos>=0 );
- }
- pIter->iLeafOffset = iOff;
- }
-}
-
-static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
- u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
+** position list content (if any).
+*/
+static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){
+ if( p->rc==SQLITE_OK ){
+ int iOff = pIter->iLeafOffset; /* Offset to read at */
+ ASSERT_SZLEAF_OK(pIter->pLeaf);
+ if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
+ int iEod = MIN(pIter->iEndofDoclist, pIter->pLeaf->szLeaf);
+ pIter->bDel = 0;
+ pIter->nPos = 1;
+ if( iOff<iEod && pIter->pLeaf->p[iOff]==0 ){
+ pIter->bDel = 1;
+ iOff++;
+ if( iOff<iEod && pIter->pLeaf->p[iOff]==0 ){
+ pIter->nPos = 1;
+ iOff++;
+ }else{
+ pIter->nPos = 0;
+ }
+ }
+ }else{
+ int nSz;
+ fts5FastGetVarint32(pIter->pLeaf->p, iOff, nSz);
+ pIter->bDel = (nSz & 0x0001);
+ pIter->nPos = nSz>>1;
+ assert_nc( pIter->nPos>=0 );
+ }
+ pIter->iLeafOffset = iOff;
+ }
+}
+
+static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
+ u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
i64 iOff = pIter->iLeafOffset;
-
- ASSERT_SZLEAF_OK(pIter->pLeaf);
- if( iOff>=pIter->pLeaf->szLeaf ){
- fts5SegIterNextPage(p, pIter);
- if( pIter->pLeaf==0 ){
- if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
- return;
- }
- iOff = 4;
- a = pIter->pLeaf->p;
- }
- iOff += sqlite3Fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
- pIter->iLeafOffset = iOff;
-}
-
-/*
+
+ ASSERT_SZLEAF_OK(pIter->pLeaf);
+ if( iOff>=pIter->pLeaf->szLeaf ){
+ fts5SegIterNextPage(p, pIter);
+ if( pIter->pLeaf==0 ){
+ if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
+ return;
+ }
+ iOff = 4;
+ a = pIter->pLeaf->p;
+ }
+ iOff += sqlite3Fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
+ pIter->iLeafOffset = iOff;
+}
+
+/*
** Fts5SegIter.iLeafOffset currently points to the first byte of the
-** "nSuffix" field of a term. Function parameter nKeep contains the value
-** of the "nPrefix" field (if there was one - it is passed 0 if this is
-** the first term in the segment).
-**
-** This function populates:
-**
-** Fts5SegIter.term
-** Fts5SegIter.rowid
-**
-** accordingly and leaves (Fts5SegIter.iLeafOffset) set to the content of
+** "nSuffix" field of a term. Function parameter nKeep contains the value
+** of the "nPrefix" field (if there was one - it is passed 0 if this is
+** the first term in the segment).
+**
+** This function populates:
+**
+** Fts5SegIter.term
+** Fts5SegIter.rowid
+**
+** accordingly and leaves (Fts5SegIter.iLeafOffset) set to the content of
** the first position list. The position list belonging to document
-** (Fts5SegIter.iRowid).
-*/
-static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
- u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
+** (Fts5SegIter.iRowid).
+*/
+static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
+ u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
i64 iOff = pIter->iLeafOffset; /* Offset to read at */
- int nNew; /* Bytes of new data */
-
- iOff += fts5GetVarint32(&a[iOff], nNew);
+ int nNew; /* Bytes of new data */
+
+ iOff += fts5GetVarint32(&a[iOff], nNew);
if( iOff+nNew>pIter->pLeaf->szLeaf || nKeep>pIter->term.n || nNew==0 ){
- p->rc = FTS5_CORRUPT;
- return;
- }
- pIter->term.n = nKeep;
- fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
+ p->rc = FTS5_CORRUPT;
+ return;
+ }
+ pIter->term.n = nKeep;
+ fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
assert( pIter->term.n<=pIter->term.nSpace );
- iOff += nNew;
- pIter->iTermLeafOffset = iOff;
- pIter->iTermLeafPgno = pIter->iLeafPgno;
- pIter->iLeafOffset = iOff;
-
- if( pIter->iPgidxOff>=pIter->pLeaf->nn ){
- pIter->iEndofDoclist = pIter->pLeaf->nn+1;
- }else{
- int nExtra;
- pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], nExtra);
- pIter->iEndofDoclist += nExtra;
- }
-
- fts5SegIterLoadRowid(p, pIter);
-}
-
-static void fts5SegIterNext(Fts5Index*, Fts5SegIter*, int*);
-static void fts5SegIterNext_Reverse(Fts5Index*, Fts5SegIter*, int*);
-static void fts5SegIterNext_None(Fts5Index*, Fts5SegIter*, int*);
-
-static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){
- if( pIter->flags & FTS5_SEGITER_REVERSE ){
- pIter->xNext = fts5SegIterNext_Reverse;
- }else if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
- pIter->xNext = fts5SegIterNext_None;
- }else{
- pIter->xNext = fts5SegIterNext;
- }
-}
-
-/*
-** Initialize the iterator object pIter to iterate through the entries in
+ iOff += nNew;
+ pIter->iTermLeafOffset = iOff;
+ pIter->iTermLeafPgno = pIter->iLeafPgno;
+ pIter->iLeafOffset = iOff;
+
+ if( pIter->iPgidxOff>=pIter->pLeaf->nn ){
+ pIter->iEndofDoclist = pIter->pLeaf->nn+1;
+ }else{
+ int nExtra;
+ pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], nExtra);
+ pIter->iEndofDoclist += nExtra;
+ }
+
+ fts5SegIterLoadRowid(p, pIter);
+}
+
+static void fts5SegIterNext(Fts5Index*, Fts5SegIter*, int*);
+static void fts5SegIterNext_Reverse(Fts5Index*, Fts5SegIter*, int*);
+static void fts5SegIterNext_None(Fts5Index*, Fts5SegIter*, int*);
+
+static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){
+ if( pIter->flags & FTS5_SEGITER_REVERSE ){
+ pIter->xNext = fts5SegIterNext_Reverse;
+ }else if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
+ pIter->xNext = fts5SegIterNext_None;
+ }else{
+ pIter->xNext = fts5SegIterNext;
+ }
+}
+
+/*
+** Initialize the iterator object pIter to iterate through the entries in
** segment pSeg. The iterator is left pointing to the first entry when
-** this function returns.
-**
+** this function returns.
+**
** If an error occurs, Fts5Index.rc is set to an appropriate error code. If
-** an error has already occurred when this function is called, it is a no-op.
-*/
-static void fts5SegIterInit(
- Fts5Index *p, /* FTS index object */
- Fts5StructureSegment *pSeg, /* Description of segment */
- Fts5SegIter *pIter /* Object to populate */
-){
- if( pSeg->pgnoFirst==0 ){
- /* This happens if the segment is being used as an input to an incremental
- ** merge and all data has already been "trimmed". See function
- ** fts5TrimSegments() for details. In this case leave the iterator empty.
- ** The caller will see the (pIter->pLeaf==0) and assume the iterator is
- ** at EOF already. */
- assert( pIter->pLeaf==0 );
- return;
- }
-
- if( p->rc==SQLITE_OK ){
- memset(pIter, 0, sizeof(*pIter));
- fts5SegIterSetNext(p, pIter);
- pIter->pSeg = pSeg;
- pIter->iLeafPgno = pSeg->pgnoFirst-1;
- fts5SegIterNextPage(p, pIter);
- }
-
- if( p->rc==SQLITE_OK ){
- pIter->iLeafOffset = 4;
+** an error has already occurred when this function is called, it is a no-op.
+*/
+static void fts5SegIterInit(
+ Fts5Index *p, /* FTS index object */
+ Fts5StructureSegment *pSeg, /* Description of segment */
+ Fts5SegIter *pIter /* Object to populate */
+){
+ if( pSeg->pgnoFirst==0 ){
+ /* This happens if the segment is being used as an input to an incremental
+ ** merge and all data has already been "trimmed". See function
+ ** fts5TrimSegments() for details. In this case leave the iterator empty.
+ ** The caller will see the (pIter->pLeaf==0) and assume the iterator is
+ ** at EOF already. */
+ assert( pIter->pLeaf==0 );
+ return;
+ }
+
+ if( p->rc==SQLITE_OK ){
+ memset(pIter, 0, sizeof(*pIter));
+ fts5SegIterSetNext(p, pIter);
+ pIter->pSeg = pSeg;
+ pIter->iLeafPgno = pSeg->pgnoFirst-1;
+ fts5SegIterNextPage(p, pIter);
+ }
+
+ if( p->rc==SQLITE_OK ){
+ pIter->iLeafOffset = 4;
assert( pIter->pLeaf!=0 );
- assert_nc( pIter->pLeaf->nn>4 );
+ assert_nc( pIter->pLeaf->nn>4 );
assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
- pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
- fts5SegIterLoadTerm(p, pIter, 0);
- fts5SegIterLoadNPos(p, pIter);
- }
-}
-
-/*
-** This function is only ever called on iterators created by calls to
-** Fts5IndexQuery() with the FTS5INDEX_QUERY_DESC flag set.
-**
-** The iterator is in an unusual state when this function is called: the
-** Fts5SegIter.iLeafOffset variable is set to the offset of the start of
-** the position-list size field for the first relevant rowid on the page.
-** Fts5SegIter.rowid is set, but nPos and bDel are not.
-**
+ pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
+ fts5SegIterLoadTerm(p, pIter, 0);
+ fts5SegIterLoadNPos(p, pIter);
+ }
+}
+
+/*
+** This function is only ever called on iterators created by calls to
+** Fts5IndexQuery() with the FTS5INDEX_QUERY_DESC flag set.
+**
+** The iterator is in an unusual state when this function is called: the
+** Fts5SegIter.iLeafOffset variable is set to the offset of the start of
+** the position-list size field for the first relevant rowid on the page.
+** Fts5SegIter.rowid is set, but nPos and bDel are not.
+**
** This function advances the iterator so that it points to the last
** relevant rowid on the page and, if necessary, initializes the
-** aRowidOffset[] and iRowidOffset variables. At this point the iterator
-** is in its regular state - Fts5SegIter.iLeafOffset points to the first
-** byte of the position list content associated with said rowid.
-*/
-static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
- int eDetail = p->pConfig->eDetail;
- int n = pIter->pLeaf->szLeaf;
- int i = pIter->iLeafOffset;
- u8 *a = pIter->pLeaf->p;
- int iRowidOffset = 0;
-
- if( n>pIter->iEndofDoclist ){
- n = pIter->iEndofDoclist;
- }
-
- ASSERT_SZLEAF_OK(pIter->pLeaf);
- while( 1 ){
+** aRowidOffset[] and iRowidOffset variables. At this point the iterator
+** is in its regular state - Fts5SegIter.iLeafOffset points to the first
+** byte of the position list content associated with said rowid.
+*/
+static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
+ int eDetail = p->pConfig->eDetail;
+ int n = pIter->pLeaf->szLeaf;
+ int i = pIter->iLeafOffset;
+ u8 *a = pIter->pLeaf->p;
+ int iRowidOffset = 0;
+
+ if( n>pIter->iEndofDoclist ){
+ n = pIter->iEndofDoclist;
+ }
+
+ ASSERT_SZLEAF_OK(pIter->pLeaf);
+ while( 1 ){
u64 iDelta = 0;
-
- if( eDetail==FTS5_DETAIL_NONE ){
- /* todo */
- if( i<n && a[i]==0 ){
- i++;
- if( i<n && a[i]==0 ) i++;
- }
- }else{
- int nPos;
- int bDummy;
- i += fts5GetPoslistSize(&a[i], &nPos, &bDummy);
- i += nPos;
- }
- if( i>=n ) break;
+
+ if( eDetail==FTS5_DETAIL_NONE ){
+ /* todo */
+ if( i<n && a[i]==0 ){
+ i++;
+ if( i<n && a[i]==0 ) i++;
+ }
+ }else{
+ int nPos;
+ int bDummy;
+ i += fts5GetPoslistSize(&a[i], &nPos, &bDummy);
+ i += nPos;
+ }
+ if( i>=n ) break;
i += fts5GetVarint(&a[i], &iDelta);
- pIter->iRowid += iDelta;
-
- /* If necessary, grow the pIter->aRowidOffset[] array. */
- if( iRowidOffset>=pIter->nRowidOffset ){
- int nNew = pIter->nRowidOffset + 8;
+ pIter->iRowid += iDelta;
+
+ /* If necessary, grow the pIter->aRowidOffset[] array. */
+ if( iRowidOffset>=pIter->nRowidOffset ){
+ int nNew = pIter->nRowidOffset + 8;
int *aNew = (int*)sqlite3_realloc64(pIter->aRowidOffset,nNew*sizeof(int));
- if( aNew==0 ){
- p->rc = SQLITE_NOMEM;
- break;
- }
- pIter->aRowidOffset = aNew;
- pIter->nRowidOffset = nNew;
- }
-
- pIter->aRowidOffset[iRowidOffset++] = pIter->iLeafOffset;
- pIter->iLeafOffset = i;
- }
- pIter->iRowidOffset = iRowidOffset;
- fts5SegIterLoadNPos(p, pIter);
-}
-
-/*
-**
-*/
-static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){
- assert( pIter->flags & FTS5_SEGITER_REVERSE );
- assert( pIter->flags & FTS5_SEGITER_ONETERM );
-
- fts5DataRelease(pIter->pLeaf);
- pIter->pLeaf = 0;
- while( p->rc==SQLITE_OK && pIter->iLeafPgno>pIter->iTermLeafPgno ){
- Fts5Data *pNew;
- pIter->iLeafPgno--;
- pNew = fts5DataRead(p, FTS5_SEGMENT_ROWID(
- pIter->pSeg->iSegid, pIter->iLeafPgno
- ));
- if( pNew ){
- /* iTermLeafOffset may be equal to szLeaf if the term is the last
- ** thing on the page - i.e. the first rowid is on the following page.
- ** In this case leave pIter->pLeaf==0, this iterator is at EOF. */
- if( pIter->iLeafPgno==pIter->iTermLeafPgno ){
- assert( pIter->pLeaf==0 );
- if( pIter->iTermLeafOffset<pNew->szLeaf ){
- pIter->pLeaf = pNew;
- pIter->iLeafOffset = pIter->iTermLeafOffset;
- }
- }else{
- int iRowidOff;
- iRowidOff = fts5LeafFirstRowidOff(pNew);
- if( iRowidOff ){
+ if( aNew==0 ){
+ p->rc = SQLITE_NOMEM;
+ break;
+ }
+ pIter->aRowidOffset = aNew;
+ pIter->nRowidOffset = nNew;
+ }
+
+ pIter->aRowidOffset[iRowidOffset++] = pIter->iLeafOffset;
+ pIter->iLeafOffset = i;
+ }
+ pIter->iRowidOffset = iRowidOffset;
+ fts5SegIterLoadNPos(p, pIter);
+}
+
+/*
+**
+*/
+static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){
+ assert( pIter->flags & FTS5_SEGITER_REVERSE );
+ assert( pIter->flags & FTS5_SEGITER_ONETERM );
+
+ fts5DataRelease(pIter->pLeaf);
+ pIter->pLeaf = 0;
+ while( p->rc==SQLITE_OK && pIter->iLeafPgno>pIter->iTermLeafPgno ){
+ Fts5Data *pNew;
+ pIter->iLeafPgno--;
+ pNew = fts5DataRead(p, FTS5_SEGMENT_ROWID(
+ pIter->pSeg->iSegid, pIter->iLeafPgno
+ ));
+ if( pNew ){
+ /* iTermLeafOffset may be equal to szLeaf if the term is the last
+ ** thing on the page - i.e. the first rowid is on the following page.
+ ** In this case leave pIter->pLeaf==0, this iterator is at EOF. */
+ if( pIter->iLeafPgno==pIter->iTermLeafPgno ){
+ assert( pIter->pLeaf==0 );
+ if( pIter->iTermLeafOffset<pNew->szLeaf ){
+ pIter->pLeaf = pNew;
+ pIter->iLeafOffset = pIter->iTermLeafOffset;
+ }
+ }else{
+ int iRowidOff;
+ iRowidOff = fts5LeafFirstRowidOff(pNew);
+ if( iRowidOff ){
if( iRowidOff>=pNew->szLeaf ){
p->rc = FTS5_CORRUPT;
}else{
pIter->pLeaf = pNew;
pIter->iLeafOffset = iRowidOff;
}
- }
- }
-
- if( pIter->pLeaf ){
- u8 *a = &pIter->pLeaf->p[pIter->iLeafOffset];
- pIter->iLeafOffset += fts5GetVarint(a, (u64*)&pIter->iRowid);
- break;
- }else{
- fts5DataRelease(pNew);
- }
- }
- }
-
- if( pIter->pLeaf ){
- pIter->iEndofDoclist = pIter->pLeaf->nn+1;
- fts5SegIterReverseInitPage(p, pIter);
- }
-}
-
-/*
-** Return true if the iterator passed as the second argument currently
-** points to a delete marker. A delete marker is an entry with a 0 byte
-** position-list.
-*/
-static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5Iter *pIter){
- Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
- return (p->rc==SQLITE_OK && pSeg->pLeaf && pSeg->nPos==0);
-}
-
-/*
-** Advance iterator pIter to the next entry.
-**
-** This version of fts5SegIterNext() is only used by reverse iterators.
-*/
-static void fts5SegIterNext_Reverse(
- Fts5Index *p, /* FTS5 backend object */
- Fts5SegIter *pIter, /* Iterator to advance */
- int *pbUnused /* Unused */
-){
- assert( pIter->flags & FTS5_SEGITER_REVERSE );
- assert( pIter->pNextLeaf==0 );
- UNUSED_PARAM(pbUnused);
-
- if( pIter->iRowidOffset>0 ){
- u8 *a = pIter->pLeaf->p;
- int iOff;
+ }
+ }
+
+ if( pIter->pLeaf ){
+ u8 *a = &pIter->pLeaf->p[pIter->iLeafOffset];
+ pIter->iLeafOffset += fts5GetVarint(a, (u64*)&pIter->iRowid);
+ break;
+ }else{
+ fts5DataRelease(pNew);
+ }
+ }
+ }
+
+ if( pIter->pLeaf ){
+ pIter->iEndofDoclist = pIter->pLeaf->nn+1;
+ fts5SegIterReverseInitPage(p, pIter);
+ }
+}
+
+/*
+** Return true if the iterator passed as the second argument currently
+** points to a delete marker. A delete marker is an entry with a 0 byte
+** position-list.
+*/
+static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5Iter *pIter){
+ Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
+ return (p->rc==SQLITE_OK && pSeg->pLeaf && pSeg->nPos==0);
+}
+
+/*
+** Advance iterator pIter to the next entry.
+**
+** This version of fts5SegIterNext() is only used by reverse iterators.
+*/
+static void fts5SegIterNext_Reverse(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegIter *pIter, /* Iterator to advance */
+ int *pbUnused /* Unused */
+){
+ assert( pIter->flags & FTS5_SEGITER_REVERSE );
+ assert( pIter->pNextLeaf==0 );
+ UNUSED_PARAM(pbUnused);
+
+ if( pIter->iRowidOffset>0 ){
+ u8 *a = pIter->pLeaf->p;
+ int iOff;
u64 iDelta;
-
- pIter->iRowidOffset--;
- pIter->iLeafOffset = pIter->aRowidOffset[pIter->iRowidOffset];
- fts5SegIterLoadNPos(p, pIter);
- iOff = pIter->iLeafOffset;
- if( p->pConfig->eDetail!=FTS5_DETAIL_NONE ){
- iOff += pIter->nPos;
- }
+
+ pIter->iRowidOffset--;
+ pIter->iLeafOffset = pIter->aRowidOffset[pIter->iRowidOffset];
+ fts5SegIterLoadNPos(p, pIter);
+ iOff = pIter->iLeafOffset;
+ if( p->pConfig->eDetail!=FTS5_DETAIL_NONE ){
+ iOff += pIter->nPos;
+ }
fts5GetVarint(&a[iOff], &iDelta);
- pIter->iRowid -= iDelta;
- }else{
- fts5SegIterReverseNewPage(p, pIter);
- }
-}
-
-/*
-** Advance iterator pIter to the next entry.
-**
-** This version of fts5SegIterNext() is only used if detail=none and the
-** iterator is not a reverse direction iterator.
-*/
-static void fts5SegIterNext_None(
- Fts5Index *p, /* FTS5 backend object */
- Fts5SegIter *pIter, /* Iterator to advance */
- int *pbNewTerm /* OUT: Set for new term */
-){
- int iOff;
-
- assert( p->rc==SQLITE_OK );
- assert( (pIter->flags & FTS5_SEGITER_REVERSE)==0 );
- assert( p->pConfig->eDetail==FTS5_DETAIL_NONE );
-
- ASSERT_SZLEAF_OK(pIter->pLeaf);
- iOff = pIter->iLeafOffset;
-
- /* Next entry is on the next page */
- if( pIter->pSeg && iOff>=pIter->pLeaf->szLeaf ){
- fts5SegIterNextPage(p, pIter);
- if( p->rc || pIter->pLeaf==0 ) return;
- pIter->iRowid = 0;
- iOff = 4;
- }
-
- if( iOff<pIter->iEndofDoclist ){
- /* Next entry is on the current page */
- i64 iDelta;
- iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta);
- pIter->iLeafOffset = iOff;
- pIter->iRowid += iDelta;
- }else if( (pIter->flags & FTS5_SEGITER_ONETERM)==0 ){
- if( pIter->pSeg ){
- int nKeep = 0;
- if( iOff!=fts5LeafFirstTermOff(pIter->pLeaf) ){
- iOff += fts5GetVarint32(&pIter->pLeaf->p[iOff], nKeep);
- }
- pIter->iLeafOffset = iOff;
- fts5SegIterLoadTerm(p, pIter, nKeep);
- }else{
- const u8 *pList = 0;
- const char *zTerm = 0;
- int nList;
- sqlite3Fts5HashScanNext(p->pHash);
- sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
- if( pList==0 ) goto next_none_eof;
- pIter->pLeaf->p = (u8*)pList;
- pIter->pLeaf->nn = nList;
- pIter->pLeaf->szLeaf = nList;
- pIter->iEndofDoclist = nList;
- sqlite3Fts5BufferSet(&p->rc,&pIter->term, (int)strlen(zTerm), (u8*)zTerm);
- pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
- }
-
- if( pbNewTerm ) *pbNewTerm = 1;
- }else{
- goto next_none_eof;
- }
-
- fts5SegIterLoadNPos(p, pIter);
-
- return;
- next_none_eof:
- fts5DataRelease(pIter->pLeaf);
- pIter->pLeaf = 0;
-}
-
-
-/*
+ pIter->iRowid -= iDelta;
+ }else{
+ fts5SegIterReverseNewPage(p, pIter);
+ }
+}
+
+/*
** Advance iterator pIter to the next entry.
-**
+**
+** This version of fts5SegIterNext() is only used if detail=none and the
+** iterator is not a reverse direction iterator.
+*/
+static void fts5SegIterNext_None(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegIter *pIter, /* Iterator to advance */
+ int *pbNewTerm /* OUT: Set for new term */
+){
+ int iOff;
+
+ assert( p->rc==SQLITE_OK );
+ assert( (pIter->flags & FTS5_SEGITER_REVERSE)==0 );
+ assert( p->pConfig->eDetail==FTS5_DETAIL_NONE );
+
+ ASSERT_SZLEAF_OK(pIter->pLeaf);
+ iOff = pIter->iLeafOffset;
+
+ /* Next entry is on the next page */
+ if( pIter->pSeg && iOff>=pIter->pLeaf->szLeaf ){
+ fts5SegIterNextPage(p, pIter);
+ if( p->rc || pIter->pLeaf==0 ) return;
+ pIter->iRowid = 0;
+ iOff = 4;
+ }
+
+ if( iOff<pIter->iEndofDoclist ){
+ /* Next entry is on the current page */
+ i64 iDelta;
+ iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta);
+ pIter->iLeafOffset = iOff;
+ pIter->iRowid += iDelta;
+ }else if( (pIter->flags & FTS5_SEGITER_ONETERM)==0 ){
+ if( pIter->pSeg ){
+ int nKeep = 0;
+ if( iOff!=fts5LeafFirstTermOff(pIter->pLeaf) ){
+ iOff += fts5GetVarint32(&pIter->pLeaf->p[iOff], nKeep);
+ }
+ pIter->iLeafOffset = iOff;
+ fts5SegIterLoadTerm(p, pIter, nKeep);
+ }else{
+ const u8 *pList = 0;
+ const char *zTerm = 0;
+ int nList;
+ sqlite3Fts5HashScanNext(p->pHash);
+ sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
+ if( pList==0 ) goto next_none_eof;
+ pIter->pLeaf->p = (u8*)pList;
+ pIter->pLeaf->nn = nList;
+ pIter->pLeaf->szLeaf = nList;
+ pIter->iEndofDoclist = nList;
+ sqlite3Fts5BufferSet(&p->rc,&pIter->term, (int)strlen(zTerm), (u8*)zTerm);
+ pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
+ }
+
+ if( pbNewTerm ) *pbNewTerm = 1;
+ }else{
+ goto next_none_eof;
+ }
+
+ fts5SegIterLoadNPos(p, pIter);
+
+ return;
+ next_none_eof:
+ fts5DataRelease(pIter->pLeaf);
+ pIter->pLeaf = 0;
+}
+
+
+/*
+** Advance iterator pIter to the next entry.
+**
** If an error occurs, Fts5Index.rc is set to an appropriate error code. It
** is not considered an error if the iterator reaches EOF. If an error has
-** already occurred when this function is called, it is a no-op.
-*/
-static void fts5SegIterNext(
- Fts5Index *p, /* FTS5 backend object */
- Fts5SegIter *pIter, /* Iterator to advance */
- int *pbNewTerm /* OUT: Set for new term */
-){
- Fts5Data *pLeaf = pIter->pLeaf;
- int iOff;
- int bNewTerm = 0;
- int nKeep = 0;
- u8 *a;
- int n;
-
- assert( pbNewTerm==0 || *pbNewTerm==0 );
- assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE );
-
- /* Search for the end of the position list within the current page. */
- a = pLeaf->p;
- n = pLeaf->szLeaf;
-
- ASSERT_SZLEAF_OK(pLeaf);
- iOff = pIter->iLeafOffset + pIter->nPos;
-
- if( iOff<n ){
- /* The next entry is on the current page. */
- assert_nc( iOff<=pIter->iEndofDoclist );
- if( iOff>=pIter->iEndofDoclist ){
- bNewTerm = 1;
- if( iOff!=fts5LeafFirstTermOff(pLeaf) ){
- iOff += fts5GetVarint32(&a[iOff], nKeep);
- }
- }else{
- u64 iDelta;
- iOff += sqlite3Fts5GetVarint(&a[iOff], &iDelta);
- pIter->iRowid += iDelta;
- assert_nc( iDelta>0 );
- }
- pIter->iLeafOffset = iOff;
-
- }else if( pIter->pSeg==0 ){
- const u8 *pList = 0;
- const char *zTerm = 0;
- int nList = 0;
- assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm );
- if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){
- sqlite3Fts5HashScanNext(p->pHash);
- sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
- }
- if( pList==0 ){
- fts5DataRelease(pIter->pLeaf);
- pIter->pLeaf = 0;
- }else{
- pIter->pLeaf->p = (u8*)pList;
- pIter->pLeaf->nn = nList;
- pIter->pLeaf->szLeaf = nList;
- pIter->iEndofDoclist = nList+1;
- sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm),
- (u8*)zTerm);
- pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
- *pbNewTerm = 1;
- }
- }else{
- iOff = 0;
- /* Next entry is not on the current page */
- while( iOff==0 ){
- fts5SegIterNextPage(p, pIter);
- pLeaf = pIter->pLeaf;
- if( pLeaf==0 ) break;
- ASSERT_SZLEAF_OK(pLeaf);
- if( (iOff = fts5LeafFirstRowidOff(pLeaf)) && iOff<pLeaf->szLeaf ){
- iOff += sqlite3Fts5GetVarint(&pLeaf->p[iOff], (u64*)&pIter->iRowid);
- pIter->iLeafOffset = iOff;
-
- if( pLeaf->nn>pLeaf->szLeaf ){
- pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
- &pLeaf->p[pLeaf->szLeaf], pIter->iEndofDoclist
- );
- }
- }
- else if( pLeaf->nn>pLeaf->szLeaf ){
- pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
- &pLeaf->p[pLeaf->szLeaf], iOff
- );
- pIter->iLeafOffset = iOff;
- pIter->iEndofDoclist = iOff;
- bNewTerm = 1;
- }
- assert_nc( iOff<pLeaf->szLeaf );
- if( iOff>pLeaf->szLeaf ){
- p->rc = FTS5_CORRUPT;
- return;
- }
- }
- }
-
- /* Check if the iterator is now at EOF. If so, return early. */
- if( pIter->pLeaf ){
- if( bNewTerm ){
- if( pIter->flags & FTS5_SEGITER_ONETERM ){
- fts5DataRelease(pIter->pLeaf);
- pIter->pLeaf = 0;
- }else{
- fts5SegIterLoadTerm(p, pIter, nKeep);
- fts5SegIterLoadNPos(p, pIter);
- if( pbNewTerm ) *pbNewTerm = 1;
- }
- }else{
- /* The following could be done by calling fts5SegIterLoadNPos(). But
- ** this block is particularly performance critical, so equivalent
+** already occurred when this function is called, it is a no-op.
+*/
+static void fts5SegIterNext(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegIter *pIter, /* Iterator to advance */
+ int *pbNewTerm /* OUT: Set for new term */
+){
+ Fts5Data *pLeaf = pIter->pLeaf;
+ int iOff;
+ int bNewTerm = 0;
+ int nKeep = 0;
+ u8 *a;
+ int n;
+
+ assert( pbNewTerm==0 || *pbNewTerm==0 );
+ assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE );
+
+ /* Search for the end of the position list within the current page. */
+ a = pLeaf->p;
+ n = pLeaf->szLeaf;
+
+ ASSERT_SZLEAF_OK(pLeaf);
+ iOff = pIter->iLeafOffset + pIter->nPos;
+
+ if( iOff<n ){
+ /* The next entry is on the current page. */
+ assert_nc( iOff<=pIter->iEndofDoclist );
+ if( iOff>=pIter->iEndofDoclist ){
+ bNewTerm = 1;
+ if( iOff!=fts5LeafFirstTermOff(pLeaf) ){
+ iOff += fts5GetVarint32(&a[iOff], nKeep);
+ }
+ }else{
+ u64 iDelta;
+ iOff += sqlite3Fts5GetVarint(&a[iOff], &iDelta);
+ pIter->iRowid += iDelta;
+ assert_nc( iDelta>0 );
+ }
+ pIter->iLeafOffset = iOff;
+
+ }else if( pIter->pSeg==0 ){
+ const u8 *pList = 0;
+ const char *zTerm = 0;
+ int nList = 0;
+ assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm );
+ if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){
+ sqlite3Fts5HashScanNext(p->pHash);
+ sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
+ }
+ if( pList==0 ){
+ fts5DataRelease(pIter->pLeaf);
+ pIter->pLeaf = 0;
+ }else{
+ pIter->pLeaf->p = (u8*)pList;
+ pIter->pLeaf->nn = nList;
+ pIter->pLeaf->szLeaf = nList;
+ pIter->iEndofDoclist = nList+1;
+ sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm),
+ (u8*)zTerm);
+ pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
+ *pbNewTerm = 1;
+ }
+ }else{
+ iOff = 0;
+ /* Next entry is not on the current page */
+ while( iOff==0 ){
+ fts5SegIterNextPage(p, pIter);
+ pLeaf = pIter->pLeaf;
+ if( pLeaf==0 ) break;
+ ASSERT_SZLEAF_OK(pLeaf);
+ if( (iOff = fts5LeafFirstRowidOff(pLeaf)) && iOff<pLeaf->szLeaf ){
+ iOff += sqlite3Fts5GetVarint(&pLeaf->p[iOff], (u64*)&pIter->iRowid);
+ pIter->iLeafOffset = iOff;
+
+ if( pLeaf->nn>pLeaf->szLeaf ){
+ pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
+ &pLeaf->p[pLeaf->szLeaf], pIter->iEndofDoclist
+ );
+ }
+ }
+ else if( pLeaf->nn>pLeaf->szLeaf ){
+ pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
+ &pLeaf->p[pLeaf->szLeaf], iOff
+ );
+ pIter->iLeafOffset = iOff;
+ pIter->iEndofDoclist = iOff;
+ bNewTerm = 1;
+ }
+ assert_nc( iOff<pLeaf->szLeaf );
+ if( iOff>pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ return;
+ }
+ }
+ }
+
+ /* Check if the iterator is now at EOF. If so, return early. */
+ if( pIter->pLeaf ){
+ if( bNewTerm ){
+ if( pIter->flags & FTS5_SEGITER_ONETERM ){
+ fts5DataRelease(pIter->pLeaf);
+ pIter->pLeaf = 0;
+ }else{
+ fts5SegIterLoadTerm(p, pIter, nKeep);
+ fts5SegIterLoadNPos(p, pIter);
+ if( pbNewTerm ) *pbNewTerm = 1;
+ }
+ }else{
+ /* The following could be done by calling fts5SegIterLoadNPos(). But
+ ** this block is particularly performance critical, so equivalent
** code is inlined. */
- int nSz;
+ int nSz;
assert_nc( pIter->iLeafOffset<=pIter->pLeaf->nn );
- fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz);
- pIter->bDel = (nSz & 0x0001);
- pIter->nPos = nSz>>1;
- assert_nc( pIter->nPos>=0 );
- }
- }
-}
-
-#define SWAPVAL(T, a, b) { T tmp; tmp=a; a=b; b=tmp; }
-
-#define fts5IndexSkipVarint(a, iOff) { \
- int iEnd = iOff+9; \
- while( (a[iOff++] & 0x80) && iOff<iEnd ); \
-}
-
-/*
-** Iterator pIter currently points to the first rowid in a doclist. This
-** function sets the iterator up so that iterates in reverse order through
-** the doclist.
-*/
-static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
- Fts5DlidxIter *pDlidx = pIter->pDlidx;
- Fts5Data *pLast = 0;
- int pgnoLast = 0;
-
- if( pDlidx ){
- int iSegid = pIter->pSeg->iSegid;
- pgnoLast = fts5DlidxIterPgno(pDlidx);
+ fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz);
+ pIter->bDel = (nSz & 0x0001);
+ pIter->nPos = nSz>>1;
+ assert_nc( pIter->nPos>=0 );
+ }
+ }
+}
+
+#define SWAPVAL(T, a, b) { T tmp; tmp=a; a=b; b=tmp; }
+
+#define fts5IndexSkipVarint(a, iOff) { \
+ int iEnd = iOff+9; \
+ while( (a[iOff++] & 0x80) && iOff<iEnd ); \
+}
+
+/*
+** Iterator pIter currently points to the first rowid in a doclist. This
+** function sets the iterator up so that iterates in reverse order through
+** the doclist.
+*/
+static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
+ Fts5DlidxIter *pDlidx = pIter->pDlidx;
+ Fts5Data *pLast = 0;
+ int pgnoLast = 0;
+
+ if( pDlidx ){
+ int iSegid = pIter->pSeg->iSegid;
+ pgnoLast = fts5DlidxIterPgno(pDlidx);
pLast = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast));
- }else{
- Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */
-
- /* Currently, Fts5SegIter.iLeafOffset points to the first byte of
- ** position-list content for the current rowid. Back it up so that it
- ** points to the start of the position-list size field. */
- int iPoslist;
- if( pIter->iTermLeafPgno==pIter->iLeafPgno ){
- iPoslist = pIter->iTermLeafOffset;
- }else{
- iPoslist = 4;
- }
- fts5IndexSkipVarint(pLeaf->p, iPoslist);
- pIter->iLeafOffset = iPoslist;
-
- /* If this condition is true then the largest rowid for the current
- ** term may not be stored on the current page. So search forward to
- ** see where said rowid really is. */
- if( pIter->iEndofDoclist>=pLeaf->szLeaf ){
- int pgno;
- Fts5StructureSegment *pSeg = pIter->pSeg;
-
- /* The last rowid in the doclist may not be on the current page. Search
- ** forward to find the page containing the last rowid. */
- for(pgno=pIter->iLeafPgno+1; !p->rc && pgno<=pSeg->pgnoLast; pgno++){
- i64 iAbs = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno);
+ }else{
+ Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */
+
+ /* Currently, Fts5SegIter.iLeafOffset points to the first byte of
+ ** position-list content for the current rowid. Back it up so that it
+ ** points to the start of the position-list size field. */
+ int iPoslist;
+ if( pIter->iTermLeafPgno==pIter->iLeafPgno ){
+ iPoslist = pIter->iTermLeafOffset;
+ }else{
+ iPoslist = 4;
+ }
+ fts5IndexSkipVarint(pLeaf->p, iPoslist);
+ pIter->iLeafOffset = iPoslist;
+
+ /* If this condition is true then the largest rowid for the current
+ ** term may not be stored on the current page. So search forward to
+ ** see where said rowid really is. */
+ if( pIter->iEndofDoclist>=pLeaf->szLeaf ){
+ int pgno;
+ Fts5StructureSegment *pSeg = pIter->pSeg;
+
+ /* The last rowid in the doclist may not be on the current page. Search
+ ** forward to find the page containing the last rowid. */
+ for(pgno=pIter->iLeafPgno+1; !p->rc && pgno<=pSeg->pgnoLast; pgno++){
+ i64 iAbs = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno);
Fts5Data *pNew = fts5LeafRead(p, iAbs);
- if( pNew ){
- int iRowid, bTermless;
- iRowid = fts5LeafFirstRowidOff(pNew);
- bTermless = fts5LeafIsTermless(pNew);
- if( iRowid ){
- SWAPVAL(Fts5Data*, pNew, pLast);
- pgnoLast = pgno;
- }
- fts5DataRelease(pNew);
- if( bTermless==0 ) break;
- }
- }
- }
- }
-
- /* If pLast is NULL at this point, then the last rowid for this doclist
+ if( pNew ){
+ int iRowid, bTermless;
+ iRowid = fts5LeafFirstRowidOff(pNew);
+ bTermless = fts5LeafIsTermless(pNew);
+ if( iRowid ){
+ SWAPVAL(Fts5Data*, pNew, pLast);
+ pgnoLast = pgno;
+ }
+ fts5DataRelease(pNew);
+ if( bTermless==0 ) break;
+ }
+ }
+ }
+ }
+
+ /* If pLast is NULL at this point, then the last rowid for this doclist
** lies on the page currently indicated by the iterator. In this case
- ** pIter->iLeafOffset is already set to point to the position-list size
- ** field associated with the first relevant rowid on the page.
- **
- ** Or, if pLast is non-NULL, then it is the page that contains the last
- ** rowid. In this case configure the iterator so that it points to the
- ** first rowid on this page.
- */
- if( pLast ){
- int iOff;
- fts5DataRelease(pIter->pLeaf);
- pIter->pLeaf = pLast;
- pIter->iLeafPgno = pgnoLast;
- iOff = fts5LeafFirstRowidOff(pLast);
+ ** pIter->iLeafOffset is already set to point to the position-list size
+ ** field associated with the first relevant rowid on the page.
+ **
+ ** Or, if pLast is non-NULL, then it is the page that contains the last
+ ** rowid. In this case configure the iterator so that it points to the
+ ** first rowid on this page.
+ */
+ if( pLast ){
+ int iOff;
+ fts5DataRelease(pIter->pLeaf);
+ pIter->pLeaf = pLast;
+ pIter->iLeafPgno = pgnoLast;
+ iOff = fts5LeafFirstRowidOff(pLast);
if( iOff>pLast->szLeaf ){
p->rc = FTS5_CORRUPT;
return;
}
- iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid);
- pIter->iLeafOffset = iOff;
-
- if( fts5LeafIsTermless(pLast) ){
- pIter->iEndofDoclist = pLast->nn+1;
- }else{
- pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast);
- }
- }
-
- fts5SegIterReverseInitPage(p, pIter);
-}
-
-/*
-** Iterator pIter currently points to the first rowid of a doclist.
+ iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid);
+ pIter->iLeafOffset = iOff;
+
+ if( fts5LeafIsTermless(pLast) ){
+ pIter->iEndofDoclist = pLast->nn+1;
+ }else{
+ pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast);
+ }
+ }
+
+ fts5SegIterReverseInitPage(p, pIter);
+}
+
+/*
+** Iterator pIter currently points to the first rowid of a doclist.
** There is a doclist-index associated with the final term on the current
** page. If the current term is the last term on the page, load the
-** doclist-index from disk and initialize an iterator at (pIter->pDlidx).
-*/
-static void fts5SegIterLoadDlidx(Fts5Index *p, Fts5SegIter *pIter){
- int iSeg = pIter->pSeg->iSegid;
- int bRev = (pIter->flags & FTS5_SEGITER_REVERSE);
- Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */
-
- assert( pIter->flags & FTS5_SEGITER_ONETERM );
- assert( pIter->pDlidx==0 );
-
- /* Check if the current doclist ends on this page. If it does, return
- ** early without loading the doclist-index (as it belongs to a different
- ** term. */
+** doclist-index from disk and initialize an iterator at (pIter->pDlidx).
+*/
+static void fts5SegIterLoadDlidx(Fts5Index *p, Fts5SegIter *pIter){
+ int iSeg = pIter->pSeg->iSegid;
+ int bRev = (pIter->flags & FTS5_SEGITER_REVERSE);
+ Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */
+
+ assert( pIter->flags & FTS5_SEGITER_ONETERM );
+ assert( pIter->pDlidx==0 );
+
+ /* Check if the current doclist ends on this page. If it does, return
+ ** early without loading the doclist-index (as it belongs to a different
+ ** term. */
if( pIter->iTermLeafPgno==pIter->iLeafPgno
&& pIter->iEndofDoclist<pLeaf->szLeaf
- ){
- return;
- }
-
- pIter->pDlidx = fts5DlidxIterInit(p, bRev, iSeg, pIter->iTermLeafPgno);
-}
-
-/*
-** The iterator object passed as the second argument currently contains
-** no valid values except for the Fts5SegIter.pLeaf member variable. This
-** function searches the leaf page for a term matching (pTerm/nTerm).
-**
-** If the specified term is found on the page, then the iterator is left
-** pointing to it. If argument bGe is zero and the term is not found,
-** the iterator is left pointing at EOF.
-**
-** If bGe is non-zero and the specified term is not found, then the
-** iterator is left pointing to the smallest term in the segment that
-** is larger than the specified term, even if this term is not on the
-** current page.
-*/
-static void fts5LeafSeek(
- Fts5Index *p, /* Leave any error code here */
- int bGe, /* True for a >= search */
- Fts5SegIter *pIter, /* Iterator to seek */
- const u8 *pTerm, int nTerm /* Term to search for */
-){
+ ){
+ return;
+ }
+
+ pIter->pDlidx = fts5DlidxIterInit(p, bRev, iSeg, pIter->iTermLeafPgno);
+}
+
+/*
+** The iterator object passed as the second argument currently contains
+** no valid values except for the Fts5SegIter.pLeaf member variable. This
+** function searches the leaf page for a term matching (pTerm/nTerm).
+**
+** If the specified term is found on the page, then the iterator is left
+** pointing to it. If argument bGe is zero and the term is not found,
+** the iterator is left pointing at EOF.
+**
+** If bGe is non-zero and the specified term is not found, then the
+** iterator is left pointing to the smallest term in the segment that
+** is larger than the specified term, even if this term is not on the
+** current page.
+*/
+static void fts5LeafSeek(
+ Fts5Index *p, /* Leave any error code here */
+ int bGe, /* True for a >= search */
+ Fts5SegIter *pIter, /* Iterator to seek */
+ const u8 *pTerm, int nTerm /* Term to search for */
+){
u32 iOff;
- const u8 *a = pIter->pLeaf->p;
+ const u8 *a = pIter->pLeaf->p;
u32 n = (u32)pIter->pLeaf->nn;
-
+
u32 nMatch = 0;
u32 nKeep = 0;
u32 nNew = 0;
u32 iTermOff;
u32 iPgidx; /* Current offset in pgidx */
- int bEndOfPage = 0;
-
- assert( p->rc==SQLITE_OK );
-
+ int bEndOfPage = 0;
+
+ assert( p->rc==SQLITE_OK );
+
iPgidx = (u32)pIter->pLeaf->szLeaf;
- iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
- iOff = iTermOff;
- if( iOff>n ){
- p->rc = FTS5_CORRUPT;
- return;
- }
-
- while( 1 ){
-
- /* Figure out how many new bytes are in this term */
- fts5FastGetVarint32(a, iOff, nNew);
- if( nKeep<nMatch ){
- goto search_failed;
- }
-
- assert( nKeep>=nMatch );
- if( nKeep==nMatch ){
+ iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
+ iOff = iTermOff;
+ if( iOff>n ){
+ p->rc = FTS5_CORRUPT;
+ return;
+ }
+
+ while( 1 ){
+
+ /* Figure out how many new bytes are in this term */
+ fts5FastGetVarint32(a, iOff, nNew);
+ if( nKeep<nMatch ){
+ goto search_failed;
+ }
+
+ assert( nKeep>=nMatch );
+ if( nKeep==nMatch ){
u32 nCmp;
u32 i;
nCmp = (u32)MIN(nNew, nTerm-nMatch);
- for(i=0; i<nCmp; i++){
- if( a[iOff+i]!=pTerm[nMatch+i] ) break;
- }
- nMatch += i;
-
+ for(i=0; i<nCmp; i++){
+ if( a[iOff+i]!=pTerm[nMatch+i] ) break;
+ }
+ nMatch += i;
+
if( (u32)nTerm==nMatch ){
- if( i==nNew ){
- goto search_success;
- }else{
- goto search_failed;
- }
- }else if( i<nNew && a[iOff+i]>pTerm[nMatch] ){
- goto search_failed;
- }
- }
-
- if( iPgidx>=n ){
- bEndOfPage = 1;
- break;
- }
-
- iPgidx += fts5GetVarint32(&a[iPgidx], nKeep);
- iTermOff += nKeep;
- iOff = iTermOff;
-
- if( iOff>=n ){
- p->rc = FTS5_CORRUPT;
- return;
- }
-
- /* Read the nKeep field of the next term. */
- fts5FastGetVarint32(a, iOff, nKeep);
- }
-
- search_failed:
- if( bGe==0 ){
- fts5DataRelease(pIter->pLeaf);
- pIter->pLeaf = 0;
- return;
- }else if( bEndOfPage ){
- do {
- fts5SegIterNextPage(p, pIter);
- if( pIter->pLeaf==0 ) return;
- a = pIter->pLeaf->p;
- if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
+ if( i==nNew ){
+ goto search_success;
+ }else{
+ goto search_failed;
+ }
+ }else if( i<nNew && a[iOff+i]>pTerm[nMatch] ){
+ goto search_failed;
+ }
+ }
+
+ if( iPgidx>=n ){
+ bEndOfPage = 1;
+ break;
+ }
+
+ iPgidx += fts5GetVarint32(&a[iPgidx], nKeep);
+ iTermOff += nKeep;
+ iOff = iTermOff;
+
+ if( iOff>=n ){
+ p->rc = FTS5_CORRUPT;
+ return;
+ }
+
+ /* Read the nKeep field of the next term. */
+ fts5FastGetVarint32(a, iOff, nKeep);
+ }
+
+ search_failed:
+ if( bGe==0 ){
+ fts5DataRelease(pIter->pLeaf);
+ pIter->pLeaf = 0;
+ return;
+ }else if( bEndOfPage ){
+ do {
+ fts5SegIterNextPage(p, pIter);
+ if( pIter->pLeaf==0 ) return;
+ a = pIter->pLeaf->p;
+ if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
iPgidx = (u32)pIter->pLeaf->szLeaf;
- iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
+ iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
if( iOff<4 || (i64)iOff>=pIter->pLeaf->szLeaf ){
- p->rc = FTS5_CORRUPT;
+ p->rc = FTS5_CORRUPT;
return;
- }else{
- nKeep = 0;
- iTermOff = iOff;
+ }else{
+ nKeep = 0;
+ iTermOff = iOff;
n = (u32)pIter->pLeaf->nn;
- iOff += fts5GetVarint32(&a[iOff], nNew);
- break;
- }
- }
- }while( 1 );
- }
-
- search_success:
+ iOff += fts5GetVarint32(&a[iOff], nNew);
+ break;
+ }
+ }
+ }while( 1 );
+ }
+
+ search_success:
if( (i64)iOff+nNew>n || nNew<1 ){
p->rc = FTS5_CORRUPT;
return;
}
pIter->iLeafOffset = iOff + nNew;
- pIter->iTermLeafOffset = pIter->iLeafOffset;
- pIter->iTermLeafPgno = pIter->iLeafPgno;
-
- fts5BufferSet(&p->rc, &pIter->term, nKeep, pTerm);
- fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
-
- if( iPgidx>=n ){
- pIter->iEndofDoclist = pIter->pLeaf->nn+1;
- }else{
- int nExtra;
- iPgidx += fts5GetVarint32(&a[iPgidx], nExtra);
- pIter->iEndofDoclist = iTermOff + nExtra;
- }
- pIter->iPgidxOff = iPgidx;
-
- fts5SegIterLoadRowid(p, pIter);
- fts5SegIterLoadNPos(p, pIter);
-}
-
-static sqlite3_stmt *fts5IdxSelectStmt(Fts5Index *p){
- if( p->pIdxSelect==0 ){
- Fts5Config *pConfig = p->pConfig;
- fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf(
- "SELECT pgno FROM '%q'.'%q_idx' WHERE "
- "segid=? AND term<=? ORDER BY term DESC LIMIT 1",
- pConfig->zDb, pConfig->zName
- ));
- }
- return p->pIdxSelect;
-}
-
-/*
-** Initialize the object pIter to point to term pTerm/nTerm within segment
-** pSeg. If there is no such term in the index, the iterator is set to EOF.
-**
+ pIter->iTermLeafOffset = pIter->iLeafOffset;
+ pIter->iTermLeafPgno = pIter->iLeafPgno;
+
+ fts5BufferSet(&p->rc, &pIter->term, nKeep, pTerm);
+ fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
+
+ if( iPgidx>=n ){
+ pIter->iEndofDoclist = pIter->pLeaf->nn+1;
+ }else{
+ int nExtra;
+ iPgidx += fts5GetVarint32(&a[iPgidx], nExtra);
+ pIter->iEndofDoclist = iTermOff + nExtra;
+ }
+ pIter->iPgidxOff = iPgidx;
+
+ fts5SegIterLoadRowid(p, pIter);
+ fts5SegIterLoadNPos(p, pIter);
+}
+
+static sqlite3_stmt *fts5IdxSelectStmt(Fts5Index *p){
+ if( p->pIdxSelect==0 ){
+ Fts5Config *pConfig = p->pConfig;
+ fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf(
+ "SELECT pgno FROM '%q'.'%q_idx' WHERE "
+ "segid=? AND term<=? ORDER BY term DESC LIMIT 1",
+ pConfig->zDb, pConfig->zName
+ ));
+ }
+ return p->pIdxSelect;
+}
+
+/*
+** Initialize the object pIter to point to term pTerm/nTerm within segment
+** pSeg. If there is no such term in the index, the iterator is set to EOF.
+**
** If an error occurs, Fts5Index.rc is set to an appropriate error code. If
-** an error has already occurred when this function is called, it is a no-op.
-*/
-static void fts5SegIterSeekInit(
- Fts5Index *p, /* FTS5 backend */
- const u8 *pTerm, int nTerm, /* Term to seek to */
- int flags, /* Mask of FTS5INDEX_XXX flags */
- Fts5StructureSegment *pSeg, /* Description of segment */
- Fts5SegIter *pIter /* Object to populate */
-){
- int iPg = 1;
- int bGe = (flags & FTS5INDEX_QUERY_SCAN);
- int bDlidx = 0; /* True if there is a doclist-index */
- sqlite3_stmt *pIdxSelect = 0;
-
- assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 );
- assert( pTerm && nTerm );
- memset(pIter, 0, sizeof(*pIter));
- pIter->pSeg = pSeg;
-
- /* This block sets stack variable iPg to the leaf page number that may
- ** contain term (pTerm/nTerm), if it is present in the segment. */
- pIdxSelect = fts5IdxSelectStmt(p);
- if( p->rc ) return;
- sqlite3_bind_int(pIdxSelect, 1, pSeg->iSegid);
- sqlite3_bind_blob(pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC);
- if( SQLITE_ROW==sqlite3_step(pIdxSelect) ){
- i64 val = sqlite3_column_int(pIdxSelect, 0);
- iPg = (int)(val>>1);
- bDlidx = (val & 0x0001);
- }
- p->rc = sqlite3_reset(pIdxSelect);
+** an error has already occurred when this function is called, it is a no-op.
+*/
+static void fts5SegIterSeekInit(
+ Fts5Index *p, /* FTS5 backend */
+ const u8 *pTerm, int nTerm, /* Term to seek to */
+ int flags, /* Mask of FTS5INDEX_XXX flags */
+ Fts5StructureSegment *pSeg, /* Description of segment */
+ Fts5SegIter *pIter /* Object to populate */
+){
+ int iPg = 1;
+ int bGe = (flags & FTS5INDEX_QUERY_SCAN);
+ int bDlidx = 0; /* True if there is a doclist-index */
+ sqlite3_stmt *pIdxSelect = 0;
+
+ assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 );
+ assert( pTerm && nTerm );
+ memset(pIter, 0, sizeof(*pIter));
+ pIter->pSeg = pSeg;
+
+ /* This block sets stack variable iPg to the leaf page number that may
+ ** contain term (pTerm/nTerm), if it is present in the segment. */
+ pIdxSelect = fts5IdxSelectStmt(p);
+ if( p->rc ) return;
+ sqlite3_bind_int(pIdxSelect, 1, pSeg->iSegid);
+ sqlite3_bind_blob(pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC);
+ if( SQLITE_ROW==sqlite3_step(pIdxSelect) ){
+ i64 val = sqlite3_column_int(pIdxSelect, 0);
+ iPg = (int)(val>>1);
+ bDlidx = (val & 0x0001);
+ }
+ p->rc = sqlite3_reset(pIdxSelect);
sqlite3_bind_null(pIdxSelect, 2);
-
- if( iPg<pSeg->pgnoFirst ){
- iPg = pSeg->pgnoFirst;
- bDlidx = 0;
- }
-
- pIter->iLeafPgno = iPg - 1;
- fts5SegIterNextPage(p, pIter);
-
- if( pIter->pLeaf ){
- fts5LeafSeek(p, bGe, pIter, pTerm, nTerm);
- }
-
- if( p->rc==SQLITE_OK && bGe==0 ){
- pIter->flags |= FTS5_SEGITER_ONETERM;
- if( pIter->pLeaf ){
- if( flags & FTS5INDEX_QUERY_DESC ){
- pIter->flags |= FTS5_SEGITER_REVERSE;
- }
- if( bDlidx ){
- fts5SegIterLoadDlidx(p, pIter);
- }
- if( flags & FTS5INDEX_QUERY_DESC ){
- fts5SegIterReverse(p, pIter);
- }
- }
- }
-
- fts5SegIterSetNext(p, pIter);
-
- /* Either:
- **
- ** 1) an error has occurred, or
- ** 2) the iterator points to EOF, or
- ** 3) the iterator points to an entry with term (pTerm/nTerm), or
- ** 4) the FTS5INDEX_QUERY_SCAN flag was set and the iterator points
- ** to an entry with a term greater than or equal to (pTerm/nTerm).
- */
+
+ if( iPg<pSeg->pgnoFirst ){
+ iPg = pSeg->pgnoFirst;
+ bDlidx = 0;
+ }
+
+ pIter->iLeafPgno = iPg - 1;
+ fts5SegIterNextPage(p, pIter);
+
+ if( pIter->pLeaf ){
+ fts5LeafSeek(p, bGe, pIter, pTerm, nTerm);
+ }
+
+ if( p->rc==SQLITE_OK && bGe==0 ){
+ pIter->flags |= FTS5_SEGITER_ONETERM;
+ if( pIter->pLeaf ){
+ if( flags & FTS5INDEX_QUERY_DESC ){
+ pIter->flags |= FTS5_SEGITER_REVERSE;
+ }
+ if( bDlidx ){
+ fts5SegIterLoadDlidx(p, pIter);
+ }
+ if( flags & FTS5INDEX_QUERY_DESC ){
+ fts5SegIterReverse(p, pIter);
+ }
+ }
+ }
+
+ fts5SegIterSetNext(p, pIter);
+
+ /* Either:
+ **
+ ** 1) an error has occurred, or
+ ** 2) the iterator points to EOF, or
+ ** 3) the iterator points to an entry with term (pTerm/nTerm), or
+ ** 4) the FTS5INDEX_QUERY_SCAN flag was set and the iterator points
+ ** to an entry with a term greater than or equal to (pTerm/nTerm).
+ */
assert_nc( p->rc!=SQLITE_OK /* 1 */
- || pIter->pLeaf==0 /* 2 */
- || fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)==0 /* 3 */
- || (bGe && fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)>0) /* 4 */
- );
-}
-
-/*
-** Initialize the object pIter to point to term pTerm/nTerm within the
+ || pIter->pLeaf==0 /* 2 */
+ || fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)==0 /* 3 */
+ || (bGe && fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)>0) /* 4 */
+ );
+}
+
+/*
+** Initialize the object pIter to point to term pTerm/nTerm within the
** in-memory hash table. If there is no such term in the hash-table, the
-** iterator is set to EOF.
-**
+** iterator is set to EOF.
+**
** If an error occurs, Fts5Index.rc is set to an appropriate error code. If
-** an error has already occurred when this function is called, it is a no-op.
-*/
-static void fts5SegIterHashInit(
- Fts5Index *p, /* FTS5 backend */
- const u8 *pTerm, int nTerm, /* Term to seek to */
- int flags, /* Mask of FTS5INDEX_XXX flags */
- Fts5SegIter *pIter /* Object to populate */
-){
- int nList = 0;
- const u8 *z = 0;
- int n = 0;
+** an error has already occurred when this function is called, it is a no-op.
+*/
+static void fts5SegIterHashInit(
+ Fts5Index *p, /* FTS5 backend */
+ const u8 *pTerm, int nTerm, /* Term to seek to */
+ int flags, /* Mask of FTS5INDEX_XXX flags */
+ Fts5SegIter *pIter /* Object to populate */
+){
+ int nList = 0;
+ const u8 *z = 0;
+ int n = 0;
Fts5Data *pLeaf = 0;
-
- assert( p->pHash );
- assert( p->rc==SQLITE_OK );
-
- if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){
+
+ assert( p->pHash );
+ assert( p->rc==SQLITE_OK );
+
+ if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){
const u8 *pList = 0;
- p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm);
- sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList);
- n = (z ? (int)strlen((const char*)z) : 0);
+ p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm);
+ sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList);
+ n = (z ? (int)strlen((const char*)z) : 0);
if( pList ){
pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
if( pLeaf ){
pLeaf->p = (u8*)pList;
}
}
- }else{
+ }else{
p->rc = sqlite3Fts5HashQuery(p->pHash, sizeof(Fts5Data),
(const char*)pTerm, nTerm, (void**)&pLeaf, &nList
);
if( pLeaf ){
pLeaf->p = (u8*)&pLeaf[1];
}
- z = pTerm;
- n = nTerm;
+ z = pTerm;
+ n = nTerm;
pIter->flags |= FTS5_SEGITER_ONETERM;
- }
-
+ }
+
if( pLeaf ){
- sqlite3Fts5BufferSet(&p->rc, &pIter->term, n, z);
- pLeaf->nn = pLeaf->szLeaf = nList;
- pIter->pLeaf = pLeaf;
- pIter->iLeafOffset = fts5GetVarint(pLeaf->p, (u64*)&pIter->iRowid);
- pIter->iEndofDoclist = pLeaf->nn;
-
- if( flags & FTS5INDEX_QUERY_DESC ){
- pIter->flags |= FTS5_SEGITER_REVERSE;
- fts5SegIterReverseInitPage(p, pIter);
- }else{
- fts5SegIterLoadNPos(p, pIter);
- }
- }
-
- fts5SegIterSetNext(p, pIter);
-}
-
-/*
-** Zero the iterator passed as the only argument.
-*/
-static void fts5SegIterClear(Fts5SegIter *pIter){
- fts5BufferFree(&pIter->term);
- fts5DataRelease(pIter->pLeaf);
- fts5DataRelease(pIter->pNextLeaf);
- fts5DlidxIterFree(pIter->pDlidx);
- sqlite3_free(pIter->aRowidOffset);
- memset(pIter, 0, sizeof(Fts5SegIter));
-}
-
-#ifdef SQLITE_DEBUG
-
-/*
-** This function is used as part of the big assert() procedure implemented by
-** fts5AssertMultiIterSetup(). It ensures that the result currently stored
-** in *pRes is the correct result of comparing the current positions of the
-** two iterators.
-*/
-static void fts5AssertComparisonResult(
+ sqlite3Fts5BufferSet(&p->rc, &pIter->term, n, z);
+ pLeaf->nn = pLeaf->szLeaf = nList;
+ pIter->pLeaf = pLeaf;
+ pIter->iLeafOffset = fts5GetVarint(pLeaf->p, (u64*)&pIter->iRowid);
+ pIter->iEndofDoclist = pLeaf->nn;
+
+ if( flags & FTS5INDEX_QUERY_DESC ){
+ pIter->flags |= FTS5_SEGITER_REVERSE;
+ fts5SegIterReverseInitPage(p, pIter);
+ }else{
+ fts5SegIterLoadNPos(p, pIter);
+ }
+ }
+
+ fts5SegIterSetNext(p, pIter);
+}
+
+/*
+** Zero the iterator passed as the only argument.
+*/
+static void fts5SegIterClear(Fts5SegIter *pIter){
+ fts5BufferFree(&pIter->term);
+ fts5DataRelease(pIter->pLeaf);
+ fts5DataRelease(pIter->pNextLeaf);
+ fts5DlidxIterFree(pIter->pDlidx);
+ sqlite3_free(pIter->aRowidOffset);
+ memset(pIter, 0, sizeof(Fts5SegIter));
+}
+
+#ifdef SQLITE_DEBUG
+
+/*
+** This function is used as part of the big assert() procedure implemented by
+** fts5AssertMultiIterSetup(). It ensures that the result currently stored
+** in *pRes is the correct result of comparing the current positions of the
+** two iterators.
+*/
+static void fts5AssertComparisonResult(
Fts5Iter *pIter,
- Fts5SegIter *p1,
- Fts5SegIter *p2,
- Fts5CResult *pRes
-){
- int i1 = p1 - pIter->aSeg;
- int i2 = p2 - pIter->aSeg;
-
- if( p1->pLeaf || p2->pLeaf ){
- if( p1->pLeaf==0 ){
- assert( pRes->iFirst==i2 );
- }else if( p2->pLeaf==0 ){
- assert( pRes->iFirst==i1 );
- }else{
- int nMin = MIN(p1->term.n, p2->term.n);
+ Fts5SegIter *p1,
+ Fts5SegIter *p2,
+ Fts5CResult *pRes
+){
+ int i1 = p1 - pIter->aSeg;
+ int i2 = p2 - pIter->aSeg;
+
+ if( p1->pLeaf || p2->pLeaf ){
+ if( p1->pLeaf==0 ){
+ assert( pRes->iFirst==i2 );
+ }else if( p2->pLeaf==0 ){
+ assert( pRes->iFirst==i1 );
+ }else{
+ int nMin = MIN(p1->term.n, p2->term.n);
int res = fts5Memcmp(p1->term.p, p2->term.p, nMin);
- if( res==0 ) res = p1->term.n - p2->term.n;
-
- if( res==0 ){
- assert( pRes->bTermEq==1 );
- assert( p1->iRowid!=p2->iRowid );
- res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : 1;
- }else{
- assert( pRes->bTermEq==0 );
- }
-
- if( res<0 ){
- assert( pRes->iFirst==i1 );
- }else{
- assert( pRes->iFirst==i2 );
- }
- }
- }
-}
-
-/*
-** This function is a no-op unless SQLITE_DEBUG is defined when this module
+ if( res==0 ) res = p1->term.n - p2->term.n;
+
+ if( res==0 ){
+ assert( pRes->bTermEq==1 );
+ assert( p1->iRowid!=p2->iRowid );
+ res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : 1;
+ }else{
+ assert( pRes->bTermEq==0 );
+ }
+
+ if( res<0 ){
+ assert( pRes->iFirst==i1 );
+ }else{
+ assert( pRes->iFirst==i2 );
+ }
+ }
+ }
+}
+
+/*
+** This function is a no-op unless SQLITE_DEBUG is defined when this module
** is compiled. In that case, this function is essentially an assert()
-** statement used to verify that the contents of the pIter->aFirst[] array
-** are correct.
-*/
-static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5Iter *pIter){
- if( p->rc==SQLITE_OK ){
- Fts5SegIter *pFirst = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
- int i;
-
- assert( (pFirst->pLeaf==0)==pIter->base.bEof );
-
- /* Check that pIter->iSwitchRowid is set correctly. */
- for(i=0; i<pIter->nSeg; i++){
- Fts5SegIter *p1 = &pIter->aSeg[i];
+** statement used to verify that the contents of the pIter->aFirst[] array
+** are correct.
+*/
+static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5Iter *pIter){
+ if( p->rc==SQLITE_OK ){
+ Fts5SegIter *pFirst = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ int i;
+
+ assert( (pFirst->pLeaf==0)==pIter->base.bEof );
+
+ /* Check that pIter->iSwitchRowid is set correctly. */
+ for(i=0; i<pIter->nSeg; i++){
+ Fts5SegIter *p1 = &pIter->aSeg[i];
assert( p1==pFirst
|| p1->pLeaf==0
|| fts5BufferCompare(&pFirst->term, &p1->term)
- || p1->iRowid==pIter->iSwitchRowid
- || (p1->iRowid<pIter->iSwitchRowid)==pIter->bRev
- );
- }
-
- for(i=0; i<pIter->nSeg; i+=2){
- Fts5SegIter *p1 = &pIter->aSeg[i];
- Fts5SegIter *p2 = &pIter->aSeg[i+1];
- Fts5CResult *pRes = &pIter->aFirst[(pIter->nSeg + i) / 2];
- fts5AssertComparisonResult(pIter, p1, p2, pRes);
- }
-
- for(i=1; i<(pIter->nSeg / 2); i+=2){
- Fts5SegIter *p1 = &pIter->aSeg[ pIter->aFirst[i*2].iFirst ];
- Fts5SegIter *p2 = &pIter->aSeg[ pIter->aFirst[i*2+1].iFirst ];
- Fts5CResult *pRes = &pIter->aFirst[i];
- fts5AssertComparisonResult(pIter, p1, p2, pRes);
- }
- }
-}
-#else
-# define fts5AssertMultiIterSetup(x,y)
-#endif
-
-/*
-** Do the comparison necessary to populate pIter->aFirst[iOut].
-**
-** If the returned value is non-zero, then it is the index of an entry
-** in the pIter->aSeg[] array that is (a) not at EOF, and (b) pointing
+ || p1->iRowid==pIter->iSwitchRowid
+ || (p1->iRowid<pIter->iSwitchRowid)==pIter->bRev
+ );
+ }
+
+ for(i=0; i<pIter->nSeg; i+=2){
+ Fts5SegIter *p1 = &pIter->aSeg[i];
+ Fts5SegIter *p2 = &pIter->aSeg[i+1];
+ Fts5CResult *pRes = &pIter->aFirst[(pIter->nSeg + i) / 2];
+ fts5AssertComparisonResult(pIter, p1, p2, pRes);
+ }
+
+ for(i=1; i<(pIter->nSeg / 2); i+=2){
+ Fts5SegIter *p1 = &pIter->aSeg[ pIter->aFirst[i*2].iFirst ];
+ Fts5SegIter *p2 = &pIter->aSeg[ pIter->aFirst[i*2+1].iFirst ];
+ Fts5CResult *pRes = &pIter->aFirst[i];
+ fts5AssertComparisonResult(pIter, p1, p2, pRes);
+ }
+ }
+}
+#else
+# define fts5AssertMultiIterSetup(x,y)
+#endif
+
+/*
+** Do the comparison necessary to populate pIter->aFirst[iOut].
+**
+** If the returned value is non-zero, then it is the index of an entry
+** in the pIter->aSeg[] array that is (a) not at EOF, and (b) pointing
** to a key that is a duplicate of another, higher priority,
-** segment-iterator in the pSeg->aSeg[] array.
-*/
-static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){
- int i1; /* Index of left-hand Fts5SegIter */
- int i2; /* Index of right-hand Fts5SegIter */
- int iRes;
- Fts5SegIter *p1; /* Left-hand Fts5SegIter */
- Fts5SegIter *p2; /* Right-hand Fts5SegIter */
- Fts5CResult *pRes = &pIter->aFirst[iOut];
-
- assert( iOut<pIter->nSeg && iOut>0 );
- assert( pIter->bRev==0 || pIter->bRev==1 );
-
- if( iOut>=(pIter->nSeg/2) ){
- i1 = (iOut - pIter->nSeg/2) * 2;
- i2 = i1 + 1;
- }else{
- i1 = pIter->aFirst[iOut*2].iFirst;
- i2 = pIter->aFirst[iOut*2+1].iFirst;
- }
- p1 = &pIter->aSeg[i1];
- p2 = &pIter->aSeg[i2];
-
- pRes->bTermEq = 0;
- if( p1->pLeaf==0 ){ /* If p1 is at EOF */
- iRes = i2;
- }else if( p2->pLeaf==0 ){ /* If p2 is at EOF */
- iRes = i1;
- }else{
- int res = fts5BufferCompare(&p1->term, &p2->term);
- if( res==0 ){
+** segment-iterator in the pSeg->aSeg[] array.
+*/
+static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){
+ int i1; /* Index of left-hand Fts5SegIter */
+ int i2; /* Index of right-hand Fts5SegIter */
+ int iRes;
+ Fts5SegIter *p1; /* Left-hand Fts5SegIter */
+ Fts5SegIter *p2; /* Right-hand Fts5SegIter */
+ Fts5CResult *pRes = &pIter->aFirst[iOut];
+
+ assert( iOut<pIter->nSeg && iOut>0 );
+ assert( pIter->bRev==0 || pIter->bRev==1 );
+
+ if( iOut>=(pIter->nSeg/2) ){
+ i1 = (iOut - pIter->nSeg/2) * 2;
+ i2 = i1 + 1;
+ }else{
+ i1 = pIter->aFirst[iOut*2].iFirst;
+ i2 = pIter->aFirst[iOut*2+1].iFirst;
+ }
+ p1 = &pIter->aSeg[i1];
+ p2 = &pIter->aSeg[i2];
+
+ pRes->bTermEq = 0;
+ if( p1->pLeaf==0 ){ /* If p1 is at EOF */
+ iRes = i2;
+ }else if( p2->pLeaf==0 ){ /* If p2 is at EOF */
+ iRes = i1;
+ }else{
+ int res = fts5BufferCompare(&p1->term, &p2->term);
+ if( res==0 ){
assert_nc( i2>i1 );
assert_nc( i2!=0 );
- pRes->bTermEq = 1;
- if( p1->iRowid==p2->iRowid ){
- p1->bDel = p2->bDel;
- return i2;
- }
- res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : +1;
- }
- assert( res!=0 );
- if( res<0 ){
- iRes = i1;
- }else{
- iRes = i2;
- }
- }
-
- pRes->iFirst = (u16)iRes;
- return 0;
-}
-
-/*
-** Move the seg-iter so that it points to the first rowid on page iLeafPgno.
-** It is an error if leaf iLeafPgno does not exist or contains no rowids.
-*/
-static void fts5SegIterGotoPage(
- Fts5Index *p, /* FTS5 backend object */
- Fts5SegIter *pIter, /* Iterator to advance */
- int iLeafPgno
-){
- assert( iLeafPgno>pIter->iLeafPgno );
-
- if( iLeafPgno>pIter->pSeg->pgnoLast ){
- p->rc = FTS5_CORRUPT;
- }else{
- fts5DataRelease(pIter->pNextLeaf);
- pIter->pNextLeaf = 0;
- pIter->iLeafPgno = iLeafPgno-1;
- fts5SegIterNextPage(p, pIter);
- assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno );
-
+ pRes->bTermEq = 1;
+ if( p1->iRowid==p2->iRowid ){
+ p1->bDel = p2->bDel;
+ return i2;
+ }
+ res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : +1;
+ }
+ assert( res!=0 );
+ if( res<0 ){
+ iRes = i1;
+ }else{
+ iRes = i2;
+ }
+ }
+
+ pRes->iFirst = (u16)iRes;
+ return 0;
+}
+
+/*
+** Move the seg-iter so that it points to the first rowid on page iLeafPgno.
+** It is an error if leaf iLeafPgno does not exist or contains no rowids.
+*/
+static void fts5SegIterGotoPage(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegIter *pIter, /* Iterator to advance */
+ int iLeafPgno
+){
+ assert( iLeafPgno>pIter->iLeafPgno );
+
+ if( iLeafPgno>pIter->pSeg->pgnoLast ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ fts5DataRelease(pIter->pNextLeaf);
+ pIter->pNextLeaf = 0;
+ pIter->iLeafPgno = iLeafPgno-1;
+ fts5SegIterNextPage(p, pIter);
+ assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno );
+
if( p->rc==SQLITE_OK && ALWAYS(pIter->pLeaf!=0) ){
- int iOff;
- u8 *a = pIter->pLeaf->p;
- int n = pIter->pLeaf->szLeaf;
-
- iOff = fts5LeafFirstRowidOff(pIter->pLeaf);
- if( iOff<4 || iOff>=n ){
- p->rc = FTS5_CORRUPT;
- }else{
- iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
- pIter->iLeafOffset = iOff;
- fts5SegIterLoadNPos(p, pIter);
- }
- }
- }
-}
-
-/*
+ int iOff;
+ u8 *a = pIter->pLeaf->p;
+ int n = pIter->pLeaf->szLeaf;
+
+ iOff = fts5LeafFirstRowidOff(pIter->pLeaf);
+ if( iOff<4 || iOff>=n ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
+ pIter->iLeafOffset = iOff;
+ fts5SegIterLoadNPos(p, pIter);
+ }
+ }
+ }
+}
+
+/*
** Advance the iterator passed as the second argument until it is at or
-** past rowid iFrom. Regardless of the value of iFrom, the iterator is
-** always advanced at least once.
-*/
-static void fts5SegIterNextFrom(
- Fts5Index *p, /* FTS5 backend object */
- Fts5SegIter *pIter, /* Iterator to advance */
- i64 iMatch /* Advance iterator at least this far */
-){
- int bRev = (pIter->flags & FTS5_SEGITER_REVERSE);
- Fts5DlidxIter *pDlidx = pIter->pDlidx;
- int iLeafPgno = pIter->iLeafPgno;
- int bMove = 1;
-
- assert( pIter->flags & FTS5_SEGITER_ONETERM );
- assert( pIter->pDlidx );
- assert( pIter->pLeaf );
-
- if( bRev==0 ){
- while( !fts5DlidxIterEof(p, pDlidx) && iMatch>fts5DlidxIterRowid(pDlidx) ){
- iLeafPgno = fts5DlidxIterPgno(pDlidx);
- fts5DlidxIterNext(p, pDlidx);
- }
- assert_nc( iLeafPgno>=pIter->iLeafPgno || p->rc );
- if( iLeafPgno>pIter->iLeafPgno ){
- fts5SegIterGotoPage(p, pIter, iLeafPgno);
- bMove = 0;
- }
- }else{
- assert( pIter->pNextLeaf==0 );
- assert( iMatch<pIter->iRowid );
- while( !fts5DlidxIterEof(p, pDlidx) && iMatch<fts5DlidxIterRowid(pDlidx) ){
- fts5DlidxIterPrev(p, pDlidx);
- }
- iLeafPgno = fts5DlidxIterPgno(pDlidx);
-
- assert( fts5DlidxIterEof(p, pDlidx) || iLeafPgno<=pIter->iLeafPgno );
-
- if( iLeafPgno<pIter->iLeafPgno ){
- pIter->iLeafPgno = iLeafPgno+1;
- fts5SegIterReverseNewPage(p, pIter);
- bMove = 0;
- }
- }
-
- do{
- if( bMove && p->rc==SQLITE_OK ) pIter->xNext(p, pIter, 0);
- if( pIter->pLeaf==0 ) break;
- if( bRev==0 && pIter->iRowid>=iMatch ) break;
- if( bRev!=0 && pIter->iRowid<=iMatch ) break;
- bMove = 1;
- }while( p->rc==SQLITE_OK );
-}
-
-
-/*
-** Free the iterator object passed as the second argument.
-*/
-static void fts5MultiIterFree(Fts5Iter *pIter){
- if( pIter ){
- int i;
- for(i=0; i<pIter->nSeg; i++){
- fts5SegIterClear(&pIter->aSeg[i]);
- }
- fts5BufferFree(&pIter->poslist);
- sqlite3_free(pIter);
- }
-}
-
-static void fts5MultiIterAdvanced(
- Fts5Index *p, /* FTS5 backend to iterate within */
- Fts5Iter *pIter, /* Iterator to update aFirst[] array for */
- int iChanged, /* Index of sub-iterator just advanced */
- int iMinset /* Minimum entry in aFirst[] to set */
-){
- int i;
- for(i=(pIter->nSeg+iChanged)/2; i>=iMinset && p->rc==SQLITE_OK; i=i/2){
- int iEq;
- if( (iEq = fts5MultiIterDoCompare(pIter, i)) ){
- Fts5SegIter *pSeg = &pIter->aSeg[iEq];
- assert( p->rc==SQLITE_OK );
- pSeg->xNext(p, pSeg, 0);
- i = pIter->nSeg + iEq;
- }
- }
-}
-
-/*
-** Sub-iterator iChanged of iterator pIter has just been advanced. It still
-** points to the same term though - just a different rowid. This function
-** attempts to update the contents of the pIter->aFirst[] accordingly.
-** If it does so successfully, 0 is returned. Otherwise 1.
-**
-** If non-zero is returned, the caller should call fts5MultiIterAdvanced()
-** on the iterator instead. That function does the same as this one, except
-** that it deals with more complicated cases as well.
-*/
-static int fts5MultiIterAdvanceRowid(
- Fts5Iter *pIter, /* Iterator to update aFirst[] array for */
- int iChanged, /* Index of sub-iterator just advanced */
- Fts5SegIter **ppFirst
-){
- Fts5SegIter *pNew = &pIter->aSeg[iChanged];
-
- if( pNew->iRowid==pIter->iSwitchRowid
- || (pNew->iRowid<pIter->iSwitchRowid)==pIter->bRev
- ){
- int i;
- Fts5SegIter *pOther = &pIter->aSeg[iChanged ^ 0x0001];
- pIter->iSwitchRowid = pIter->bRev ? SMALLEST_INT64 : LARGEST_INT64;
- for(i=(pIter->nSeg+iChanged)/2; 1; i=i/2){
- Fts5CResult *pRes = &pIter->aFirst[i];
-
- assert( pNew->pLeaf );
- assert( pRes->bTermEq==0 || pOther->pLeaf );
-
- if( pRes->bTermEq ){
- if( pNew->iRowid==pOther->iRowid ){
- return 1;
- }else if( (pOther->iRowid>pNew->iRowid)==pIter->bRev ){
- pIter->iSwitchRowid = pOther->iRowid;
- pNew = pOther;
- }else if( (pOther->iRowid>pIter->iSwitchRowid)==pIter->bRev ){
- pIter->iSwitchRowid = pOther->iRowid;
- }
- }
- pRes->iFirst = (u16)(pNew - pIter->aSeg);
- if( i==1 ) break;
-
- pOther = &pIter->aSeg[ pIter->aFirst[i ^ 0x0001].iFirst ];
- }
- }
-
- *ppFirst = pNew;
- return 0;
-}
-
-/*
-** Set the pIter->bEof variable based on the state of the sub-iterators.
-*/
-static void fts5MultiIterSetEof(Fts5Iter *pIter){
- Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
- pIter->base.bEof = pSeg->pLeaf==0;
- pIter->iSwitchRowid = pSeg->iRowid;
-}
-
-/*
+** past rowid iFrom. Regardless of the value of iFrom, the iterator is
+** always advanced at least once.
+*/
+static void fts5SegIterNextFrom(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegIter *pIter, /* Iterator to advance */
+ i64 iMatch /* Advance iterator at least this far */
+){
+ int bRev = (pIter->flags & FTS5_SEGITER_REVERSE);
+ Fts5DlidxIter *pDlidx = pIter->pDlidx;
+ int iLeafPgno = pIter->iLeafPgno;
+ int bMove = 1;
+
+ assert( pIter->flags & FTS5_SEGITER_ONETERM );
+ assert( pIter->pDlidx );
+ assert( pIter->pLeaf );
+
+ if( bRev==0 ){
+ while( !fts5DlidxIterEof(p, pDlidx) && iMatch>fts5DlidxIterRowid(pDlidx) ){
+ iLeafPgno = fts5DlidxIterPgno(pDlidx);
+ fts5DlidxIterNext(p, pDlidx);
+ }
+ assert_nc( iLeafPgno>=pIter->iLeafPgno || p->rc );
+ if( iLeafPgno>pIter->iLeafPgno ){
+ fts5SegIterGotoPage(p, pIter, iLeafPgno);
+ bMove = 0;
+ }
+ }else{
+ assert( pIter->pNextLeaf==0 );
+ assert( iMatch<pIter->iRowid );
+ while( !fts5DlidxIterEof(p, pDlidx) && iMatch<fts5DlidxIterRowid(pDlidx) ){
+ fts5DlidxIterPrev(p, pDlidx);
+ }
+ iLeafPgno = fts5DlidxIterPgno(pDlidx);
+
+ assert( fts5DlidxIterEof(p, pDlidx) || iLeafPgno<=pIter->iLeafPgno );
+
+ if( iLeafPgno<pIter->iLeafPgno ){
+ pIter->iLeafPgno = iLeafPgno+1;
+ fts5SegIterReverseNewPage(p, pIter);
+ bMove = 0;
+ }
+ }
+
+ do{
+ if( bMove && p->rc==SQLITE_OK ) pIter->xNext(p, pIter, 0);
+ if( pIter->pLeaf==0 ) break;
+ if( bRev==0 && pIter->iRowid>=iMatch ) break;
+ if( bRev!=0 && pIter->iRowid<=iMatch ) break;
+ bMove = 1;
+ }while( p->rc==SQLITE_OK );
+}
+
+
+/*
+** Free the iterator object passed as the second argument.
+*/
+static void fts5MultiIterFree(Fts5Iter *pIter){
+ if( pIter ){
+ int i;
+ for(i=0; i<pIter->nSeg; i++){
+ fts5SegIterClear(&pIter->aSeg[i]);
+ }
+ fts5BufferFree(&pIter->poslist);
+ sqlite3_free(pIter);
+ }
+}
+
+static void fts5MultiIterAdvanced(
+ Fts5Index *p, /* FTS5 backend to iterate within */
+ Fts5Iter *pIter, /* Iterator to update aFirst[] array for */
+ int iChanged, /* Index of sub-iterator just advanced */
+ int iMinset /* Minimum entry in aFirst[] to set */
+){
+ int i;
+ for(i=(pIter->nSeg+iChanged)/2; i>=iMinset && p->rc==SQLITE_OK; i=i/2){
+ int iEq;
+ if( (iEq = fts5MultiIterDoCompare(pIter, i)) ){
+ Fts5SegIter *pSeg = &pIter->aSeg[iEq];
+ assert( p->rc==SQLITE_OK );
+ pSeg->xNext(p, pSeg, 0);
+ i = pIter->nSeg + iEq;
+ }
+ }
+}
+
+/*
+** Sub-iterator iChanged of iterator pIter has just been advanced. It still
+** points to the same term though - just a different rowid. This function
+** attempts to update the contents of the pIter->aFirst[] accordingly.
+** If it does so successfully, 0 is returned. Otherwise 1.
+**
+** If non-zero is returned, the caller should call fts5MultiIterAdvanced()
+** on the iterator instead. That function does the same as this one, except
+** that it deals with more complicated cases as well.
+*/
+static int fts5MultiIterAdvanceRowid(
+ Fts5Iter *pIter, /* Iterator to update aFirst[] array for */
+ int iChanged, /* Index of sub-iterator just advanced */
+ Fts5SegIter **ppFirst
+){
+ Fts5SegIter *pNew = &pIter->aSeg[iChanged];
+
+ if( pNew->iRowid==pIter->iSwitchRowid
+ || (pNew->iRowid<pIter->iSwitchRowid)==pIter->bRev
+ ){
+ int i;
+ Fts5SegIter *pOther = &pIter->aSeg[iChanged ^ 0x0001];
+ pIter->iSwitchRowid = pIter->bRev ? SMALLEST_INT64 : LARGEST_INT64;
+ for(i=(pIter->nSeg+iChanged)/2; 1; i=i/2){
+ Fts5CResult *pRes = &pIter->aFirst[i];
+
+ assert( pNew->pLeaf );
+ assert( pRes->bTermEq==0 || pOther->pLeaf );
+
+ if( pRes->bTermEq ){
+ if( pNew->iRowid==pOther->iRowid ){
+ return 1;
+ }else if( (pOther->iRowid>pNew->iRowid)==pIter->bRev ){
+ pIter->iSwitchRowid = pOther->iRowid;
+ pNew = pOther;
+ }else if( (pOther->iRowid>pIter->iSwitchRowid)==pIter->bRev ){
+ pIter->iSwitchRowid = pOther->iRowid;
+ }
+ }
+ pRes->iFirst = (u16)(pNew - pIter->aSeg);
+ if( i==1 ) break;
+
+ pOther = &pIter->aSeg[ pIter->aFirst[i ^ 0x0001].iFirst ];
+ }
+ }
+
+ *ppFirst = pNew;
+ return 0;
+}
+
+/*
+** Set the pIter->bEof variable based on the state of the sub-iterators.
+*/
+static void fts5MultiIterSetEof(Fts5Iter *pIter){
+ Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ pIter->base.bEof = pSeg->pLeaf==0;
+ pIter->iSwitchRowid = pSeg->iRowid;
+}
+
+/*
** Move the iterator to the next entry.
-**
+**
** If an error occurs, an error code is left in Fts5Index.rc. It is not
** considered an error if the iterator reaches EOF, or if it is already at
-** EOF when this function is called.
-*/
-static void fts5MultiIterNext(
+** EOF when this function is called.
+*/
+static void fts5MultiIterNext(
Fts5Index *p,
- Fts5Iter *pIter,
- int bFrom, /* True if argument iFrom is valid */
- i64 iFrom /* Advance at least as far as this */
-){
- int bUseFrom = bFrom;
- assert( pIter->base.bEof==0 );
- while( p->rc==SQLITE_OK ){
- int iFirst = pIter->aFirst[1].iFirst;
- int bNewTerm = 0;
- Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
- assert( p->rc==SQLITE_OK );
- if( bUseFrom && pSeg->pDlidx ){
- fts5SegIterNextFrom(p, pSeg, iFrom);
- }else{
- pSeg->xNext(p, pSeg, &bNewTerm);
- }
-
+ Fts5Iter *pIter,
+ int bFrom, /* True if argument iFrom is valid */
+ i64 iFrom /* Advance at least as far as this */
+){
+ int bUseFrom = bFrom;
+ assert( pIter->base.bEof==0 );
+ while( p->rc==SQLITE_OK ){
+ int iFirst = pIter->aFirst[1].iFirst;
+ int bNewTerm = 0;
+ Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
+ assert( p->rc==SQLITE_OK );
+ if( bUseFrom && pSeg->pDlidx ){
+ fts5SegIterNextFrom(p, pSeg, iFrom);
+ }else{
+ pSeg->xNext(p, pSeg, &bNewTerm);
+ }
+
if( pSeg->pLeaf==0 || bNewTerm
- || fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg)
- ){
- fts5MultiIterAdvanced(p, pIter, iFirst, 1);
- fts5MultiIterSetEof(pIter);
- pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
- if( pSeg->pLeaf==0 ) return;
- }
-
- fts5AssertMultiIterSetup(p, pIter);
- assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf );
- if( pIter->bSkipEmpty==0 || pSeg->nPos ){
- pIter->xSetOutputs(pIter, pSeg);
- return;
- }
- bUseFrom = 0;
- }
-}
-
-static void fts5MultiIterNext2(
+ || fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg)
+ ){
+ fts5MultiIterAdvanced(p, pIter, iFirst, 1);
+ fts5MultiIterSetEof(pIter);
+ pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
+ if( pSeg->pLeaf==0 ) return;
+ }
+
+ fts5AssertMultiIterSetup(p, pIter);
+ assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf );
+ if( pIter->bSkipEmpty==0 || pSeg->nPos ){
+ pIter->xSetOutputs(pIter, pSeg);
+ return;
+ }
+ bUseFrom = 0;
+ }
+}
+
+static void fts5MultiIterNext2(
Fts5Index *p,
- Fts5Iter *pIter,
- int *pbNewTerm /* OUT: True if *might* be new term */
-){
- assert( pIter->bSkipEmpty );
- if( p->rc==SQLITE_OK ){
- *pbNewTerm = 0;
- do{
- int iFirst = pIter->aFirst[1].iFirst;
- Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
- int bNewTerm = 0;
-
- assert( p->rc==SQLITE_OK );
- pSeg->xNext(p, pSeg, &bNewTerm);
+ Fts5Iter *pIter,
+ int *pbNewTerm /* OUT: True if *might* be new term */
+){
+ assert( pIter->bSkipEmpty );
+ if( p->rc==SQLITE_OK ){
+ *pbNewTerm = 0;
+ do{
+ int iFirst = pIter->aFirst[1].iFirst;
+ Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
+ int bNewTerm = 0;
+
+ assert( p->rc==SQLITE_OK );
+ pSeg->xNext(p, pSeg, &bNewTerm);
if( pSeg->pLeaf==0 || bNewTerm
- || fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg)
- ){
- fts5MultiIterAdvanced(p, pIter, iFirst, 1);
- fts5MultiIterSetEof(pIter);
- *pbNewTerm = 1;
- }
- fts5AssertMultiIterSetup(p, pIter);
-
- }while( fts5MultiIterIsEmpty(p, pIter) );
- }
-}
-
-static void fts5IterSetOutputs_Noop(Fts5Iter *pUnused1, Fts5SegIter *pUnused2){
- UNUSED_PARAM2(pUnused1, pUnused2);
-}
-
-static Fts5Iter *fts5MultiIterAlloc(
- Fts5Index *p, /* FTS5 backend to iterate within */
- int nSeg
-){
- Fts5Iter *pNew;
- int nSlot; /* Power of two >= nSeg */
-
- for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2);
+ || fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg)
+ ){
+ fts5MultiIterAdvanced(p, pIter, iFirst, 1);
+ fts5MultiIterSetEof(pIter);
+ *pbNewTerm = 1;
+ }
+ fts5AssertMultiIterSetup(p, pIter);
+
+ }while( fts5MultiIterIsEmpty(p, pIter) );
+ }
+}
+
+static void fts5IterSetOutputs_Noop(Fts5Iter *pUnused1, Fts5SegIter *pUnused2){
+ UNUSED_PARAM2(pUnused1, pUnused2);
+}
+
+static Fts5Iter *fts5MultiIterAlloc(
+ Fts5Index *p, /* FTS5 backend to iterate within */
+ int nSeg
+){
+ Fts5Iter *pNew;
+ int nSlot; /* Power of two >= nSeg */
+
+ for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2);
pNew = fts5IdxMalloc(p,
- sizeof(Fts5Iter) + /* pNew */
- sizeof(Fts5SegIter) * (nSlot-1) + /* pNew->aSeg[] */
- sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */
- );
- if( pNew ){
- pNew->nSeg = nSlot;
- pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot];
- pNew->pIndex = p;
- pNew->xSetOutputs = fts5IterSetOutputs_Noop;
- }
- return pNew;
-}
-
-static void fts5PoslistCallback(
+ sizeof(Fts5Iter) + /* pNew */
+ sizeof(Fts5SegIter) * (nSlot-1) + /* pNew->aSeg[] */
+ sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */
+ );
+ if( pNew ){
+ pNew->nSeg = nSlot;
+ pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot];
+ pNew->pIndex = p;
+ pNew->xSetOutputs = fts5IterSetOutputs_Noop;
+ }
+ return pNew;
+}
+
+static void fts5PoslistCallback(
Fts5Index *pUnused,
void *pContext,
- const u8 *pChunk, int nChunk
-){
- UNUSED_PARAM(pUnused);
- assert_nc( nChunk>=0 );
- if( nChunk>0 ){
- fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk);
- }
-}
-
-typedef struct PoslistCallbackCtx PoslistCallbackCtx;
-struct PoslistCallbackCtx {
- Fts5Buffer *pBuf; /* Append to this buffer */
- Fts5Colset *pColset; /* Restrict matches to this column */
- int eState; /* See above */
-};
-
-typedef struct PoslistOffsetsCtx PoslistOffsetsCtx;
-struct PoslistOffsetsCtx {
- Fts5Buffer *pBuf; /* Append to this buffer */
- Fts5Colset *pColset; /* Restrict matches to this column */
- int iRead;
- int iWrite;
-};
-
-/*
-** TODO: Make this more efficient!
-*/
-static int fts5IndexColsetTest(Fts5Colset *pColset, int iCol){
- int i;
- for(i=0; i<pColset->nCol; i++){
- if( pColset->aiCol[i]==iCol ) return 1;
- }
- return 0;
-}
-
-static void fts5PoslistOffsetsCallback(
+ const u8 *pChunk, int nChunk
+){
+ UNUSED_PARAM(pUnused);
+ assert_nc( nChunk>=0 );
+ if( nChunk>0 ){
+ fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk);
+ }
+}
+
+typedef struct PoslistCallbackCtx PoslistCallbackCtx;
+struct PoslistCallbackCtx {
+ Fts5Buffer *pBuf; /* Append to this buffer */
+ Fts5Colset *pColset; /* Restrict matches to this column */
+ int eState; /* See above */
+};
+
+typedef struct PoslistOffsetsCtx PoslistOffsetsCtx;
+struct PoslistOffsetsCtx {
+ Fts5Buffer *pBuf; /* Append to this buffer */
+ Fts5Colset *pColset; /* Restrict matches to this column */
+ int iRead;
+ int iWrite;
+};
+
+/*
+** TODO: Make this more efficient!
+*/
+static int fts5IndexColsetTest(Fts5Colset *pColset, int iCol){
+ int i;
+ for(i=0; i<pColset->nCol; i++){
+ if( pColset->aiCol[i]==iCol ) return 1;
+ }
+ return 0;
+}
+
+static void fts5PoslistOffsetsCallback(
Fts5Index *pUnused,
void *pContext,
- const u8 *pChunk, int nChunk
-){
- PoslistOffsetsCtx *pCtx = (PoslistOffsetsCtx*)pContext;
- UNUSED_PARAM(pUnused);
- assert_nc( nChunk>=0 );
- if( nChunk>0 ){
- int i = 0;
- while( i<nChunk ){
- int iVal;
- i += fts5GetVarint32(&pChunk[i], iVal);
- iVal += pCtx->iRead - 2;
- pCtx->iRead = iVal;
- if( fts5IndexColsetTest(pCtx->pColset, iVal) ){
- fts5BufferSafeAppendVarint(pCtx->pBuf, iVal + 2 - pCtx->iWrite);
- pCtx->iWrite = iVal;
- }
- }
- }
-}
-
-static void fts5PoslistFilterCallback(
- Fts5Index *pUnused,
+ const u8 *pChunk, int nChunk
+){
+ PoslistOffsetsCtx *pCtx = (PoslistOffsetsCtx*)pContext;
+ UNUSED_PARAM(pUnused);
+ assert_nc( nChunk>=0 );
+ if( nChunk>0 ){
+ int i = 0;
+ while( i<nChunk ){
+ int iVal;
+ i += fts5GetVarint32(&pChunk[i], iVal);
+ iVal += pCtx->iRead - 2;
+ pCtx->iRead = iVal;
+ if( fts5IndexColsetTest(pCtx->pColset, iVal) ){
+ fts5BufferSafeAppendVarint(pCtx->pBuf, iVal + 2 - pCtx->iWrite);
+ pCtx->iWrite = iVal;
+ }
+ }
+ }
+}
+
+static void fts5PoslistFilterCallback(
+ Fts5Index *pUnused,
void *pContext,
- const u8 *pChunk, int nChunk
-){
- PoslistCallbackCtx *pCtx = (PoslistCallbackCtx*)pContext;
- UNUSED_PARAM(pUnused);
- assert_nc( nChunk>=0 );
- if( nChunk>0 ){
- /* Search through to find the first varint with value 1. This is the
- ** start of the next columns hits. */
- int i = 0;
- int iStart = 0;
-
- if( pCtx->eState==2 ){
- int iCol;
- fts5FastGetVarint32(pChunk, i, iCol);
- if( fts5IndexColsetTest(pCtx->pColset, iCol) ){
- pCtx->eState = 1;
- fts5BufferSafeAppendVarint(pCtx->pBuf, 1);
- }else{
- pCtx->eState = 0;
- }
- }
-
- do {
- while( i<nChunk && pChunk[i]!=0x01 ){
- while( pChunk[i] & 0x80 ) i++;
- i++;
- }
- if( pCtx->eState ){
- fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
- }
- if( i<nChunk ){
- int iCol;
- iStart = i;
- i++;
- if( i>=nChunk ){
- pCtx->eState = 2;
- }else{
- fts5FastGetVarint32(pChunk, i, iCol);
- pCtx->eState = fts5IndexColsetTest(pCtx->pColset, iCol);
- if( pCtx->eState ){
- fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
- iStart = i;
- }
- }
- }
- }while( i<nChunk );
- }
-}
-
-static void fts5ChunkIterate(
- Fts5Index *p, /* Index object */
- Fts5SegIter *pSeg, /* Poslist of this iterator */
- void *pCtx, /* Context pointer for xChunk callback */
- void (*xChunk)(Fts5Index*, void*, const u8*, int)
-){
- int nRem = pSeg->nPos; /* Number of bytes still to come */
- Fts5Data *pData = 0;
- u8 *pChunk = &pSeg->pLeaf->p[pSeg->iLeafOffset];
- int nChunk = MIN(nRem, pSeg->pLeaf->szLeaf - pSeg->iLeafOffset);
- int pgno = pSeg->iLeafPgno;
- int pgnoSave = 0;
-
+ const u8 *pChunk, int nChunk
+){
+ PoslistCallbackCtx *pCtx = (PoslistCallbackCtx*)pContext;
+ UNUSED_PARAM(pUnused);
+ assert_nc( nChunk>=0 );
+ if( nChunk>0 ){
+ /* Search through to find the first varint with value 1. This is the
+ ** start of the next columns hits. */
+ int i = 0;
+ int iStart = 0;
+
+ if( pCtx->eState==2 ){
+ int iCol;
+ fts5FastGetVarint32(pChunk, i, iCol);
+ if( fts5IndexColsetTest(pCtx->pColset, iCol) ){
+ pCtx->eState = 1;
+ fts5BufferSafeAppendVarint(pCtx->pBuf, 1);
+ }else{
+ pCtx->eState = 0;
+ }
+ }
+
+ do {
+ while( i<nChunk && pChunk[i]!=0x01 ){
+ while( pChunk[i] & 0x80 ) i++;
+ i++;
+ }
+ if( pCtx->eState ){
+ fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
+ }
+ if( i<nChunk ){
+ int iCol;
+ iStart = i;
+ i++;
+ if( i>=nChunk ){
+ pCtx->eState = 2;
+ }else{
+ fts5FastGetVarint32(pChunk, i, iCol);
+ pCtx->eState = fts5IndexColsetTest(pCtx->pColset, iCol);
+ if( pCtx->eState ){
+ fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
+ iStart = i;
+ }
+ }
+ }
+ }while( i<nChunk );
+ }
+}
+
+static void fts5ChunkIterate(
+ Fts5Index *p, /* Index object */
+ Fts5SegIter *pSeg, /* Poslist of this iterator */
+ void *pCtx, /* Context pointer for xChunk callback */
+ void (*xChunk)(Fts5Index*, void*, const u8*, int)
+){
+ int nRem = pSeg->nPos; /* Number of bytes still to come */
+ Fts5Data *pData = 0;
+ u8 *pChunk = &pSeg->pLeaf->p[pSeg->iLeafOffset];
+ int nChunk = MIN(nRem, pSeg->pLeaf->szLeaf - pSeg->iLeafOffset);
+ int pgno = pSeg->iLeafPgno;
+ int pgnoSave = 0;
+
/* This function does not work with detail=none databases. */
- assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE );
-
- if( (pSeg->flags & FTS5_SEGITER_REVERSE)==0 ){
- pgnoSave = pgno+1;
- }
-
- while( 1 ){
- xChunk(p, pCtx, pChunk, nChunk);
- nRem -= nChunk;
- fts5DataRelease(pData);
- if( nRem<=0 ){
- break;
+ assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE );
+
+ if( (pSeg->flags & FTS5_SEGITER_REVERSE)==0 ){
+ pgnoSave = pgno+1;
+ }
+
+ while( 1 ){
+ xChunk(p, pCtx, pChunk, nChunk);
+ nRem -= nChunk;
+ fts5DataRelease(pData);
+ if( nRem<=0 ){
+ break;
}else if( pSeg->pSeg==0 ){
p->rc = FTS5_CORRUPT;
return;
- }else{
- pgno++;
- pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno));
- if( pData==0 ) break;
- pChunk = &pData->p[4];
- nChunk = MIN(nRem, pData->szLeaf - 4);
- if( pgno==pgnoSave ){
- assert( pSeg->pNextLeaf==0 );
- pSeg->pNextLeaf = pData;
- pData = 0;
- }
- }
- }
-}
-
-/*
-** Iterator pIter currently points to a valid entry (not EOF). This
-** function appends the position list data for the current entry to
-** buffer pBuf. It does not make a copy of the position-list size
-** field.
-*/
-static void fts5SegiterPoslist(
- Fts5Index *p,
- Fts5SegIter *pSeg,
- Fts5Colset *pColset,
- Fts5Buffer *pBuf
-){
+ }else{
+ pgno++;
+ pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno));
+ if( pData==0 ) break;
+ pChunk = &pData->p[4];
+ nChunk = MIN(nRem, pData->szLeaf - 4);
+ if( pgno==pgnoSave ){
+ assert( pSeg->pNextLeaf==0 );
+ pSeg->pNextLeaf = pData;
+ pData = 0;
+ }
+ }
+ }
+}
+
+/*
+** Iterator pIter currently points to a valid entry (not EOF). This
+** function appends the position list data for the current entry to
+** buffer pBuf. It does not make a copy of the position-list size
+** field.
+*/
+static void fts5SegiterPoslist(
+ Fts5Index *p,
+ Fts5SegIter *pSeg,
+ Fts5Colset *pColset,
+ Fts5Buffer *pBuf
+){
assert( pBuf!=0 );
assert( pSeg!=0 );
if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+FTS5_DATA_ZERO_PADDING) ){
assert( pBuf->p!=0 );
assert( pBuf->nSpace >= pBuf->n+pSeg->nPos+FTS5_DATA_ZERO_PADDING );
memset(&pBuf->p[pBuf->n+pSeg->nPos], 0, FTS5_DATA_ZERO_PADDING);
- if( pColset==0 ){
- fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
- }else{
- if( p->pConfig->eDetail==FTS5_DETAIL_FULL ){
- PoslistCallbackCtx sCtx;
- sCtx.pBuf = pBuf;
- sCtx.pColset = pColset;
- sCtx.eState = fts5IndexColsetTest(pColset, 0);
- assert( sCtx.eState==0 || sCtx.eState==1 );
- fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback);
- }else{
- PoslistOffsetsCtx sCtx;
- memset(&sCtx, 0, sizeof(sCtx));
- sCtx.pBuf = pBuf;
- sCtx.pColset = pColset;
- fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistOffsetsCallback);
- }
- }
- }
-}
-
-/*
+ if( pColset==0 ){
+ fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
+ }else{
+ if( p->pConfig->eDetail==FTS5_DETAIL_FULL ){
+ PoslistCallbackCtx sCtx;
+ sCtx.pBuf = pBuf;
+ sCtx.pColset = pColset;
+ sCtx.eState = fts5IndexColsetTest(pColset, 0);
+ assert( sCtx.eState==0 || sCtx.eState==1 );
+ fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback);
+ }else{
+ PoslistOffsetsCtx sCtx;
+ memset(&sCtx, 0, sizeof(sCtx));
+ sCtx.pBuf = pBuf;
+ sCtx.pColset = pColset;
+ fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistOffsetsCallback);
+ }
+ }
+ }
+}
+
+/*
** Parameter pPos points to a buffer containing a position list, size nPos.
** This function filters it according to pColset (which must be non-NULL)
** and sets pIter->base.pData/nData to point to the new position list.
@@ -226148,14 +226148,14 @@ static void fts5SegiterPoslist(
** This function is a no-op if *pRc is other than SQLITE_OK when it is
** called. If an OOM error is encountered, *pRc is set to SQLITE_NOMEM
** before returning.
-*/
-static void fts5IndexExtractColset(
- int *pRc,
- Fts5Colset *pColset, /* Colset to filter on */
- const u8 *pPos, int nPos, /* Position list */
+*/
+static void fts5IndexExtractColset(
+ int *pRc,
+ Fts5Colset *pColset, /* Colset to filter on */
+ const u8 *pPos, int nPos, /* Position list */
Fts5Iter *pIter
-){
- if( *pRc==SQLITE_OK ){
+){
+ if( *pRc==SQLITE_OK ){
const u8 *p = pPos;
const u8 *aCopy = p;
const u8 *pEnd = &p[nPos]; /* One byte past end of position list */
@@ -226174,7 +226174,7 @@ static void fts5IndexExtractColset(
pIter->base.nData = pIter->poslist.n;
return;
}
- }
+ }
/* Advance pointer p until it points to pEnd or an 0x01 byte that is
** not part of a varint */
@@ -226201,971 +226201,971 @@ static void fts5IndexExtractColset(
p--;
p += fts5GetVarint32(p, iCurrent);
}
- }
- }
-
-}
-
-/*
-** xSetOutputs callback used by detail=none tables.
-*/
-static void fts5IterSetOutputs_None(Fts5Iter *pIter, Fts5SegIter *pSeg){
- assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_NONE );
- pIter->base.iRowid = pSeg->iRowid;
- pIter->base.nData = pSeg->nPos;
-}
-
-/*
-** xSetOutputs callback used by detail=full and detail=col tables when no
-** column filters are specified.
-*/
-static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){
- pIter->base.iRowid = pSeg->iRowid;
- pIter->base.nData = pSeg->nPos;
-
- assert( pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_NONE );
- assert( pIter->pColset==0 );
-
- if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
+ }
+ }
+
+}
+
+/*
+** xSetOutputs callback used by detail=none tables.
+*/
+static void fts5IterSetOutputs_None(Fts5Iter *pIter, Fts5SegIter *pSeg){
+ assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_NONE );
+ pIter->base.iRowid = pSeg->iRowid;
+ pIter->base.nData = pSeg->nPos;
+}
+
+/*
+** xSetOutputs callback used by detail=full and detail=col tables when no
+** column filters are specified.
+*/
+static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){
+ pIter->base.iRowid = pSeg->iRowid;
+ pIter->base.nData = pSeg->nPos;
+
+ assert( pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_NONE );
+ assert( pIter->pColset==0 );
+
+ if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
/* All data is stored on the current page. Populate the output
- ** variables to point into the body of the page object. */
- pIter->base.pData = &pSeg->pLeaf->p[pSeg->iLeafOffset];
- }else{
- /* The data is distributed over two or more pages. Copy it into the
- ** Fts5Iter.poslist buffer and then set the output pointer to point
- ** to this buffer. */
- fts5BufferZero(&pIter->poslist);
- fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist);
- pIter->base.pData = pIter->poslist.p;
- }
-}
-
-/*
-** xSetOutputs callback used when the Fts5Colset object has nCol==0 (match
-** against no columns at all).
-*/
-static void fts5IterSetOutputs_ZeroColset(Fts5Iter *pIter, Fts5SegIter *pSeg){
- UNUSED_PARAM(pSeg);
- pIter->base.nData = 0;
-}
-
-/*
-** xSetOutputs callback used by detail=col when there is a column filter
-** and there are 100 or more columns. Also called as a fallback from
-** fts5IterSetOutputs_Col100 if the column-list spans more than one page.
-*/
-static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){
- fts5BufferZero(&pIter->poslist);
- fts5SegiterPoslist(pIter->pIndex, pSeg, pIter->pColset, &pIter->poslist);
- pIter->base.iRowid = pSeg->iRowid;
- pIter->base.pData = pIter->poslist.p;
- pIter->base.nData = pIter->poslist.n;
-}
-
-/*
+ ** variables to point into the body of the page object. */
+ pIter->base.pData = &pSeg->pLeaf->p[pSeg->iLeafOffset];
+ }else{
+ /* The data is distributed over two or more pages. Copy it into the
+ ** Fts5Iter.poslist buffer and then set the output pointer to point
+ ** to this buffer. */
+ fts5BufferZero(&pIter->poslist);
+ fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist);
+ pIter->base.pData = pIter->poslist.p;
+ }
+}
+
+/*
+** xSetOutputs callback used when the Fts5Colset object has nCol==0 (match
+** against no columns at all).
+*/
+static void fts5IterSetOutputs_ZeroColset(Fts5Iter *pIter, Fts5SegIter *pSeg){
+ UNUSED_PARAM(pSeg);
+ pIter->base.nData = 0;
+}
+
+/*
+** xSetOutputs callback used by detail=col when there is a column filter
+** and there are 100 or more columns. Also called as a fallback from
+** fts5IterSetOutputs_Col100 if the column-list spans more than one page.
+*/
+static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){
+ fts5BufferZero(&pIter->poslist);
+ fts5SegiterPoslist(pIter->pIndex, pSeg, pIter->pColset, &pIter->poslist);
+ pIter->base.iRowid = pSeg->iRowid;
+ pIter->base.pData = pIter->poslist.p;
+ pIter->base.nData = pIter->poslist.n;
+}
+
+/*
** xSetOutputs callback used when:
-**
-** * detail=col,
-** * there is a column filter, and
+**
+** * detail=col,
+** * there is a column filter, and
** * the table contains 100 or fewer columns.
-**
+**
** The last point is to ensure all column numbers are stored as
-** single-byte varints.
-*/
-static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){
-
- assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
- assert( pIter->pColset );
-
- if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){
- fts5IterSetOutputs_Col(pIter, pSeg);
- }else{
- u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset];
+** single-byte varints.
+*/
+static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){
+
+ assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
+ assert( pIter->pColset );
+
+ if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){
+ fts5IterSetOutputs_Col(pIter, pSeg);
+ }else{
+ u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset];
u8 *pEnd = (u8*)&a[pSeg->nPos];
- int iPrev = 0;
- int *aiCol = pIter->pColset->aiCol;
- int *aiColEnd = &aiCol[pIter->pColset->nCol];
-
- u8 *aOut = pIter->poslist.p;
- int iPrevOut = 0;
-
- pIter->base.iRowid = pSeg->iRowid;
-
- while( a<pEnd ){
- iPrev += (int)a++[0] - 2;
- while( *aiCol<iPrev ){
- aiCol++;
- if( aiCol==aiColEnd ) goto setoutputs_col_out;
- }
- if( *aiCol==iPrev ){
- *aOut++ = (u8)((iPrev - iPrevOut) + 2);
- iPrevOut = iPrev;
- }
- }
-
-setoutputs_col_out:
- pIter->base.pData = pIter->poslist.p;
- pIter->base.nData = aOut - pIter->poslist.p;
- }
-}
-
-/*
-** xSetOutputs callback used by detail=full when there is a column filter.
-*/
-static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){
- Fts5Colset *pColset = pIter->pColset;
- pIter->base.iRowid = pSeg->iRowid;
-
- assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_FULL );
- assert( pColset );
-
- if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
+ int iPrev = 0;
+ int *aiCol = pIter->pColset->aiCol;
+ int *aiColEnd = &aiCol[pIter->pColset->nCol];
+
+ u8 *aOut = pIter->poslist.p;
+ int iPrevOut = 0;
+
+ pIter->base.iRowid = pSeg->iRowid;
+
+ while( a<pEnd ){
+ iPrev += (int)a++[0] - 2;
+ while( *aiCol<iPrev ){
+ aiCol++;
+ if( aiCol==aiColEnd ) goto setoutputs_col_out;
+ }
+ if( *aiCol==iPrev ){
+ *aOut++ = (u8)((iPrev - iPrevOut) + 2);
+ iPrevOut = iPrev;
+ }
+ }
+
+setoutputs_col_out:
+ pIter->base.pData = pIter->poslist.p;
+ pIter->base.nData = aOut - pIter->poslist.p;
+ }
+}
+
+/*
+** xSetOutputs callback used by detail=full when there is a column filter.
+*/
+static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){
+ Fts5Colset *pColset = pIter->pColset;
+ pIter->base.iRowid = pSeg->iRowid;
+
+ assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_FULL );
+ assert( pColset );
+
+ if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
/* All data is stored on the current page. Populate the output
- ** variables to point into the body of the page object. */
- const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset];
+ ** variables to point into the body of the page object. */
+ const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset];
int *pRc = &pIter->pIndex->rc;
fts5BufferZero(&pIter->poslist);
fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, pIter);
- }else{
- /* The data is distributed over two or more pages. Copy it into the
- ** Fts5Iter.poslist buffer and then set the output pointer to point
- ** to this buffer. */
- fts5BufferZero(&pIter->poslist);
- fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
- pIter->base.pData = pIter->poslist.p;
- pIter->base.nData = pIter->poslist.n;
- }
-}
-
-static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){
+ }else{
+ /* The data is distributed over two or more pages. Copy it into the
+ ** Fts5Iter.poslist buffer and then set the output pointer to point
+ ** to this buffer. */
+ fts5BufferZero(&pIter->poslist);
+ fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
+ pIter->base.pData = pIter->poslist.p;
+ pIter->base.nData = pIter->poslist.n;
+ }
+}
+
+static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){
assert( pIter!=0 || (*pRc)!=SQLITE_OK );
- if( *pRc==SQLITE_OK ){
- Fts5Config *pConfig = pIter->pIndex->pConfig;
- if( pConfig->eDetail==FTS5_DETAIL_NONE ){
- pIter->xSetOutputs = fts5IterSetOutputs_None;
- }
-
- else if( pIter->pColset==0 ){
- pIter->xSetOutputs = fts5IterSetOutputs_Nocolset;
- }
-
- else if( pIter->pColset->nCol==0 ){
- pIter->xSetOutputs = fts5IterSetOutputs_ZeroColset;
- }
-
- else if( pConfig->eDetail==FTS5_DETAIL_FULL ){
- pIter->xSetOutputs = fts5IterSetOutputs_Full;
- }
-
- else{
- assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS );
- if( pConfig->nCol<=100 ){
- pIter->xSetOutputs = fts5IterSetOutputs_Col100;
- sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol);
- }else{
- pIter->xSetOutputs = fts5IterSetOutputs_Col;
- }
- }
- }
-}
-
-
-/*
-** Allocate a new Fts5Iter object.
-**
-** The new object will be used to iterate through data in structure pStruct.
-** If iLevel is -ve, then all data in all segments is merged. Or, if iLevel
-** is zero or greater, data from the first nSegment segments on level iLevel
-** is merged.
-**
+ if( *pRc==SQLITE_OK ){
+ Fts5Config *pConfig = pIter->pIndex->pConfig;
+ if( pConfig->eDetail==FTS5_DETAIL_NONE ){
+ pIter->xSetOutputs = fts5IterSetOutputs_None;
+ }
+
+ else if( pIter->pColset==0 ){
+ pIter->xSetOutputs = fts5IterSetOutputs_Nocolset;
+ }
+
+ else if( pIter->pColset->nCol==0 ){
+ pIter->xSetOutputs = fts5IterSetOutputs_ZeroColset;
+ }
+
+ else if( pConfig->eDetail==FTS5_DETAIL_FULL ){
+ pIter->xSetOutputs = fts5IterSetOutputs_Full;
+ }
+
+ else{
+ assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS );
+ if( pConfig->nCol<=100 ){
+ pIter->xSetOutputs = fts5IterSetOutputs_Col100;
+ sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol);
+ }else{
+ pIter->xSetOutputs = fts5IterSetOutputs_Col;
+ }
+ }
+ }
+}
+
+
+/*
+** Allocate a new Fts5Iter object.
+**
+** The new object will be used to iterate through data in structure pStruct.
+** If iLevel is -ve, then all data in all segments is merged. Or, if iLevel
+** is zero or greater, data from the first nSegment segments on level iLevel
+** is merged.
+**
** The iterator initially points to the first term/rowid entry in the
-** iterated data.
-*/
-static void fts5MultiIterNew(
- Fts5Index *p, /* FTS5 backend to iterate within */
- Fts5Structure *pStruct, /* Structure of specific index */
- int flags, /* FTS5INDEX_QUERY_XXX flags */
- Fts5Colset *pColset, /* Colset to filter on (or NULL) */
- const u8 *pTerm, int nTerm, /* Term to seek to (or NULL/0) */
- int iLevel, /* Level to iterate (-1 for all) */
- int nSegment, /* Number of segments to merge (iLevel>=0) */
- Fts5Iter **ppOut /* New object */
-){
- int nSeg = 0; /* Number of segment-iters in use */
- int iIter = 0; /* */
- int iSeg; /* Used to iterate through segments */
- Fts5StructureLevel *pLvl;
- Fts5Iter *pNew;
-
- assert( (pTerm==0 && nTerm==0) || iLevel<0 );
-
- /* Allocate space for the new multi-seg-iterator. */
- if( p->rc==SQLITE_OK ){
- if( iLevel<0 ){
- assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
- nSeg = pStruct->nSegment;
- nSeg += (p->pHash ? 1 : 0);
- }else{
- nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment);
- }
- }
- *ppOut = pNew = fts5MultiIterAlloc(p, nSeg);
+** iterated data.
+*/
+static void fts5MultiIterNew(
+ Fts5Index *p, /* FTS5 backend to iterate within */
+ Fts5Structure *pStruct, /* Structure of specific index */
+ int flags, /* FTS5INDEX_QUERY_XXX flags */
+ Fts5Colset *pColset, /* Colset to filter on (or NULL) */
+ const u8 *pTerm, int nTerm, /* Term to seek to (or NULL/0) */
+ int iLevel, /* Level to iterate (-1 for all) */
+ int nSegment, /* Number of segments to merge (iLevel>=0) */
+ Fts5Iter **ppOut /* New object */
+){
+ int nSeg = 0; /* Number of segment-iters in use */
+ int iIter = 0; /* */
+ int iSeg; /* Used to iterate through segments */
+ Fts5StructureLevel *pLvl;
+ Fts5Iter *pNew;
+
+ assert( (pTerm==0 && nTerm==0) || iLevel<0 );
+
+ /* Allocate space for the new multi-seg-iterator. */
+ if( p->rc==SQLITE_OK ){
+ if( iLevel<0 ){
+ assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
+ nSeg = pStruct->nSegment;
+ nSeg += (p->pHash ? 1 : 0);
+ }else{
+ nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment);
+ }
+ }
+ *ppOut = pNew = fts5MultiIterAlloc(p, nSeg);
if( pNew==0 ){
assert( p->rc!=SQLITE_OK );
goto fts5MultiIterNew_post_check;
}
- pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
- pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY));
- pNew->pColset = pColset;
- if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){
- fts5IterSetOutputCb(&p->rc, pNew);
- }
-
- /* Initialize each of the component segment iterators. */
- if( p->rc==SQLITE_OK ){
- if( iLevel<0 ){
- Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel];
- if( p->pHash ){
- /* Add a segment iterator for the current contents of the hash table. */
- Fts5SegIter *pIter = &pNew->aSeg[iIter++];
- fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter);
- }
- for(pLvl=&pStruct->aLevel[0]; pLvl<pEnd; pLvl++){
- for(iSeg=pLvl->nSeg-1; iSeg>=0; iSeg--){
- Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
- Fts5SegIter *pIter = &pNew->aSeg[iIter++];
- if( pTerm==0 ){
- fts5SegIterInit(p, pSeg, pIter);
- }else{
- fts5SegIterSeekInit(p, pTerm, nTerm, flags, pSeg, pIter);
- }
- }
- }
- }else{
- pLvl = &pStruct->aLevel[iLevel];
- for(iSeg=nSeg-1; iSeg>=0; iSeg--){
- fts5SegIterInit(p, &pLvl->aSeg[iSeg], &pNew->aSeg[iIter++]);
- }
- }
- assert( iIter==nSeg );
- }
-
+ pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
+ pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY));
+ pNew->pColset = pColset;
+ if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){
+ fts5IterSetOutputCb(&p->rc, pNew);
+ }
+
+ /* Initialize each of the component segment iterators. */
+ if( p->rc==SQLITE_OK ){
+ if( iLevel<0 ){
+ Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel];
+ if( p->pHash ){
+ /* Add a segment iterator for the current contents of the hash table. */
+ Fts5SegIter *pIter = &pNew->aSeg[iIter++];
+ fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter);
+ }
+ for(pLvl=&pStruct->aLevel[0]; pLvl<pEnd; pLvl++){
+ for(iSeg=pLvl->nSeg-1; iSeg>=0; iSeg--){
+ Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
+ Fts5SegIter *pIter = &pNew->aSeg[iIter++];
+ if( pTerm==0 ){
+ fts5SegIterInit(p, pSeg, pIter);
+ }else{
+ fts5SegIterSeekInit(p, pTerm, nTerm, flags, pSeg, pIter);
+ }
+ }
+ }
+ }else{
+ pLvl = &pStruct->aLevel[iLevel];
+ for(iSeg=nSeg-1; iSeg>=0; iSeg--){
+ fts5SegIterInit(p, &pLvl->aSeg[iSeg], &pNew->aSeg[iIter++]);
+ }
+ }
+ assert( iIter==nSeg );
+ }
+
/* If the above was successful, each component iterators now points
** to the first entry in its segment. In this case initialize the
- ** aFirst[] array. Or, if an error has occurred, free the iterator
- ** object and set the output variable to NULL. */
- if( p->rc==SQLITE_OK ){
- for(iIter=pNew->nSeg-1; iIter>0; iIter--){
- int iEq;
- if( (iEq = fts5MultiIterDoCompare(pNew, iIter)) ){
- Fts5SegIter *pSeg = &pNew->aSeg[iEq];
- if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0);
- fts5MultiIterAdvanced(p, pNew, iEq, iIter);
- }
- }
- fts5MultiIterSetEof(pNew);
- fts5AssertMultiIterSetup(p, pNew);
-
- if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){
- fts5MultiIterNext(p, pNew, 0, 0);
- }else if( pNew->base.bEof==0 ){
- Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst];
- pNew->xSetOutputs(pNew, pSeg);
- }
-
- }else{
- fts5MultiIterFree(pNew);
- *ppOut = 0;
- }
+ ** aFirst[] array. Or, if an error has occurred, free the iterator
+ ** object and set the output variable to NULL. */
+ if( p->rc==SQLITE_OK ){
+ for(iIter=pNew->nSeg-1; iIter>0; iIter--){
+ int iEq;
+ if( (iEq = fts5MultiIterDoCompare(pNew, iIter)) ){
+ Fts5SegIter *pSeg = &pNew->aSeg[iEq];
+ if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0);
+ fts5MultiIterAdvanced(p, pNew, iEq, iIter);
+ }
+ }
+ fts5MultiIterSetEof(pNew);
+ fts5AssertMultiIterSetup(p, pNew);
+
+ if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){
+ fts5MultiIterNext(p, pNew, 0, 0);
+ }else if( pNew->base.bEof==0 ){
+ Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst];
+ pNew->xSetOutputs(pNew, pSeg);
+ }
+
+ }else{
+ fts5MultiIterFree(pNew);
+ *ppOut = 0;
+ }
fts5MultiIterNew_post_check:
assert( (*ppOut)!=0 || p->rc!=SQLITE_OK );
return;
-}
-
-/*
-** Create an Fts5Iter that iterates through the doclist provided
-** as the second argument.
-*/
-static void fts5MultiIterNew2(
- Fts5Index *p, /* FTS5 backend to iterate within */
- Fts5Data *pData, /* Doclist to iterate through */
- int bDesc, /* True for descending rowid order */
- Fts5Iter **ppOut /* New object */
-){
- Fts5Iter *pNew;
- pNew = fts5MultiIterAlloc(p, 2);
- if( pNew ){
- Fts5SegIter *pIter = &pNew->aSeg[1];
-
- pIter->flags = FTS5_SEGITER_ONETERM;
- if( pData->szLeaf>0 ){
- pIter->pLeaf = pData;
- pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid);
- pIter->iEndofDoclist = pData->nn;
- pNew->aFirst[1].iFirst = 1;
- if( bDesc ){
- pNew->bRev = 1;
- pIter->flags |= FTS5_SEGITER_REVERSE;
- fts5SegIterReverseInitPage(p, pIter);
- }else{
- fts5SegIterLoadNPos(p, pIter);
- }
- pData = 0;
- }else{
- pNew->base.bEof = 1;
- }
- fts5SegIterSetNext(p, pIter);
-
- *ppOut = pNew;
- }
-
- fts5DataRelease(pData);
-}
-
-/*
+}
+
+/*
+** Create an Fts5Iter that iterates through the doclist provided
+** as the second argument.
+*/
+static void fts5MultiIterNew2(
+ Fts5Index *p, /* FTS5 backend to iterate within */
+ Fts5Data *pData, /* Doclist to iterate through */
+ int bDesc, /* True for descending rowid order */
+ Fts5Iter **ppOut /* New object */
+){
+ Fts5Iter *pNew;
+ pNew = fts5MultiIterAlloc(p, 2);
+ if( pNew ){
+ Fts5SegIter *pIter = &pNew->aSeg[1];
+
+ pIter->flags = FTS5_SEGITER_ONETERM;
+ if( pData->szLeaf>0 ){
+ pIter->pLeaf = pData;
+ pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid);
+ pIter->iEndofDoclist = pData->nn;
+ pNew->aFirst[1].iFirst = 1;
+ if( bDesc ){
+ pNew->bRev = 1;
+ pIter->flags |= FTS5_SEGITER_REVERSE;
+ fts5SegIterReverseInitPage(p, pIter);
+ }else{
+ fts5SegIterLoadNPos(p, pIter);
+ }
+ pData = 0;
+ }else{
+ pNew->base.bEof = 1;
+ }
+ fts5SegIterSetNext(p, pIter);
+
+ *ppOut = pNew;
+ }
+
+ fts5DataRelease(pData);
+}
+
+/*
** Return true if the iterator is at EOF or if an error has occurred.
-** False otherwise.
-*/
-static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){
+** False otherwise.
+*/
+static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){
assert( pIter!=0 || p->rc!=SQLITE_OK );
assert( p->rc!=SQLITE_OK
|| (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->base.bEof
- );
- return (p->rc || pIter->base.bEof);
-}
-
-/*
-** Return the rowid of the entry that the iterator currently points
-** to. If the iterator points to EOF when this function is called the
-** results are undefined.
-*/
-static i64 fts5MultiIterRowid(Fts5Iter *pIter){
- assert( pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf );
- return pIter->aSeg[ pIter->aFirst[1].iFirst ].iRowid;
-}
-
-/*
-** Move the iterator to the next entry at or following iMatch.
-*/
-static void fts5MultiIterNextFrom(
+ );
+ return (p->rc || pIter->base.bEof);
+}
+
+/*
+** Return the rowid of the entry that the iterator currently points
+** to. If the iterator points to EOF when this function is called the
+** results are undefined.
+*/
+static i64 fts5MultiIterRowid(Fts5Iter *pIter){
+ assert( pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf );
+ return pIter->aSeg[ pIter->aFirst[1].iFirst ].iRowid;
+}
+
+/*
+** Move the iterator to the next entry at or following iMatch.
+*/
+static void fts5MultiIterNextFrom(
Fts5Index *p,
Fts5Iter *pIter,
- i64 iMatch
-){
- while( 1 ){
- i64 iRowid;
- fts5MultiIterNext(p, pIter, 1, iMatch);
- if( fts5MultiIterEof(p, pIter) ) break;
- iRowid = fts5MultiIterRowid(pIter);
- if( pIter->bRev==0 && iRowid>=iMatch ) break;
- if( pIter->bRev!=0 && iRowid<=iMatch ) break;
- }
-}
-
-/*
+ i64 iMatch
+){
+ while( 1 ){
+ i64 iRowid;
+ fts5MultiIterNext(p, pIter, 1, iMatch);
+ if( fts5MultiIterEof(p, pIter) ) break;
+ iRowid = fts5MultiIterRowid(pIter);
+ if( pIter->bRev==0 && iRowid>=iMatch ) break;
+ if( pIter->bRev!=0 && iRowid<=iMatch ) break;
+ }
+}
+
+/*
** Return a pointer to a buffer containing the term associated with the
-** entry that the iterator currently points to.
-*/
-static const u8 *fts5MultiIterTerm(Fts5Iter *pIter, int *pn){
- Fts5SegIter *p = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
- *pn = p->term.n;
- return p->term.p;
-}
-
-/*
-** Allocate a new segment-id for the structure pStruct. The new segment
+** entry that the iterator currently points to.
+*/
+static const u8 *fts5MultiIterTerm(Fts5Iter *pIter, int *pn){
+ Fts5SegIter *p = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ *pn = p->term.n;
+ return p->term.p;
+}
+
+/*
+** Allocate a new segment-id for the structure pStruct. The new segment
** id must be between 1 and 65335 inclusive, and must not be used by
-** any currently existing segment. If a free segment id cannot be found,
-** SQLITE_FULL is returned.
-**
+** any currently existing segment. If a free segment id cannot be found,
+** SQLITE_FULL is returned.
+**
** If an error has already occurred, this function is a no-op. 0 is
-** returned in this case.
-*/
-static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
- int iSegid = 0;
-
- if( p->rc==SQLITE_OK ){
- if( pStruct->nSegment>=FTS5_MAX_SEGMENT ){
- p->rc = SQLITE_FULL;
- }else{
- /* FTS5_MAX_SEGMENT is currently defined as 2000. So the following
- ** array is 63 elements, or 252 bytes, in size. */
- u32 aUsed[(FTS5_MAX_SEGMENT+31) / 32];
- int iLvl, iSeg;
- int i;
- u32 mask;
- memset(aUsed, 0, sizeof(aUsed));
- for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
- for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
- int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid;
+** returned in this case.
+*/
+static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
+ int iSegid = 0;
+
+ if( p->rc==SQLITE_OK ){
+ if( pStruct->nSegment>=FTS5_MAX_SEGMENT ){
+ p->rc = SQLITE_FULL;
+ }else{
+ /* FTS5_MAX_SEGMENT is currently defined as 2000. So the following
+ ** array is 63 elements, or 252 bytes, in size. */
+ u32 aUsed[(FTS5_MAX_SEGMENT+31) / 32];
+ int iLvl, iSeg;
+ int i;
+ u32 mask;
+ memset(aUsed, 0, sizeof(aUsed));
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+ for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
+ int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid;
if( iId<=FTS5_MAX_SEGMENT && iId>0 ){
aUsed[(iId-1) / 32] |= (u32)1 << ((iId-1) % 32);
- }
- }
- }
-
- for(i=0; aUsed[i]==0xFFFFFFFF; i++);
- mask = aUsed[i];
+ }
+ }
+ }
+
+ for(i=0; aUsed[i]==0xFFFFFFFF; i++);
+ mask = aUsed[i];
for(iSegid=0; mask & ((u32)1 << iSegid); iSegid++);
- iSegid += 1 + i*32;
-
-#ifdef SQLITE_DEBUG
- for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
- for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
+ iSegid += 1 + i*32;
+
+#ifdef SQLITE_DEBUG
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+ for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
assert_nc( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
- }
- }
+ }
+ }
assert_nc( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
-
- {
- sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
- if( p->rc==SQLITE_OK ){
- u8 aBlob[2] = {0xff, 0xff};
- sqlite3_bind_int(pIdxSelect, 1, iSegid);
- sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
+
+ {
+ sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
+ if( p->rc==SQLITE_OK ){
+ u8 aBlob[2] = {0xff, 0xff};
+ sqlite3_bind_int(pIdxSelect, 1, iSegid);
+ sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
assert_nc( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
- p->rc = sqlite3_reset(pIdxSelect);
+ p->rc = sqlite3_reset(pIdxSelect);
sqlite3_bind_null(pIdxSelect, 2);
- }
- }
-#endif
- }
- }
-
- return iSegid;
-}
-
-/*
-** Discard all data currently cached in the hash-tables.
-*/
-static void fts5IndexDiscardData(Fts5Index *p){
- assert( p->pHash || p->nPendingData==0 );
- if( p->pHash ){
- sqlite3Fts5HashClear(p->pHash);
- p->nPendingData = 0;
- }
-}
-
-/*
+ }
+ }
+#endif
+ }
+ }
+
+ return iSegid;
+}
+
+/*
+** Discard all data currently cached in the hash-tables.
+*/
+static void fts5IndexDiscardData(Fts5Index *p){
+ assert( p->pHash || p->nPendingData==0 );
+ if( p->pHash ){
+ sqlite3Fts5HashClear(p->pHash);
+ p->nPendingData = 0;
+ }
+}
+
+/*
** Return the size of the prefix, in bytes, that buffer
-** (pNew/<length-unknown>) shares with buffer (pOld/nOld).
-**
+** (pNew/<length-unknown>) shares with buffer (pOld/nOld).
+**
** Buffer (pNew/<length-unknown>) is guaranteed to be greater
-** than buffer (pOld/nOld).
-*/
-static int fts5PrefixCompress(int nOld, const u8 *pOld, const u8 *pNew){
- int i;
- for(i=0; i<nOld; i++){
- if( pOld[i]!=pNew[i] ) break;
- }
- return i;
-}
-
-static void fts5WriteDlidxClear(
+** than buffer (pOld/nOld).
+*/
+static int fts5PrefixCompress(int nOld, const u8 *pOld, const u8 *pNew){
+ int i;
+ for(i=0; i<nOld; i++){
+ if( pOld[i]!=pNew[i] ) break;
+ }
+ return i;
+}
+
+static void fts5WriteDlidxClear(
Fts5Index *p,
- Fts5SegWriter *pWriter,
- int bFlush /* If true, write dlidx to disk */
-){
- int i;
- assert( bFlush==0 || (pWriter->nDlidx>0 && pWriter->aDlidx[0].buf.n>0) );
- for(i=0; i<pWriter->nDlidx; i++){
- Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[i];
- if( pDlidx->buf.n==0 ) break;
- if( bFlush ){
- assert( pDlidx->pgno!=0 );
+ Fts5SegWriter *pWriter,
+ int bFlush /* If true, write dlidx to disk */
+){
+ int i;
+ assert( bFlush==0 || (pWriter->nDlidx>0 && pWriter->aDlidx[0].buf.n>0) );
+ for(i=0; i<pWriter->nDlidx; i++){
+ Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[i];
+ if( pDlidx->buf.n==0 ) break;
+ if( bFlush ){
+ assert( pDlidx->pgno!=0 );
fts5DataWrite(p,
- FTS5_DLIDX_ROWID(pWriter->iSegid, i, pDlidx->pgno),
- pDlidx->buf.p, pDlidx->buf.n
- );
- }
- sqlite3Fts5BufferZero(&pDlidx->buf);
- pDlidx->bPrevValid = 0;
- }
-}
-
-/*
-** Grow the pWriter->aDlidx[] array to at least nLvl elements in size.
-** Any new array elements are zeroed before returning.
-*/
-static int fts5WriteDlidxGrow(
- Fts5Index *p,
- Fts5SegWriter *pWriter,
- int nLvl
-){
- if( p->rc==SQLITE_OK && nLvl>=pWriter->nDlidx ){
+ FTS5_DLIDX_ROWID(pWriter->iSegid, i, pDlidx->pgno),
+ pDlidx->buf.p, pDlidx->buf.n
+ );
+ }
+ sqlite3Fts5BufferZero(&pDlidx->buf);
+ pDlidx->bPrevValid = 0;
+ }
+}
+
+/*
+** Grow the pWriter->aDlidx[] array to at least nLvl elements in size.
+** Any new array elements are zeroed before returning.
+*/
+static int fts5WriteDlidxGrow(
+ Fts5Index *p,
+ Fts5SegWriter *pWriter,
+ int nLvl
+){
+ if( p->rc==SQLITE_OK && nLvl>=pWriter->nDlidx ){
Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc64(
- pWriter->aDlidx, sizeof(Fts5DlidxWriter) * nLvl
- );
- if( aDlidx==0 ){
- p->rc = SQLITE_NOMEM;
- }else{
+ pWriter->aDlidx, sizeof(Fts5DlidxWriter) * nLvl
+ );
+ if( aDlidx==0 ){
+ p->rc = SQLITE_NOMEM;
+ }else{
size_t nByte = sizeof(Fts5DlidxWriter) * (nLvl - pWriter->nDlidx);
- memset(&aDlidx[pWriter->nDlidx], 0, nByte);
- pWriter->aDlidx = aDlidx;
- pWriter->nDlidx = nLvl;
- }
- }
- return p->rc;
-}
-
-/*
-** If the current doclist-index accumulating in pWriter->aDlidx[] is large
-** enough, flush it to disk and return 1. Otherwise discard it and return
-** zero.
-*/
-static int fts5WriteFlushDlidx(Fts5Index *p, Fts5SegWriter *pWriter){
- int bFlag = 0;
-
- /* If there were FTS5_MIN_DLIDX_SIZE or more empty leaf pages written
- ** to the database, also write the doclist-index to disk. */
- if( pWriter->aDlidx[0].buf.n>0 && pWriter->nEmpty>=FTS5_MIN_DLIDX_SIZE ){
- bFlag = 1;
- }
- fts5WriteDlidxClear(p, pWriter, bFlag);
- pWriter->nEmpty = 0;
- return bFlag;
-}
-
-/*
+ memset(&aDlidx[pWriter->nDlidx], 0, nByte);
+ pWriter->aDlidx = aDlidx;
+ pWriter->nDlidx = nLvl;
+ }
+ }
+ return p->rc;
+}
+
+/*
+** If the current doclist-index accumulating in pWriter->aDlidx[] is large
+** enough, flush it to disk and return 1. Otherwise discard it and return
+** zero.
+*/
+static int fts5WriteFlushDlidx(Fts5Index *p, Fts5SegWriter *pWriter){
+ int bFlag = 0;
+
+ /* If there were FTS5_MIN_DLIDX_SIZE or more empty leaf pages written
+ ** to the database, also write the doclist-index to disk. */
+ if( pWriter->aDlidx[0].buf.n>0 && pWriter->nEmpty>=FTS5_MIN_DLIDX_SIZE ){
+ bFlag = 1;
+ }
+ fts5WriteDlidxClear(p, pWriter, bFlag);
+ pWriter->nEmpty = 0;
+ return bFlag;
+}
+
+/*
** This function is called whenever processing of the doclist for the
** last term on leaf page (pWriter->iBtPage) is completed.
-**
-** The doclist-index for that term is currently stored in-memory within the
-** Fts5SegWriter.aDlidx[] array. If it is large enough, this function
-** writes it out to disk. Or, if it is too small to bother with, discards
-** it.
-**
-** Fts5SegWriter.btterm currently contains the first term on page iBtPage.
-*/
-static void fts5WriteFlushBtree(Fts5Index *p, Fts5SegWriter *pWriter){
- int bFlag;
-
- assert( pWriter->iBtPage || pWriter->nEmpty==0 );
- if( pWriter->iBtPage==0 ) return;
- bFlag = fts5WriteFlushDlidx(p, pWriter);
-
- if( p->rc==SQLITE_OK ){
- const char *z = (pWriter->btterm.n>0?(const char*)pWriter->btterm.p:"");
- /* The following was already done in fts5WriteInit(): */
- /* sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid); */
- sqlite3_bind_blob(p->pIdxWriter, 2, z, pWriter->btterm.n, SQLITE_STATIC);
- sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1));
- sqlite3_step(p->pIdxWriter);
- p->rc = sqlite3_reset(p->pIdxWriter);
+**
+** The doclist-index for that term is currently stored in-memory within the
+** Fts5SegWriter.aDlidx[] array. If it is large enough, this function
+** writes it out to disk. Or, if it is too small to bother with, discards
+** it.
+**
+** Fts5SegWriter.btterm currently contains the first term on page iBtPage.
+*/
+static void fts5WriteFlushBtree(Fts5Index *p, Fts5SegWriter *pWriter){
+ int bFlag;
+
+ assert( pWriter->iBtPage || pWriter->nEmpty==0 );
+ if( pWriter->iBtPage==0 ) return;
+ bFlag = fts5WriteFlushDlidx(p, pWriter);
+
+ if( p->rc==SQLITE_OK ){
+ const char *z = (pWriter->btterm.n>0?(const char*)pWriter->btterm.p:"");
+ /* The following was already done in fts5WriteInit(): */
+ /* sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid); */
+ sqlite3_bind_blob(p->pIdxWriter, 2, z, pWriter->btterm.n, SQLITE_STATIC);
+ sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1));
+ sqlite3_step(p->pIdxWriter);
+ p->rc = sqlite3_reset(p->pIdxWriter);
sqlite3_bind_null(p->pIdxWriter, 2);
- }
- pWriter->iBtPage = 0;
-}
-
-/*
-** This is called once for each leaf page except the first that contains
-** at least one term. Argument (nTerm/pTerm) is the split-key - a term that
-** is larger than all terms written to earlier leaves, and equal to or
-** smaller than the first term on the new leaf.
-**
-** If an error occurs, an error code is left in Fts5Index.rc. If an error
-** has already occurred when this function is called, it is a no-op.
-*/
-static void fts5WriteBtreeTerm(
- Fts5Index *p, /* FTS5 backend object */
- Fts5SegWriter *pWriter, /* Writer object */
- int nTerm, const u8 *pTerm /* First term on new page */
-){
- fts5WriteFlushBtree(p, pWriter);
+ }
+ pWriter->iBtPage = 0;
+}
+
+/*
+** This is called once for each leaf page except the first that contains
+** at least one term. Argument (nTerm/pTerm) is the split-key - a term that
+** is larger than all terms written to earlier leaves, and equal to or
+** smaller than the first term on the new leaf.
+**
+** If an error occurs, an error code is left in Fts5Index.rc. If an error
+** has already occurred when this function is called, it is a no-op.
+*/
+static void fts5WriteBtreeTerm(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegWriter *pWriter, /* Writer object */
+ int nTerm, const u8 *pTerm /* First term on new page */
+){
+ fts5WriteFlushBtree(p, pWriter);
if( p->rc==SQLITE_OK ){
fts5BufferSet(&p->rc, &pWriter->btterm, nTerm, pTerm);
pWriter->iBtPage = pWriter->writer.pgno;
}
-}
-
-/*
-** This function is called when flushing a leaf page that contains no
-** terms at all to disk.
-*/
-static void fts5WriteBtreeNoTerm(
- Fts5Index *p, /* FTS5 backend object */
- Fts5SegWriter *pWriter /* Writer object */
-){
- /* If there were no rowids on the leaf page either and the doclist-index
- ** has already been started, append an 0x00 byte to it. */
- if( pWriter->bFirstRowidInPage && pWriter->aDlidx[0].buf.n>0 ){
- Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[0];
- assert( pDlidx->bPrevValid );
- sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, 0);
- }
-
- /* Increment the "number of sequential leaves without a term" counter. */
- pWriter->nEmpty++;
-}
-
-static i64 fts5DlidxExtractFirstRowid(Fts5Buffer *pBuf){
- i64 iRowid;
- int iOff;
-
- iOff = 1 + fts5GetVarint(&pBuf->p[1], (u64*)&iRowid);
- fts5GetVarint(&pBuf->p[iOff], (u64*)&iRowid);
- return iRowid;
-}
-
-/*
-** Rowid iRowid has just been appended to the current leaf page. It is the
-** first on the page. This function appends an appropriate entry to the current
-** doclist-index.
-*/
-static void fts5WriteDlidxAppend(
+}
+
+/*
+** This function is called when flushing a leaf page that contains no
+** terms at all to disk.
+*/
+static void fts5WriteBtreeNoTerm(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegWriter *pWriter /* Writer object */
+){
+ /* If there were no rowids on the leaf page either and the doclist-index
+ ** has already been started, append an 0x00 byte to it. */
+ if( pWriter->bFirstRowidInPage && pWriter->aDlidx[0].buf.n>0 ){
+ Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[0];
+ assert( pDlidx->bPrevValid );
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, 0);
+ }
+
+ /* Increment the "number of sequential leaves without a term" counter. */
+ pWriter->nEmpty++;
+}
+
+static i64 fts5DlidxExtractFirstRowid(Fts5Buffer *pBuf){
+ i64 iRowid;
+ int iOff;
+
+ iOff = 1 + fts5GetVarint(&pBuf->p[1], (u64*)&iRowid);
+ fts5GetVarint(&pBuf->p[iOff], (u64*)&iRowid);
+ return iRowid;
+}
+
+/*
+** Rowid iRowid has just been appended to the current leaf page. It is the
+** first on the page. This function appends an appropriate entry to the current
+** doclist-index.
+*/
+static void fts5WriteDlidxAppend(
Fts5Index *p,
Fts5SegWriter *pWriter,
- i64 iRowid
-){
- int i;
- int bDone = 0;
-
- for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
- i64 iVal;
- Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[i];
-
- if( pDlidx->buf.n>=p->pConfig->pgsz ){
- /* The current doclist-index page is full. Write it to disk and push
- ** a copy of iRowid (which will become the first rowid on the next
+ i64 iRowid
+){
+ int i;
+ int bDone = 0;
+
+ for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
+ i64 iVal;
+ Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[i];
+
+ if( pDlidx->buf.n>=p->pConfig->pgsz ){
+ /* The current doclist-index page is full. Write it to disk and push
+ ** a copy of iRowid (which will become the first rowid on the next
** doclist-index leaf page) up into the next level of the b-tree
- ** hierarchy. If the node being flushed is currently the root node,
- ** also push its first rowid upwards. */
- pDlidx->buf.p[0] = 0x01; /* Not the root node */
+ ** hierarchy. If the node being flushed is currently the root node,
+ ** also push its first rowid upwards. */
+ pDlidx->buf.p[0] = 0x01; /* Not the root node */
fts5DataWrite(p,
- FTS5_DLIDX_ROWID(pWriter->iSegid, i, pDlidx->pgno),
- pDlidx->buf.p, pDlidx->buf.n
- );
- fts5WriteDlidxGrow(p, pWriter, i+2);
- pDlidx = &pWriter->aDlidx[i];
- if( p->rc==SQLITE_OK && pDlidx[1].buf.n==0 ){
- i64 iFirst = fts5DlidxExtractFirstRowid(&pDlidx->buf);
-
- /* This was the root node. Push its first rowid up to the new root. */
- pDlidx[1].pgno = pDlidx->pgno;
- sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, 0);
- sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, pDlidx->pgno);
- sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, iFirst);
- pDlidx[1].bPrevValid = 1;
- pDlidx[1].iPrev = iFirst;
- }
-
- sqlite3Fts5BufferZero(&pDlidx->buf);
- pDlidx->bPrevValid = 0;
- pDlidx->pgno++;
- }else{
- bDone = 1;
- }
-
- if( pDlidx->bPrevValid ){
- iVal = iRowid - pDlidx->iPrev;
- }else{
- i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno);
- assert( pDlidx->buf.n==0 );
- sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, !bDone);
- sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iPgno);
- iVal = iRowid;
- }
-
- sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iVal);
- pDlidx->bPrevValid = 1;
- pDlidx->iPrev = iRowid;
- }
-}
-
-static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){
- static const u8 zero[] = { 0x00, 0x00, 0x00, 0x00 };
- Fts5PageWriter *pPage = &pWriter->writer;
- i64 iRowid;
-
- assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) );
-
- /* Set the szLeaf header field. */
- assert( 0==fts5GetU16(&pPage->buf.p[2]) );
- fts5PutU16(&pPage->buf.p[2], (u16)pPage->buf.n);
-
- if( pWriter->bFirstTermInPage ){
- /* No term was written to this page. */
- assert( pPage->pgidx.n==0 );
- fts5WriteBtreeNoTerm(p, pWriter);
- }else{
- /* Append the pgidx to the page buffer. Set the szLeaf header field. */
- fts5BufferAppendBlob(&p->rc, &pPage->buf, pPage->pgidx.n, pPage->pgidx.p);
- }
-
- /* Write the page out to disk */
- iRowid = FTS5_SEGMENT_ROWID(pWriter->iSegid, pPage->pgno);
- fts5DataWrite(p, iRowid, pPage->buf.p, pPage->buf.n);
-
- /* Initialize the next page. */
- fts5BufferZero(&pPage->buf);
- fts5BufferZero(&pPage->pgidx);
- fts5BufferAppendBlob(&p->rc, &pPage->buf, 4, zero);
- pPage->iPrevPgidx = 0;
- pPage->pgno++;
-
- /* Increase the leaves written counter */
- pWriter->nLeafWritten++;
-
- /* The new leaf holds no terms or rowids */
- pWriter->bFirstTermInPage = 1;
- pWriter->bFirstRowidInPage = 1;
-}
-
-/*
-** Append term pTerm/nTerm to the segment being written by the writer passed
-** as the second argument.
-**
+ FTS5_DLIDX_ROWID(pWriter->iSegid, i, pDlidx->pgno),
+ pDlidx->buf.p, pDlidx->buf.n
+ );
+ fts5WriteDlidxGrow(p, pWriter, i+2);
+ pDlidx = &pWriter->aDlidx[i];
+ if( p->rc==SQLITE_OK && pDlidx[1].buf.n==0 ){
+ i64 iFirst = fts5DlidxExtractFirstRowid(&pDlidx->buf);
+
+ /* This was the root node. Push its first rowid up to the new root. */
+ pDlidx[1].pgno = pDlidx->pgno;
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, 0);
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, pDlidx->pgno);
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, iFirst);
+ pDlidx[1].bPrevValid = 1;
+ pDlidx[1].iPrev = iFirst;
+ }
+
+ sqlite3Fts5BufferZero(&pDlidx->buf);
+ pDlidx->bPrevValid = 0;
+ pDlidx->pgno++;
+ }else{
+ bDone = 1;
+ }
+
+ if( pDlidx->bPrevValid ){
+ iVal = iRowid - pDlidx->iPrev;
+ }else{
+ i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno);
+ assert( pDlidx->buf.n==0 );
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, !bDone);
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iPgno);
+ iVal = iRowid;
+ }
+
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iVal);
+ pDlidx->bPrevValid = 1;
+ pDlidx->iPrev = iRowid;
+ }
+}
+
+static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){
+ static const u8 zero[] = { 0x00, 0x00, 0x00, 0x00 };
+ Fts5PageWriter *pPage = &pWriter->writer;
+ i64 iRowid;
+
+ assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) );
+
+ /* Set the szLeaf header field. */
+ assert( 0==fts5GetU16(&pPage->buf.p[2]) );
+ fts5PutU16(&pPage->buf.p[2], (u16)pPage->buf.n);
+
+ if( pWriter->bFirstTermInPage ){
+ /* No term was written to this page. */
+ assert( pPage->pgidx.n==0 );
+ fts5WriteBtreeNoTerm(p, pWriter);
+ }else{
+ /* Append the pgidx to the page buffer. Set the szLeaf header field. */
+ fts5BufferAppendBlob(&p->rc, &pPage->buf, pPage->pgidx.n, pPage->pgidx.p);
+ }
+
+ /* Write the page out to disk */
+ iRowid = FTS5_SEGMENT_ROWID(pWriter->iSegid, pPage->pgno);
+ fts5DataWrite(p, iRowid, pPage->buf.p, pPage->buf.n);
+
+ /* Initialize the next page. */
+ fts5BufferZero(&pPage->buf);
+ fts5BufferZero(&pPage->pgidx);
+ fts5BufferAppendBlob(&p->rc, &pPage->buf, 4, zero);
+ pPage->iPrevPgidx = 0;
+ pPage->pgno++;
+
+ /* Increase the leaves written counter */
+ pWriter->nLeafWritten++;
+
+ /* The new leaf holds no terms or rowids */
+ pWriter->bFirstTermInPage = 1;
+ pWriter->bFirstRowidInPage = 1;
+}
+
+/*
+** Append term pTerm/nTerm to the segment being written by the writer passed
+** as the second argument.
+**
** If an error occurs, set the Fts5Index.rc error code. If an error has
-** already occurred, this function is a no-op.
-*/
-static void fts5WriteAppendTerm(
+** already occurred, this function is a no-op.
+*/
+static void fts5WriteAppendTerm(
Fts5Index *p,
- Fts5SegWriter *pWriter,
+ Fts5SegWriter *pWriter,
int nTerm, const u8 *pTerm
-){
- int nPrefix; /* Bytes of prefix compression for term */
- Fts5PageWriter *pPage = &pWriter->writer;
- Fts5Buffer *pPgidx = &pWriter->writer.pgidx;
+){
+ int nPrefix; /* Bytes of prefix compression for term */
+ Fts5PageWriter *pPage = &pWriter->writer;
+ Fts5Buffer *pPgidx = &pWriter->writer.pgidx;
int nMin = MIN(pPage->term.n, nTerm);
-
- assert( p->rc==SQLITE_OK );
- assert( pPage->buf.n>=4 );
- assert( pPage->buf.n>4 || pWriter->bFirstTermInPage );
-
- /* If the current leaf page is full, flush it to disk. */
- if( (pPage->buf.n + pPgidx->n + nTerm + 2)>=p->pConfig->pgsz ){
- if( pPage->buf.n>4 ){
- fts5WriteFlushLeaf(p, pWriter);
+
+ assert( p->rc==SQLITE_OK );
+ assert( pPage->buf.n>=4 );
+ assert( pPage->buf.n>4 || pWriter->bFirstTermInPage );
+
+ /* If the current leaf page is full, flush it to disk. */
+ if( (pPage->buf.n + pPgidx->n + nTerm + 2)>=p->pConfig->pgsz ){
+ if( pPage->buf.n>4 ){
+ fts5WriteFlushLeaf(p, pWriter);
if( p->rc!=SQLITE_OK ) return;
- }
- fts5BufferGrow(&p->rc, &pPage->buf, nTerm+FTS5_DATA_PADDING);
- }
-
- /* TODO1: Updating pgidx here. */
- pPgidx->n += sqlite3Fts5PutVarint(
- &pPgidx->p[pPgidx->n], pPage->buf.n - pPage->iPrevPgidx
- );
- pPage->iPrevPgidx = pPage->buf.n;
-#if 0
- fts5PutU16(&pPgidx->p[pPgidx->n], pPage->buf.n);
- pPgidx->n += 2;
-#endif
-
- if( pWriter->bFirstTermInPage ){
- nPrefix = 0;
- if( pPage->pgno!=1 ){
- /* This is the first term on a leaf that is not the leftmost leaf in
- ** the segment b-tree. In this case it is necessary to add a term to
+ }
+ fts5BufferGrow(&p->rc, &pPage->buf, nTerm+FTS5_DATA_PADDING);
+ }
+
+ /* TODO1: Updating pgidx here. */
+ pPgidx->n += sqlite3Fts5PutVarint(
+ &pPgidx->p[pPgidx->n], pPage->buf.n - pPage->iPrevPgidx
+ );
+ pPage->iPrevPgidx = pPage->buf.n;
+#if 0
+ fts5PutU16(&pPgidx->p[pPgidx->n], pPage->buf.n);
+ pPgidx->n += 2;
+#endif
+
+ if( pWriter->bFirstTermInPage ){
+ nPrefix = 0;
+ if( pPage->pgno!=1 ){
+ /* This is the first term on a leaf that is not the leftmost leaf in
+ ** the segment b-tree. In this case it is necessary to add a term to
** the b-tree hierarchy that is (a) larger than the largest term
- ** already written to the segment and (b) smaller than or equal to
- ** this term. In other words, a prefix of (pTerm/nTerm) that is one
- ** byte longer than the longest prefix (pTerm/nTerm) shares with the
+ ** already written to the segment and (b) smaller than or equal to
+ ** this term. In other words, a prefix of (pTerm/nTerm) that is one
+ ** byte longer than the longest prefix (pTerm/nTerm) shares with the
** previous term.
- **
- ** Usually, the previous term is available in pPage->term. The exception
- ** is if this is the first term written in an incremental-merge step.
- ** In this case the previous term is not available, so just write a
- ** copy of (pTerm/nTerm) into the parent node. This is slightly
- ** inefficient, but still correct. */
- int n = nTerm;
- if( pPage->term.n ){
+ **
+ ** Usually, the previous term is available in pPage->term. The exception
+ ** is if this is the first term written in an incremental-merge step.
+ ** In this case the previous term is not available, so just write a
+ ** copy of (pTerm/nTerm) into the parent node. This is slightly
+ ** inefficient, but still correct. */
+ int n = nTerm;
+ if( pPage->term.n ){
n = 1 + fts5PrefixCompress(nMin, pPage->term.p, pTerm);
- }
- fts5WriteBtreeTerm(p, pWriter, n, pTerm);
+ }
+ fts5WriteBtreeTerm(p, pWriter, n, pTerm);
if( p->rc!=SQLITE_OK ) return;
- pPage = &pWriter->writer;
- }
- }else{
+ pPage = &pWriter->writer;
+ }
+ }else{
nPrefix = fts5PrefixCompress(nMin, pPage->term.p, pTerm);
- fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
- }
-
- /* Append the number of bytes of new data, then the term data itself
- ** to the page. */
- fts5BufferAppendVarint(&p->rc, &pPage->buf, nTerm - nPrefix);
- fts5BufferAppendBlob(&p->rc, &pPage->buf, nTerm - nPrefix, &pTerm[nPrefix]);
-
- /* Update the Fts5PageWriter.term field. */
- fts5BufferSet(&p->rc, &pPage->term, nTerm, pTerm);
- pWriter->bFirstTermInPage = 0;
-
- pWriter->bFirstRowidInPage = 0;
- pWriter->bFirstRowidInDoclist = 1;
-
- assert( p->rc || (pWriter->nDlidx>0 && pWriter->aDlidx[0].buf.n==0) );
- pWriter->aDlidx[0].pgno = pPage->pgno;
-}
-
-/*
+ fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
+ }
+
+ /* Append the number of bytes of new data, then the term data itself
+ ** to the page. */
+ fts5BufferAppendVarint(&p->rc, &pPage->buf, nTerm - nPrefix);
+ fts5BufferAppendBlob(&p->rc, &pPage->buf, nTerm - nPrefix, &pTerm[nPrefix]);
+
+ /* Update the Fts5PageWriter.term field. */
+ fts5BufferSet(&p->rc, &pPage->term, nTerm, pTerm);
+ pWriter->bFirstTermInPage = 0;
+
+ pWriter->bFirstRowidInPage = 0;
+ pWriter->bFirstRowidInDoclist = 1;
+
+ assert( p->rc || (pWriter->nDlidx>0 && pWriter->aDlidx[0].buf.n==0) );
+ pWriter->aDlidx[0].pgno = pPage->pgno;
+}
+
+/*
** Append a rowid and position-list size field to the writers output.
-*/
-static void fts5WriteAppendRowid(
+*/
+static void fts5WriteAppendRowid(
Fts5Index *p,
- Fts5SegWriter *pWriter,
- i64 iRowid
-){
- if( p->rc==SQLITE_OK ){
- Fts5PageWriter *pPage = &pWriter->writer;
-
- if( (pPage->buf.n + pPage->pgidx.n)>=p->pConfig->pgsz ){
- fts5WriteFlushLeaf(p, pWriter);
- }
-
+ Fts5SegWriter *pWriter,
+ i64 iRowid
+){
+ if( p->rc==SQLITE_OK ){
+ Fts5PageWriter *pPage = &pWriter->writer;
+
+ if( (pPage->buf.n + pPage->pgidx.n)>=p->pConfig->pgsz ){
+ fts5WriteFlushLeaf(p, pWriter);
+ }
+
/* If this is to be the first rowid written to the page, set the
- ** rowid-pointer in the page-header. Also append a value to the dlidx
- ** buffer, in case a doclist-index is required. */
- if( pWriter->bFirstRowidInPage ){
- fts5PutU16(pPage->buf.p, (u16)pPage->buf.n);
- fts5WriteDlidxAppend(p, pWriter, iRowid);
- }
-
- /* Write the rowid. */
- if( pWriter->bFirstRowidInDoclist || pWriter->bFirstRowidInPage ){
- fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid);
- }else{
+ ** rowid-pointer in the page-header. Also append a value to the dlidx
+ ** buffer, in case a doclist-index is required. */
+ if( pWriter->bFirstRowidInPage ){
+ fts5PutU16(pPage->buf.p, (u16)pPage->buf.n);
+ fts5WriteDlidxAppend(p, pWriter, iRowid);
+ }
+
+ /* Write the rowid. */
+ if( pWriter->bFirstRowidInDoclist || pWriter->bFirstRowidInPage ){
+ fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid);
+ }else{
assert_nc( p->rc || iRowid>pWriter->iPrevRowid );
- fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid);
- }
- pWriter->iPrevRowid = iRowid;
- pWriter->bFirstRowidInDoclist = 0;
- pWriter->bFirstRowidInPage = 0;
- }
-}
-
-static void fts5WriteAppendPoslistData(
+ fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid);
+ }
+ pWriter->iPrevRowid = iRowid;
+ pWriter->bFirstRowidInDoclist = 0;
+ pWriter->bFirstRowidInPage = 0;
+ }
+}
+
+static void fts5WriteAppendPoslistData(
Fts5Index *p,
Fts5SegWriter *pWriter,
const u8 *aData,
- int nData
-){
- Fts5PageWriter *pPage = &pWriter->writer;
- const u8 *a = aData;
- int n = nData;
+ int nData
+){
+ Fts5PageWriter *pPage = &pWriter->writer;
+ const u8 *a = aData;
+ int n = nData;
- assert( p->pConfig->pgsz>0 );
+ assert( p->pConfig->pgsz>0 );
while( p->rc==SQLITE_OK
&& (pPage->buf.n + pPage->pgidx.n + n)>=p->pConfig->pgsz
- ){
- int nReq = p->pConfig->pgsz - pPage->buf.n - pPage->pgidx.n;
- int nCopy = 0;
- while( nCopy<nReq ){
- i64 dummy;
- nCopy += fts5GetVarint(&a[nCopy], (u64*)&dummy);
- }
- fts5BufferAppendBlob(&p->rc, &pPage->buf, nCopy, a);
- a += nCopy;
- n -= nCopy;
- fts5WriteFlushLeaf(p, pWriter);
- }
- if( n>0 ){
- fts5BufferAppendBlob(&p->rc, &pPage->buf, n, a);
- }
-}
-
-/*
-** Flush any data cached by the writer object to the database. Free any
-** allocations associated with the writer.
-*/
-static void fts5WriteFinish(
+ ){
+ int nReq = p->pConfig->pgsz - pPage->buf.n - pPage->pgidx.n;
+ int nCopy = 0;
+ while( nCopy<nReq ){
+ i64 dummy;
+ nCopy += fts5GetVarint(&a[nCopy], (u64*)&dummy);
+ }
+ fts5BufferAppendBlob(&p->rc, &pPage->buf, nCopy, a);
+ a += nCopy;
+ n -= nCopy;
+ fts5WriteFlushLeaf(p, pWriter);
+ }
+ if( n>0 ){
+ fts5BufferAppendBlob(&p->rc, &pPage->buf, n, a);
+ }
+}
+
+/*
+** Flush any data cached by the writer object to the database. Free any
+** allocations associated with the writer.
+*/
+static void fts5WriteFinish(
Fts5Index *p,
- Fts5SegWriter *pWriter, /* Writer object */
- int *pnLeaf /* OUT: Number of leaf pages in b-tree */
-){
- int i;
- Fts5PageWriter *pLeaf = &pWriter->writer;
- if( p->rc==SQLITE_OK ){
- assert( pLeaf->pgno>=1 );
- if( pLeaf->buf.n>4 ){
- fts5WriteFlushLeaf(p, pWriter);
- }
- *pnLeaf = pLeaf->pgno-1;
- if( pLeaf->pgno>1 ){
- fts5WriteFlushBtree(p, pWriter);
- }
- }
- fts5BufferFree(&pLeaf->term);
- fts5BufferFree(&pLeaf->buf);
- fts5BufferFree(&pLeaf->pgidx);
- fts5BufferFree(&pWriter->btterm);
-
- for(i=0; i<pWriter->nDlidx; i++){
- sqlite3Fts5BufferFree(&pWriter->aDlidx[i].buf);
- }
- sqlite3_free(pWriter->aDlidx);
-}
-
-static void fts5WriteInit(
+ Fts5SegWriter *pWriter, /* Writer object */
+ int *pnLeaf /* OUT: Number of leaf pages in b-tree */
+){
+ int i;
+ Fts5PageWriter *pLeaf = &pWriter->writer;
+ if( p->rc==SQLITE_OK ){
+ assert( pLeaf->pgno>=1 );
+ if( pLeaf->buf.n>4 ){
+ fts5WriteFlushLeaf(p, pWriter);
+ }
+ *pnLeaf = pLeaf->pgno-1;
+ if( pLeaf->pgno>1 ){
+ fts5WriteFlushBtree(p, pWriter);
+ }
+ }
+ fts5BufferFree(&pLeaf->term);
+ fts5BufferFree(&pLeaf->buf);
+ fts5BufferFree(&pLeaf->pgidx);
+ fts5BufferFree(&pWriter->btterm);
+
+ for(i=0; i<pWriter->nDlidx; i++){
+ sqlite3Fts5BufferFree(&pWriter->aDlidx[i].buf);
+ }
+ sqlite3_free(pWriter->aDlidx);
+}
+
+static void fts5WriteInit(
Fts5Index *p,
Fts5SegWriter *pWriter,
- int iSegid
-){
- const int nBuffer = p->pConfig->pgsz + FTS5_DATA_PADDING;
-
- memset(pWriter, 0, sizeof(Fts5SegWriter));
- pWriter->iSegid = iSegid;
-
- fts5WriteDlidxGrow(p, pWriter, 1);
- pWriter->writer.pgno = 1;
- pWriter->bFirstTermInPage = 1;
- pWriter->iBtPage = 1;
-
- assert( pWriter->writer.buf.n==0 );
- assert( pWriter->writer.pgidx.n==0 );
-
- /* Grow the two buffers to pgsz + padding bytes in size. */
- sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.pgidx, nBuffer);
- sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.buf, nBuffer);
-
- if( p->pIdxWriter==0 ){
- Fts5Config *pConfig = p->pConfig;
- fts5IndexPrepareStmt(p, &p->pIdxWriter, sqlite3_mprintf(
+ int iSegid
+){
+ const int nBuffer = p->pConfig->pgsz + FTS5_DATA_PADDING;
+
+ memset(pWriter, 0, sizeof(Fts5SegWriter));
+ pWriter->iSegid = iSegid;
+
+ fts5WriteDlidxGrow(p, pWriter, 1);
+ pWriter->writer.pgno = 1;
+ pWriter->bFirstTermInPage = 1;
+ pWriter->iBtPage = 1;
+
+ assert( pWriter->writer.buf.n==0 );
+ assert( pWriter->writer.pgidx.n==0 );
+
+ /* Grow the two buffers to pgsz + padding bytes in size. */
+ sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.pgidx, nBuffer);
+ sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.buf, nBuffer);
+
+ if( p->pIdxWriter==0 ){
+ Fts5Config *pConfig = p->pConfig;
+ fts5IndexPrepareStmt(p, &p->pIdxWriter, sqlite3_mprintf(
"INSERT INTO '%q'.'%q_idx'(segid,term,pgno) VALUES(?,?,?)",
- pConfig->zDb, pConfig->zName
- ));
- }
-
- if( p->rc==SQLITE_OK ){
- /* Initialize the 4-byte leaf-page header to 0x00. */
- memset(pWriter->writer.buf.p, 0, 4);
- pWriter->writer.buf.n = 4;
-
- /* Bind the current output segment id to the index-writer. This is an
- ** optimization over binding the same value over and over as rows are
- ** inserted into %_idx by the current writer. */
- sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid);
- }
-}
-
-/*
-** Iterator pIter was used to iterate through the input segments of on an
-** incremental merge operation. This function is called if the incremental
-** merge step has finished but the input has not been completely exhausted.
-*/
-static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
- int i;
- Fts5Buffer buf;
- memset(&buf, 0, sizeof(Fts5Buffer));
+ pConfig->zDb, pConfig->zName
+ ));
+ }
+
+ if( p->rc==SQLITE_OK ){
+ /* Initialize the 4-byte leaf-page header to 0x00. */
+ memset(pWriter->writer.buf.p, 0, 4);
+ pWriter->writer.buf.n = 4;
+
+ /* Bind the current output segment id to the index-writer. This is an
+ ** optimization over binding the same value over and over as rows are
+ ** inserted into %_idx by the current writer. */
+ sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid);
+ }
+}
+
+/*
+** Iterator pIter was used to iterate through the input segments of on an
+** incremental merge operation. This function is called if the incremental
+** merge step has finished but the input has not been completely exhausted.
+*/
+static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
+ int i;
+ Fts5Buffer buf;
+ memset(&buf, 0, sizeof(Fts5Buffer));
for(i=0; i<pIter->nSeg && p->rc==SQLITE_OK; i++){
- Fts5SegIter *pSeg = &pIter->aSeg[i];
- if( pSeg->pSeg==0 ){
- /* no-op */
- }else if( pSeg->pLeaf==0 ){
- /* All keys from this input segment have been transfered to the output.
- ** Set both the first and last page-numbers to 0 to indicate that the
- ** segment is now empty. */
- pSeg->pSeg->pgnoLast = 0;
- pSeg->pSeg->pgnoFirst = 0;
- }else{
- int iOff = pSeg->iTermLeafOffset; /* Offset on new first leaf page */
- i64 iLeafRowid;
- Fts5Data *pData;
- int iId = pSeg->pSeg->iSegid;
- u8 aHdr[4] = {0x00, 0x00, 0x00, 0x00};
-
- iLeafRowid = FTS5_SEGMENT_ROWID(iId, pSeg->iTermLeafPgno);
+ Fts5SegIter *pSeg = &pIter->aSeg[i];
+ if( pSeg->pSeg==0 ){
+ /* no-op */
+ }else if( pSeg->pLeaf==0 ){
+ /* All keys from this input segment have been transfered to the output.
+ ** Set both the first and last page-numbers to 0 to indicate that the
+ ** segment is now empty. */
+ pSeg->pSeg->pgnoLast = 0;
+ pSeg->pSeg->pgnoFirst = 0;
+ }else{
+ int iOff = pSeg->iTermLeafOffset; /* Offset on new first leaf page */
+ i64 iLeafRowid;
+ Fts5Data *pData;
+ int iId = pSeg->pSeg->iSegid;
+ u8 aHdr[4] = {0x00, 0x00, 0x00, 0x00};
+
+ iLeafRowid = FTS5_SEGMENT_ROWID(iId, pSeg->iTermLeafPgno);
pData = fts5LeafRead(p, iLeafRowid);
- if( pData ){
+ if( pData ){
if( iOff>pData->szLeaf ){
/* This can occur if the pages that the segments occupy overlap - if
** a single page has been assigned to more than one segment. In
@@ -227183,7 +227183,7 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
/* Set the szLeaf field */
fts5PutU16(&buf.p[2], (u16)buf.n);
}
-
+
/* Set up the new page-index array */
fts5BufferAppendVarint(&p->rc, &buf, 4);
if( pSeg->iLeafPgno==pSeg->iTermLeafPgno
@@ -227200,753 +227200,753 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
pSeg->pSeg->pgnoFirst = pSeg->iTermLeafPgno;
fts5DataDelete(p, FTS5_SEGMENT_ROWID(iId, 1), iLeafRowid);
fts5DataWrite(p, iLeafRowid, buf.p, buf.n);
- }
- fts5DataRelease(pData);
- }
- }
- }
- fts5BufferFree(&buf);
-}
-
-static void fts5MergeChunkCallback(
+ }
+ fts5DataRelease(pData);
+ }
+ }
+ }
+ fts5BufferFree(&buf);
+}
+
+static void fts5MergeChunkCallback(
Fts5Index *p,
void *pCtx,
- const u8 *pChunk, int nChunk
-){
- Fts5SegWriter *pWriter = (Fts5SegWriter*)pCtx;
- fts5WriteAppendPoslistData(p, pWriter, pChunk, nChunk);
-}
-
-/*
-**
-*/
-static void fts5IndexMergeLevel(
- Fts5Index *p, /* FTS5 backend object */
- Fts5Structure **ppStruct, /* IN/OUT: Stucture of index */
- int iLvl, /* Level to read input from */
- int *pnRem /* Write up to this many output leaves */
-){
- Fts5Structure *pStruct = *ppStruct;
- Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
- Fts5StructureLevel *pLvlOut;
- Fts5Iter *pIter = 0; /* Iterator to read input data */
- int nRem = pnRem ? *pnRem : 0; /* Output leaf pages left to write */
- int nInput; /* Number of input segments */
- Fts5SegWriter writer; /* Writer object */
- Fts5StructureSegment *pSeg; /* Output segment */
- Fts5Buffer term;
- int bOldest; /* True if the output segment is the oldest */
- int eDetail = p->pConfig->eDetail;
- const int flags = FTS5INDEX_QUERY_NOOUTPUT;
- int bTermWritten = 0; /* True if current term already output */
-
- assert( iLvl<pStruct->nLevel );
- assert( pLvl->nMerge<=pLvl->nSeg );
-
- memset(&writer, 0, sizeof(Fts5SegWriter));
- memset(&term, 0, sizeof(Fts5Buffer));
- if( pLvl->nMerge ){
- pLvlOut = &pStruct->aLevel[iLvl+1];
- assert( pLvlOut->nSeg>0 );
- nInput = pLvl->nMerge;
- pSeg = &pLvlOut->aSeg[pLvlOut->nSeg-1];
-
- fts5WriteInit(p, &writer, pSeg->iSegid);
- writer.writer.pgno = pSeg->pgnoLast+1;
- writer.iBtPage = 0;
- }else{
- int iSegid = fts5AllocateSegid(p, pStruct);
-
- /* Extend the Fts5Structure object as required to ensure the output
- ** segment exists. */
- if( iLvl==pStruct->nLevel-1 ){
- fts5StructureAddLevel(&p->rc, ppStruct);
- pStruct = *ppStruct;
- }
- fts5StructureExtendLevel(&p->rc, pStruct, iLvl+1, 1, 0);
- if( p->rc ) return;
- pLvl = &pStruct->aLevel[iLvl];
- pLvlOut = &pStruct->aLevel[iLvl+1];
-
- fts5WriteInit(p, &writer, iSegid);
-
- /* Add the new segment to the output level */
- pSeg = &pLvlOut->aSeg[pLvlOut->nSeg];
- pLvlOut->nSeg++;
- pSeg->pgnoFirst = 1;
- pSeg->iSegid = iSegid;
- pStruct->nSegment++;
-
- /* Read input from all segments in the input level */
- nInput = pLvl->nSeg;
- }
- bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2);
-
- assert( iLvl>=0 );
- for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, iLvl, nInput, &pIter);
- fts5MultiIterEof(p, pIter)==0;
- fts5MultiIterNext(p, pIter, 0, 0)
- ){
- Fts5SegIter *pSegIter = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
- int nPos; /* position-list size field value */
- int nTerm;
- const u8 *pTerm;
-
- pTerm = fts5MultiIterTerm(pIter, &nTerm);
+ const u8 *pChunk, int nChunk
+){
+ Fts5SegWriter *pWriter = (Fts5SegWriter*)pCtx;
+ fts5WriteAppendPoslistData(p, pWriter, pChunk, nChunk);
+}
+
+/*
+**
+*/
+static void fts5IndexMergeLevel(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5Structure **ppStruct, /* IN/OUT: Stucture of index */
+ int iLvl, /* Level to read input from */
+ int *pnRem /* Write up to this many output leaves */
+){
+ Fts5Structure *pStruct = *ppStruct;
+ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
+ Fts5StructureLevel *pLvlOut;
+ Fts5Iter *pIter = 0; /* Iterator to read input data */
+ int nRem = pnRem ? *pnRem : 0; /* Output leaf pages left to write */
+ int nInput; /* Number of input segments */
+ Fts5SegWriter writer; /* Writer object */
+ Fts5StructureSegment *pSeg; /* Output segment */
+ Fts5Buffer term;
+ int bOldest; /* True if the output segment is the oldest */
+ int eDetail = p->pConfig->eDetail;
+ const int flags = FTS5INDEX_QUERY_NOOUTPUT;
+ int bTermWritten = 0; /* True if current term already output */
+
+ assert( iLvl<pStruct->nLevel );
+ assert( pLvl->nMerge<=pLvl->nSeg );
+
+ memset(&writer, 0, sizeof(Fts5SegWriter));
+ memset(&term, 0, sizeof(Fts5Buffer));
+ if( pLvl->nMerge ){
+ pLvlOut = &pStruct->aLevel[iLvl+1];
+ assert( pLvlOut->nSeg>0 );
+ nInput = pLvl->nMerge;
+ pSeg = &pLvlOut->aSeg[pLvlOut->nSeg-1];
+
+ fts5WriteInit(p, &writer, pSeg->iSegid);
+ writer.writer.pgno = pSeg->pgnoLast+1;
+ writer.iBtPage = 0;
+ }else{
+ int iSegid = fts5AllocateSegid(p, pStruct);
+
+ /* Extend the Fts5Structure object as required to ensure the output
+ ** segment exists. */
+ if( iLvl==pStruct->nLevel-1 ){
+ fts5StructureAddLevel(&p->rc, ppStruct);
+ pStruct = *ppStruct;
+ }
+ fts5StructureExtendLevel(&p->rc, pStruct, iLvl+1, 1, 0);
+ if( p->rc ) return;
+ pLvl = &pStruct->aLevel[iLvl];
+ pLvlOut = &pStruct->aLevel[iLvl+1];
+
+ fts5WriteInit(p, &writer, iSegid);
+
+ /* Add the new segment to the output level */
+ pSeg = &pLvlOut->aSeg[pLvlOut->nSeg];
+ pLvlOut->nSeg++;
+ pSeg->pgnoFirst = 1;
+ pSeg->iSegid = iSegid;
+ pStruct->nSegment++;
+
+ /* Read input from all segments in the input level */
+ nInput = pLvl->nSeg;
+ }
+ bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2);
+
+ assert( iLvl>=0 );
+ for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, iLvl, nInput, &pIter);
+ fts5MultiIterEof(p, pIter)==0;
+ fts5MultiIterNext(p, pIter, 0, 0)
+ ){
+ Fts5SegIter *pSegIter = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ int nPos; /* position-list size field value */
+ int nTerm;
+ const u8 *pTerm;
+
+ pTerm = fts5MultiIterTerm(pIter, &nTerm);
if( nTerm!=term.n || fts5Memcmp(pTerm, term.p, nTerm) ){
- if( pnRem && writer.nLeafWritten>nRem ){
- break;
- }
- fts5BufferSet(&p->rc, &term, nTerm, pTerm);
- bTermWritten =0;
- }
-
- /* Check for key annihilation. */
- if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
-
- if( p->rc==SQLITE_OK && bTermWritten==0 ){
- /* This is a new term. Append a term to the output segment. */
- fts5WriteAppendTerm(p, &writer, nTerm, pTerm);
- bTermWritten = 1;
- }
-
- /* Append the rowid to the output */
- /* WRITEPOSLISTSIZE */
- fts5WriteAppendRowid(p, &writer, fts5MultiIterRowid(pIter));
-
- if( eDetail==FTS5_DETAIL_NONE ){
- if( pSegIter->bDel ){
- fts5BufferAppendVarint(&p->rc, &writer.writer.buf, 0);
- if( pSegIter->nPos>0 ){
- fts5BufferAppendVarint(&p->rc, &writer.writer.buf, 0);
- }
- }
- }else{
- /* Append the position-list data to the output */
- nPos = pSegIter->nPos*2 + pSegIter->bDel;
- fts5BufferAppendVarint(&p->rc, &writer.writer.buf, nPos);
- fts5ChunkIterate(p, pSegIter, (void*)&writer, fts5MergeChunkCallback);
- }
- }
-
- /* Flush the last leaf page to disk. Set the output segment b-tree height
- ** and last leaf page number at the same time. */
- fts5WriteFinish(p, &writer, &pSeg->pgnoLast);
-
+ if( pnRem && writer.nLeafWritten>nRem ){
+ break;
+ }
+ fts5BufferSet(&p->rc, &term, nTerm, pTerm);
+ bTermWritten =0;
+ }
+
+ /* Check for key annihilation. */
+ if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
+
+ if( p->rc==SQLITE_OK && bTermWritten==0 ){
+ /* This is a new term. Append a term to the output segment. */
+ fts5WriteAppendTerm(p, &writer, nTerm, pTerm);
+ bTermWritten = 1;
+ }
+
+ /* Append the rowid to the output */
+ /* WRITEPOSLISTSIZE */
+ fts5WriteAppendRowid(p, &writer, fts5MultiIterRowid(pIter));
+
+ if( eDetail==FTS5_DETAIL_NONE ){
+ if( pSegIter->bDel ){
+ fts5BufferAppendVarint(&p->rc, &writer.writer.buf, 0);
+ if( pSegIter->nPos>0 ){
+ fts5BufferAppendVarint(&p->rc, &writer.writer.buf, 0);
+ }
+ }
+ }else{
+ /* Append the position-list data to the output */
+ nPos = pSegIter->nPos*2 + pSegIter->bDel;
+ fts5BufferAppendVarint(&p->rc, &writer.writer.buf, nPos);
+ fts5ChunkIterate(p, pSegIter, (void*)&writer, fts5MergeChunkCallback);
+ }
+ }
+
+ /* Flush the last leaf page to disk. Set the output segment b-tree height
+ ** and last leaf page number at the same time. */
+ fts5WriteFinish(p, &writer, &pSeg->pgnoLast);
+
assert( pIter!=0 || p->rc!=SQLITE_OK );
- if( fts5MultiIterEof(p, pIter) ){
- int i;
-
- /* Remove the redundant segments from the %_data table */
- for(i=0; i<nInput; i++){
- fts5DataRemoveSegment(p, pLvl->aSeg[i].iSegid);
- }
-
- /* Remove the redundant segments from the input level */
- if( pLvl->nSeg!=nInput ){
- int nMove = (pLvl->nSeg - nInput) * sizeof(Fts5StructureSegment);
- memmove(pLvl->aSeg, &pLvl->aSeg[nInput], nMove);
- }
- pStruct->nSegment -= nInput;
- pLvl->nSeg -= nInput;
- pLvl->nMerge = 0;
- if( pSeg->pgnoLast==0 ){
- pLvlOut->nSeg--;
- pStruct->nSegment--;
- }
- }else{
- assert( pSeg->pgnoLast>0 );
- fts5TrimSegments(p, pIter);
- pLvl->nMerge = nInput;
- }
-
- fts5MultiIterFree(pIter);
- fts5BufferFree(&term);
- if( pnRem ) *pnRem -= writer.nLeafWritten;
-}
-
-/*
-** Do up to nPg pages of automerge work on the index.
-**
-** Return true if any changes were actually made, or false otherwise.
-*/
-static int fts5IndexMerge(
- Fts5Index *p, /* FTS5 backend object */
- Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
- int nPg, /* Pages of work to do */
- int nMin /* Minimum number of segments to merge */
-){
- int nRem = nPg;
- int bRet = 0;
- Fts5Structure *pStruct = *ppStruct;
- while( nRem>0 && p->rc==SQLITE_OK ){
- int iLvl; /* To iterate through levels */
- int iBestLvl = 0; /* Level offering the most input segments */
- int nBest = 0; /* Number of input segments on best level */
-
- /* Set iBestLvl to the level to read input segments from. */
- assert( pStruct->nLevel>0 );
- for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
- Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
- if( pLvl->nMerge ){
- if( pLvl->nMerge>nBest ){
- iBestLvl = iLvl;
- nBest = pLvl->nMerge;
- }
- break;
- }
- if( pLvl->nSeg>nBest ){
- nBest = pLvl->nSeg;
- iBestLvl = iLvl;
- }
- }
-
- /* If nBest is still 0, then the index must be empty. */
-#ifdef SQLITE_DEBUG
- for(iLvl=0; nBest==0 && iLvl<pStruct->nLevel; iLvl++){
- assert( pStruct->aLevel[iLvl].nSeg==0 );
- }
-#endif
-
- if( nBest<nMin && pStruct->aLevel[iBestLvl].nMerge==0 ){
- break;
- }
- bRet = 1;
- fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem);
- if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){
- fts5StructurePromote(p, iBestLvl+1, pStruct);
- }
- }
- *ppStruct = pStruct;
- return bRet;
-}
-
-/*
-** A total of nLeaf leaf pages of data has just been flushed to a level-0
-** segment. This function updates the write-counter accordingly and, if
-** necessary, performs incremental merge work.
-**
+ if( fts5MultiIterEof(p, pIter) ){
+ int i;
+
+ /* Remove the redundant segments from the %_data table */
+ for(i=0; i<nInput; i++){
+ fts5DataRemoveSegment(p, pLvl->aSeg[i].iSegid);
+ }
+
+ /* Remove the redundant segments from the input level */
+ if( pLvl->nSeg!=nInput ){
+ int nMove = (pLvl->nSeg - nInput) * sizeof(Fts5StructureSegment);
+ memmove(pLvl->aSeg, &pLvl->aSeg[nInput], nMove);
+ }
+ pStruct->nSegment -= nInput;
+ pLvl->nSeg -= nInput;
+ pLvl->nMerge = 0;
+ if( pSeg->pgnoLast==0 ){
+ pLvlOut->nSeg--;
+ pStruct->nSegment--;
+ }
+ }else{
+ assert( pSeg->pgnoLast>0 );
+ fts5TrimSegments(p, pIter);
+ pLvl->nMerge = nInput;
+ }
+
+ fts5MultiIterFree(pIter);
+ fts5BufferFree(&term);
+ if( pnRem ) *pnRem -= writer.nLeafWritten;
+}
+
+/*
+** Do up to nPg pages of automerge work on the index.
+**
+** Return true if any changes were actually made, or false otherwise.
+*/
+static int fts5IndexMerge(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
+ int nPg, /* Pages of work to do */
+ int nMin /* Minimum number of segments to merge */
+){
+ int nRem = nPg;
+ int bRet = 0;
+ Fts5Structure *pStruct = *ppStruct;
+ while( nRem>0 && p->rc==SQLITE_OK ){
+ int iLvl; /* To iterate through levels */
+ int iBestLvl = 0; /* Level offering the most input segments */
+ int nBest = 0; /* Number of input segments on best level */
+
+ /* Set iBestLvl to the level to read input segments from. */
+ assert( pStruct->nLevel>0 );
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
+ if( pLvl->nMerge ){
+ if( pLvl->nMerge>nBest ){
+ iBestLvl = iLvl;
+ nBest = pLvl->nMerge;
+ }
+ break;
+ }
+ if( pLvl->nSeg>nBest ){
+ nBest = pLvl->nSeg;
+ iBestLvl = iLvl;
+ }
+ }
+
+ /* If nBest is still 0, then the index must be empty. */
+#ifdef SQLITE_DEBUG
+ for(iLvl=0; nBest==0 && iLvl<pStruct->nLevel; iLvl++){
+ assert( pStruct->aLevel[iLvl].nSeg==0 );
+ }
+#endif
+
+ if( nBest<nMin && pStruct->aLevel[iBestLvl].nMerge==0 ){
+ break;
+ }
+ bRet = 1;
+ fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem);
+ if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){
+ fts5StructurePromote(p, iBestLvl+1, pStruct);
+ }
+ }
+ *ppStruct = pStruct;
+ return bRet;
+}
+
+/*
+** A total of nLeaf leaf pages of data has just been flushed to a level-0
+** segment. This function updates the write-counter accordingly and, if
+** necessary, performs incremental merge work.
+**
** If an error occurs, set the Fts5Index.rc error code. If an error has
-** already occurred, this function is a no-op.
-*/
-static void fts5IndexAutomerge(
- Fts5Index *p, /* FTS5 backend object */
- Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
- int nLeaf /* Number of output leaves just written */
-){
+** already occurred, this function is a no-op.
+*/
+static void fts5IndexAutomerge(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
+ int nLeaf /* Number of output leaves just written */
+){
if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 && ALWAYS((*ppStruct)!=0) ){
- Fts5Structure *pStruct = *ppStruct;
- u64 nWrite; /* Initial value of write-counter */
- int nWork; /* Number of work-quanta to perform */
- int nRem; /* Number of leaf pages left to write */
-
- /* Update the write-counter. While doing so, set nWork. */
- nWrite = pStruct->nWriteCounter;
- nWork = (int)(((nWrite + nLeaf) / p->nWorkUnit) - (nWrite / p->nWorkUnit));
- pStruct->nWriteCounter += nLeaf;
- nRem = (int)(p->nWorkUnit * nWork * pStruct->nLevel);
-
- fts5IndexMerge(p, ppStruct, nRem, p->pConfig->nAutomerge);
- }
-}
-
-static void fts5IndexCrisismerge(
- Fts5Index *p, /* FTS5 backend object */
- Fts5Structure **ppStruct /* IN/OUT: Current structure of index */
-){
- const int nCrisis = p->pConfig->nCrisisMerge;
- Fts5Structure *pStruct = *ppStruct;
- int iLvl = 0;
-
- assert( p->rc!=SQLITE_OK || pStruct->nLevel>0 );
- while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){
- fts5IndexMergeLevel(p, &pStruct, iLvl, 0);
- assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) );
- fts5StructurePromote(p, iLvl+1, pStruct);
- iLvl++;
- }
- *ppStruct = pStruct;
-}
-
-static int fts5IndexReturn(Fts5Index *p){
- int rc = p->rc;
- p->rc = SQLITE_OK;
- return rc;
-}
-
-typedef struct Fts5FlushCtx Fts5FlushCtx;
-struct Fts5FlushCtx {
- Fts5Index *pIdx;
+ Fts5Structure *pStruct = *ppStruct;
+ u64 nWrite; /* Initial value of write-counter */
+ int nWork; /* Number of work-quanta to perform */
+ int nRem; /* Number of leaf pages left to write */
+
+ /* Update the write-counter. While doing so, set nWork. */
+ nWrite = pStruct->nWriteCounter;
+ nWork = (int)(((nWrite + nLeaf) / p->nWorkUnit) - (nWrite / p->nWorkUnit));
+ pStruct->nWriteCounter += nLeaf;
+ nRem = (int)(p->nWorkUnit * nWork * pStruct->nLevel);
+
+ fts5IndexMerge(p, ppStruct, nRem, p->pConfig->nAutomerge);
+ }
+}
+
+static void fts5IndexCrisismerge(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5Structure **ppStruct /* IN/OUT: Current structure of index */
+){
+ const int nCrisis = p->pConfig->nCrisisMerge;
+ Fts5Structure *pStruct = *ppStruct;
+ int iLvl = 0;
+
+ assert( p->rc!=SQLITE_OK || pStruct->nLevel>0 );
+ while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){
+ fts5IndexMergeLevel(p, &pStruct, iLvl, 0);
+ assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) );
+ fts5StructurePromote(p, iLvl+1, pStruct);
+ iLvl++;
+ }
+ *ppStruct = pStruct;
+}
+
+static int fts5IndexReturn(Fts5Index *p){
+ int rc = p->rc;
+ p->rc = SQLITE_OK;
+ return rc;
+}
+
+typedef struct Fts5FlushCtx Fts5FlushCtx;
+struct Fts5FlushCtx {
+ Fts5Index *pIdx;
Fts5SegWriter writer;
-};
-
-/*
-** Buffer aBuf[] contains a list of varints, all small enough to fit
+};
+
+/*
+** Buffer aBuf[] contains a list of varints, all small enough to fit
** in a 32-bit integer. Return the size of the largest prefix of this
-** list nMax bytes or less in size.
-*/
-static int fts5PoslistPrefix(const u8 *aBuf, int nMax){
- int ret;
- u32 dummy;
- ret = fts5GetVarint32(aBuf, dummy);
- if( ret<nMax ){
- while( 1 ){
- int i = fts5GetVarint32(&aBuf[ret], dummy);
- if( (ret + i) > nMax ) break;
- ret += i;
- }
- }
- return ret;
-}
-
-/*
+** list nMax bytes or less in size.
+*/
+static int fts5PoslistPrefix(const u8 *aBuf, int nMax){
+ int ret;
+ u32 dummy;
+ ret = fts5GetVarint32(aBuf, dummy);
+ if( ret<nMax ){
+ while( 1 ){
+ int i = fts5GetVarint32(&aBuf[ret], dummy);
+ if( (ret + i) > nMax ) break;
+ ret += i;
+ }
+ }
+ return ret;
+}
+
+/*
** Flush the contents of in-memory hash table iHash to a new level-0
-** segment on disk. Also update the corresponding structure record.
-**
+** segment on disk. Also update the corresponding structure record.
+**
** If an error occurs, set the Fts5Index.rc error code. If an error has
-** already occurred, this function is a no-op.
-*/
-static void fts5FlushOneHash(Fts5Index *p){
- Fts5Hash *pHash = p->pHash;
- Fts5Structure *pStruct;
- int iSegid;
- int pgnoLast = 0; /* Last leaf page number in segment */
-
- /* Obtain a reference to the index structure and allocate a new segment-id
- ** for the new level-0 segment. */
- pStruct = fts5StructureRead(p);
- iSegid = fts5AllocateSegid(p, pStruct);
- fts5StructureInvalidate(p);
-
- if( iSegid ){
- const int pgsz = p->pConfig->pgsz;
- int eDetail = p->pConfig->eDetail;
- Fts5StructureSegment *pSeg; /* New segment within pStruct */
- Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */
- Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */
-
- Fts5SegWriter writer;
- fts5WriteInit(p, &writer, iSegid);
-
- pBuf = &writer.writer.buf;
- pPgidx = &writer.writer.pgidx;
-
- /* fts5WriteInit() should have initialized the buffers to (most likely)
- ** the maximum space required. */
- assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) );
- assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) );
-
- /* Begin scanning through hash table entries. This loop runs once for each
- ** term/doclist currently stored within the hash table. */
- if( p->rc==SQLITE_OK ){
- p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0);
- }
- while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){
- const char *zTerm; /* Buffer containing term */
- const u8 *pDoclist; /* Pointer to doclist for this term */
- int nDoclist; /* Size of doclist in bytes */
-
- /* Write the term for this entry to disk. */
- sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
- fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm);
+** already occurred, this function is a no-op.
+*/
+static void fts5FlushOneHash(Fts5Index *p){
+ Fts5Hash *pHash = p->pHash;
+ Fts5Structure *pStruct;
+ int iSegid;
+ int pgnoLast = 0; /* Last leaf page number in segment */
+
+ /* Obtain a reference to the index structure and allocate a new segment-id
+ ** for the new level-0 segment. */
+ pStruct = fts5StructureRead(p);
+ iSegid = fts5AllocateSegid(p, pStruct);
+ fts5StructureInvalidate(p);
+
+ if( iSegid ){
+ const int pgsz = p->pConfig->pgsz;
+ int eDetail = p->pConfig->eDetail;
+ Fts5StructureSegment *pSeg; /* New segment within pStruct */
+ Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */
+ Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */
+
+ Fts5SegWriter writer;
+ fts5WriteInit(p, &writer, iSegid);
+
+ pBuf = &writer.writer.buf;
+ pPgidx = &writer.writer.pgidx;
+
+ /* fts5WriteInit() should have initialized the buffers to (most likely)
+ ** the maximum space required. */
+ assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) );
+ assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) );
+
+ /* Begin scanning through hash table entries. This loop runs once for each
+ ** term/doclist currently stored within the hash table. */
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0);
+ }
+ while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){
+ const char *zTerm; /* Buffer containing term */
+ const u8 *pDoclist; /* Pointer to doclist for this term */
+ int nDoclist; /* Size of doclist in bytes */
+
+ /* Write the term for this entry to disk. */
+ sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
+ fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm);
if( p->rc!=SQLITE_OK ) break;
-
- assert( writer.bFirstRowidInPage==0 );
- if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
- /* The entire doclist will fit on the current leaf. */
- fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist);
- }else{
- i64 iRowid = 0;
+
+ assert( writer.bFirstRowidInPage==0 );
+ if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
+ /* The entire doclist will fit on the current leaf. */
+ fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist);
+ }else{
+ i64 iRowid = 0;
u64 iDelta = 0;
- int iOff = 0;
-
+ int iOff = 0;
+
/* The entire doclist will not fit on this leaf. The following
** loop iterates through the poslists that make up the current
- ** doclist. */
- while( p->rc==SQLITE_OK && iOff<nDoclist ){
+ ** doclist. */
+ while( p->rc==SQLITE_OK && iOff<nDoclist ){
iOff += fts5GetVarint(&pDoclist[iOff], &iDelta);
- iRowid += iDelta;
+ iRowid += iDelta;
- if( writer.bFirstRowidInPage ){
- fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */
- pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
- writer.bFirstRowidInPage = 0;
- fts5WriteDlidxAppend(p, &writer, iRowid);
+ if( writer.bFirstRowidInPage ){
+ fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */
+ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
+ writer.bFirstRowidInPage = 0;
+ fts5WriteDlidxAppend(p, &writer, iRowid);
if( p->rc!=SQLITE_OK ) break;
- }else{
- pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta);
- }
- assert( pBuf->n<=pBuf->nSpace );
-
- if( eDetail==FTS5_DETAIL_NONE ){
- if( iOff<nDoclist && pDoclist[iOff]==0 ){
- pBuf->p[pBuf->n++] = 0;
- iOff++;
- if( iOff<nDoclist && pDoclist[iOff]==0 ){
- pBuf->p[pBuf->n++] = 0;
- iOff++;
- }
- }
- if( (pBuf->n + pPgidx->n)>=pgsz ){
- fts5WriteFlushLeaf(p, &writer);
- }
- }else{
- int bDummy;
- int nPos;
- int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy);
- nCopy += nPos;
- if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){
- /* The entire poslist will fit on the current leaf. So copy
- ** it in one go. */
- fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy);
- }else{
- /* The entire poslist will not fit on this leaf. So it needs
- ** to be broken into sections. The only qualification being
- ** that each varint must be stored contiguously. */
- const u8 *pPoslist = &pDoclist[iOff];
- int iPos = 0;
- while( p->rc==SQLITE_OK ){
- int nSpace = pgsz - pBuf->n - pPgidx->n;
- int n = 0;
- if( (nCopy - iPos)<=nSpace ){
- n = nCopy - iPos;
- }else{
- n = fts5PoslistPrefix(&pPoslist[iPos], nSpace);
- }
- assert( n>0 );
- fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n);
- iPos += n;
- if( (pBuf->n + pPgidx->n)>=pgsz ){
- fts5WriteFlushLeaf(p, &writer);
- }
- if( iPos>=nCopy ) break;
- }
- }
- iOff += nCopy;
- }
- }
- }
-
- /* TODO2: Doclist terminator written here. */
- /* pBuf->p[pBuf->n++] = '\0'; */
- assert( pBuf->n<=pBuf->nSpace );
+ }else{
+ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta);
+ }
+ assert( pBuf->n<=pBuf->nSpace );
+
+ if( eDetail==FTS5_DETAIL_NONE ){
+ if( iOff<nDoclist && pDoclist[iOff]==0 ){
+ pBuf->p[pBuf->n++] = 0;
+ iOff++;
+ if( iOff<nDoclist && pDoclist[iOff]==0 ){
+ pBuf->p[pBuf->n++] = 0;
+ iOff++;
+ }
+ }
+ if( (pBuf->n + pPgidx->n)>=pgsz ){
+ fts5WriteFlushLeaf(p, &writer);
+ }
+ }else{
+ int bDummy;
+ int nPos;
+ int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy);
+ nCopy += nPos;
+ if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){
+ /* The entire poslist will fit on the current leaf. So copy
+ ** it in one go. */
+ fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy);
+ }else{
+ /* The entire poslist will not fit on this leaf. So it needs
+ ** to be broken into sections. The only qualification being
+ ** that each varint must be stored contiguously. */
+ const u8 *pPoslist = &pDoclist[iOff];
+ int iPos = 0;
+ while( p->rc==SQLITE_OK ){
+ int nSpace = pgsz - pBuf->n - pPgidx->n;
+ int n = 0;
+ if( (nCopy - iPos)<=nSpace ){
+ n = nCopy - iPos;
+ }else{
+ n = fts5PoslistPrefix(&pPoslist[iPos], nSpace);
+ }
+ assert( n>0 );
+ fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n);
+ iPos += n;
+ if( (pBuf->n + pPgidx->n)>=pgsz ){
+ fts5WriteFlushLeaf(p, &writer);
+ }
+ if( iPos>=nCopy ) break;
+ }
+ }
+ iOff += nCopy;
+ }
+ }
+ }
+
+ /* TODO2: Doclist terminator written here. */
+ /* pBuf->p[pBuf->n++] = '\0'; */
+ assert( pBuf->n<=pBuf->nSpace );
if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash);
- }
- sqlite3Fts5HashClear(pHash);
- fts5WriteFinish(p, &writer, &pgnoLast);
-
- /* Update the Fts5Structure. It is written back to the database by the
- ** fts5StructureRelease() call below. */
- if( pStruct->nLevel==0 ){
- fts5StructureAddLevel(&p->rc, &pStruct);
- }
- fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0);
- if( p->rc==SQLITE_OK ){
- pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ];
- pSeg->iSegid = iSegid;
- pSeg->pgnoFirst = 1;
- pSeg->pgnoLast = pgnoLast;
- pStruct->nSegment++;
- }
- fts5StructurePromote(p, 0, pStruct);
- }
-
- fts5IndexAutomerge(p, &pStruct, pgnoLast);
- fts5IndexCrisismerge(p, &pStruct);
- fts5StructureWrite(p, pStruct);
- fts5StructureRelease(pStruct);
-}
-
-/*
-** Flush any data stored in the in-memory hash tables to the database.
-*/
-static void fts5IndexFlush(Fts5Index *p){
- /* Unless it is empty, flush the hash table to disk */
- if( p->nPendingData ){
- assert( p->pHash );
- p->nPendingData = 0;
- fts5FlushOneHash(p);
- }
-}
-
-static Fts5Structure *fts5IndexOptimizeStruct(
+ }
+ sqlite3Fts5HashClear(pHash);
+ fts5WriteFinish(p, &writer, &pgnoLast);
+
+ /* Update the Fts5Structure. It is written back to the database by the
+ ** fts5StructureRelease() call below. */
+ if( pStruct->nLevel==0 ){
+ fts5StructureAddLevel(&p->rc, &pStruct);
+ }
+ fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0);
+ if( p->rc==SQLITE_OK ){
+ pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ];
+ pSeg->iSegid = iSegid;
+ pSeg->pgnoFirst = 1;
+ pSeg->pgnoLast = pgnoLast;
+ pStruct->nSegment++;
+ }
+ fts5StructurePromote(p, 0, pStruct);
+ }
+
+ fts5IndexAutomerge(p, &pStruct, pgnoLast);
+ fts5IndexCrisismerge(p, &pStruct);
+ fts5StructureWrite(p, pStruct);
+ fts5StructureRelease(pStruct);
+}
+
+/*
+** Flush any data stored in the in-memory hash tables to the database.
+*/
+static void fts5IndexFlush(Fts5Index *p){
+ /* Unless it is empty, flush the hash table to disk */
+ if( p->nPendingData ){
+ assert( p->pHash );
+ p->nPendingData = 0;
+ fts5FlushOneHash(p);
+ }
+}
+
+static Fts5Structure *fts5IndexOptimizeStruct(
Fts5Index *p,
- Fts5Structure *pStruct
-){
- Fts5Structure *pNew = 0;
+ Fts5Structure *pStruct
+){
+ Fts5Structure *pNew = 0;
sqlite3_int64 nByte = sizeof(Fts5Structure);
- int nSeg = pStruct->nSegment;
- int i;
-
- /* Figure out if this structure requires optimization. A structure does
- ** not require optimization if either:
- **
+ int nSeg = pStruct->nSegment;
+ int i;
+
+ /* Figure out if this structure requires optimization. A structure does
+ ** not require optimization if either:
+ **
** + it consists of fewer than two segments, or
- ** + all segments are on the same level, or
- ** + all segments except one are currently inputs to a merge operation.
- **
- ** In the first case, return NULL. In the second, increment the ref-count
- ** on *pStruct and return a copy of the pointer to it.
- */
- if( nSeg<2 ) return 0;
- for(i=0; i<pStruct->nLevel; i++){
- int nThis = pStruct->aLevel[i].nSeg;
- if( nThis==nSeg || (nThis==nSeg-1 && pStruct->aLevel[i].nMerge==nThis) ){
- fts5StructureRef(pStruct);
- return pStruct;
- }
- assert( pStruct->aLevel[i].nMerge<=nThis );
- }
-
- nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel);
- pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
-
- if( pNew ){
- Fts5StructureLevel *pLvl;
- nByte = nSeg * sizeof(Fts5StructureSegment);
- pNew->nLevel = pStruct->nLevel+1;
- pNew->nRef = 1;
- pNew->nWriteCounter = pStruct->nWriteCounter;
- pLvl = &pNew->aLevel[pStruct->nLevel];
- pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte);
- if( pLvl->aSeg ){
- int iLvl, iSeg;
- int iSegOut = 0;
- /* Iterate through all segments, from oldest to newest. Add them to
- ** the new Fts5Level object so that pLvl->aSeg[0] is the oldest
- ** segment in the data structure. */
- for(iLvl=pStruct->nLevel-1; iLvl>=0; iLvl--){
- for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
- pLvl->aSeg[iSegOut] = pStruct->aLevel[iLvl].aSeg[iSeg];
- iSegOut++;
- }
- }
- pNew->nSegment = pLvl->nSeg = nSeg;
- }else{
- sqlite3_free(pNew);
- pNew = 0;
- }
- }
-
- return pNew;
-}
-
-static int sqlite3Fts5IndexOptimize(Fts5Index *p){
- Fts5Structure *pStruct;
- Fts5Structure *pNew = 0;
-
- assert( p->rc==SQLITE_OK );
- fts5IndexFlush(p);
- pStruct = fts5StructureRead(p);
- fts5StructureInvalidate(p);
-
- if( pStruct ){
- pNew = fts5IndexOptimizeStruct(p, pStruct);
- }
- fts5StructureRelease(pStruct);
-
- assert( pNew==0 || pNew->nSegment>0 );
- if( pNew ){
- int iLvl;
- for(iLvl=0; pNew->aLevel[iLvl].nSeg==0; iLvl++){}
- while( p->rc==SQLITE_OK && pNew->aLevel[iLvl].nSeg>0 ){
- int nRem = FTS5_OPT_WORK_UNIT;
- fts5IndexMergeLevel(p, &pNew, iLvl, &nRem);
- }
-
- fts5StructureWrite(p, pNew);
- fts5StructureRelease(pNew);
- }
-
+ ** + all segments are on the same level, or
+ ** + all segments except one are currently inputs to a merge operation.
+ **
+ ** In the first case, return NULL. In the second, increment the ref-count
+ ** on *pStruct and return a copy of the pointer to it.
+ */
+ if( nSeg<2 ) return 0;
+ for(i=0; i<pStruct->nLevel; i++){
+ int nThis = pStruct->aLevel[i].nSeg;
+ if( nThis==nSeg || (nThis==nSeg-1 && pStruct->aLevel[i].nMerge==nThis) ){
+ fts5StructureRef(pStruct);
+ return pStruct;
+ }
+ assert( pStruct->aLevel[i].nMerge<=nThis );
+ }
+
+ nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel);
+ pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
+
+ if( pNew ){
+ Fts5StructureLevel *pLvl;
+ nByte = nSeg * sizeof(Fts5StructureSegment);
+ pNew->nLevel = pStruct->nLevel+1;
+ pNew->nRef = 1;
+ pNew->nWriteCounter = pStruct->nWriteCounter;
+ pLvl = &pNew->aLevel[pStruct->nLevel];
+ pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte);
+ if( pLvl->aSeg ){
+ int iLvl, iSeg;
+ int iSegOut = 0;
+ /* Iterate through all segments, from oldest to newest. Add them to
+ ** the new Fts5Level object so that pLvl->aSeg[0] is the oldest
+ ** segment in the data structure. */
+ for(iLvl=pStruct->nLevel-1; iLvl>=0; iLvl--){
+ for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
+ pLvl->aSeg[iSegOut] = pStruct->aLevel[iLvl].aSeg[iSeg];
+ iSegOut++;
+ }
+ }
+ pNew->nSegment = pLvl->nSeg = nSeg;
+ }else{
+ sqlite3_free(pNew);
+ pNew = 0;
+ }
+ }
+
+ return pNew;
+}
+
+static int sqlite3Fts5IndexOptimize(Fts5Index *p){
+ Fts5Structure *pStruct;
+ Fts5Structure *pNew = 0;
+
+ assert( p->rc==SQLITE_OK );
+ fts5IndexFlush(p);
+ pStruct = fts5StructureRead(p);
+ fts5StructureInvalidate(p);
+
+ if( pStruct ){
+ pNew = fts5IndexOptimizeStruct(p, pStruct);
+ }
+ fts5StructureRelease(pStruct);
+
+ assert( pNew==0 || pNew->nSegment>0 );
+ if( pNew ){
+ int iLvl;
+ for(iLvl=0; pNew->aLevel[iLvl].nSeg==0; iLvl++){}
+ while( p->rc==SQLITE_OK && pNew->aLevel[iLvl].nSeg>0 ){
+ int nRem = FTS5_OPT_WORK_UNIT;
+ fts5IndexMergeLevel(p, &pNew, iLvl, &nRem);
+ }
+
+ fts5StructureWrite(p, pNew);
+ fts5StructureRelease(pNew);
+ }
+
return fts5IndexReturn(p);
-}
-
-/*
-** This is called to implement the special "VALUES('merge', $nMerge)"
-** INSERT command.
-*/
-static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
- Fts5Structure *pStruct = fts5StructureRead(p);
- if( pStruct ){
- int nMin = p->pConfig->nUsermerge;
- fts5StructureInvalidate(p);
- if( nMerge<0 ){
- Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct);
- fts5StructureRelease(pStruct);
- pStruct = pNew;
- nMin = 2;
- nMerge = nMerge*-1;
- }
- if( pStruct && pStruct->nLevel ){
- if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
- fts5StructureWrite(p, pStruct);
- }
- }
- fts5StructureRelease(pStruct);
- }
- return fts5IndexReturn(p);
-}
-
-static void fts5AppendRowid(
- Fts5Index *p,
- i64 iDelta,
- Fts5Iter *pUnused,
- Fts5Buffer *pBuf
-){
- UNUSED_PARAM(pUnused);
- fts5BufferAppendVarint(&p->rc, pBuf, iDelta);
-}
-
-static void fts5AppendPoslist(
- Fts5Index *p,
- i64 iDelta,
- Fts5Iter *pMulti,
- Fts5Buffer *pBuf
-){
- int nData = pMulti->base.nData;
+}
+
+/*
+** This is called to implement the special "VALUES('merge', $nMerge)"
+** INSERT command.
+*/
+static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
+ Fts5Structure *pStruct = fts5StructureRead(p);
+ if( pStruct ){
+ int nMin = p->pConfig->nUsermerge;
+ fts5StructureInvalidate(p);
+ if( nMerge<0 ){
+ Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct);
+ fts5StructureRelease(pStruct);
+ pStruct = pNew;
+ nMin = 2;
+ nMerge = nMerge*-1;
+ }
+ if( pStruct && pStruct->nLevel ){
+ if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
+ fts5StructureWrite(p, pStruct);
+ }
+ }
+ fts5StructureRelease(pStruct);
+ }
+ return fts5IndexReturn(p);
+}
+
+static void fts5AppendRowid(
+ Fts5Index *p,
+ i64 iDelta,
+ Fts5Iter *pUnused,
+ Fts5Buffer *pBuf
+){
+ UNUSED_PARAM(pUnused);
+ fts5BufferAppendVarint(&p->rc, pBuf, iDelta);
+}
+
+static void fts5AppendPoslist(
+ Fts5Index *p,
+ i64 iDelta,
+ Fts5Iter *pMulti,
+ Fts5Buffer *pBuf
+){
+ int nData = pMulti->base.nData;
int nByte = nData + 9 + 9 + FTS5_DATA_ZERO_PADDING;
- assert( nData>0 );
+ assert( nData>0 );
if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nByte) ){
- fts5BufferSafeAppendVarint(pBuf, iDelta);
- fts5BufferSafeAppendVarint(pBuf, nData*2);
- fts5BufferSafeAppendBlob(pBuf, pMulti->base.pData, nData);
+ fts5BufferSafeAppendVarint(pBuf, iDelta);
+ fts5BufferSafeAppendVarint(pBuf, nData*2);
+ fts5BufferSafeAppendBlob(pBuf, pMulti->base.pData, nData);
memset(&pBuf->p[pBuf->n], 0, FTS5_DATA_ZERO_PADDING);
- }
-}
-
-
-static void fts5DoclistIterNext(Fts5DoclistIter *pIter){
- u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist;
-
+ }
+}
+
+
+static void fts5DoclistIterNext(Fts5DoclistIter *pIter){
+ u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist;
+
assert( pIter->aPoslist || (p==0 && pIter->aPoslist==0) );
- if( p>=pIter->aEof ){
- pIter->aPoslist = 0;
- }else{
- i64 iDelta;
-
- p += fts5GetVarint(p, (u64*)&iDelta);
- pIter->iRowid += iDelta;
-
- /* Read position list size */
- if( p[0] & 0x80 ){
- int nPos;
- pIter->nSize = fts5GetVarint32(p, nPos);
- pIter->nPoslist = (nPos>>1);
- }else{
- pIter->nPoslist = ((int)(p[0])) >> 1;
- pIter->nSize = 1;
- }
-
- pIter->aPoslist = p;
+ if( p>=pIter->aEof ){
+ pIter->aPoslist = 0;
+ }else{
+ i64 iDelta;
+
+ p += fts5GetVarint(p, (u64*)&iDelta);
+ pIter->iRowid += iDelta;
+
+ /* Read position list size */
+ if( p[0] & 0x80 ){
+ int nPos;
+ pIter->nSize = fts5GetVarint32(p, nPos);
+ pIter->nPoslist = (nPos>>1);
+ }else{
+ pIter->nPoslist = ((int)(p[0])) >> 1;
+ pIter->nSize = 1;
+ }
+
+ pIter->aPoslist = p;
if( &pIter->aPoslist[pIter->nPoslist]>pIter->aEof ){
pIter->aPoslist = 0;
}
- }
-}
-
-static void fts5DoclistIterInit(
+ }
+}
+
+static void fts5DoclistIterInit(
Fts5Buffer *pBuf,
- Fts5DoclistIter *pIter
-){
- memset(pIter, 0, sizeof(*pIter));
+ Fts5DoclistIter *pIter
+){
+ memset(pIter, 0, sizeof(*pIter));
if( pBuf->n>0 ){
pIter->aPoslist = pBuf->p;
pIter->aEof = &pBuf->p[pBuf->n];
fts5DoclistIterNext(pIter);
}
-}
-
-#if 0
-/*
-** Append a doclist to buffer pBuf.
-**
-** This function assumes that space within the buffer has already been
-** allocated.
-*/
-static void fts5MergeAppendDocid(
- Fts5Buffer *pBuf, /* Buffer to write to */
- i64 *piLastRowid, /* IN/OUT: Previous rowid written (if any) */
- i64 iRowid /* Rowid to append */
-){
- assert( pBuf->n!=0 || (*piLastRowid)==0 );
- fts5BufferSafeAppendVarint(pBuf, iRowid - *piLastRowid);
- *piLastRowid = iRowid;
-}
-#endif
-
-#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \
- assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \
- fts5BufferSafeAppendVarint((pBuf), (iRowid) - (iLastRowid)); \
- (iLastRowid) = (iRowid); \
-}
-
-/*
-** Swap the contents of buffer *p1 with that of *p2.
-*/
-static void fts5BufferSwap(Fts5Buffer *p1, Fts5Buffer *p2){
- Fts5Buffer tmp = *p1;
- *p1 = *p2;
- *p2 = tmp;
-}
-
-static void fts5NextRowid(Fts5Buffer *pBuf, int *piOff, i64 *piRowid){
- int i = *piOff;
- if( i>=pBuf->n ){
- *piOff = -1;
- }else{
- u64 iVal;
- *piOff = i + sqlite3Fts5GetVarint(&pBuf->p[i], &iVal);
- *piRowid += iVal;
- }
-}
-
-/*
-** This is the equivalent of fts5MergePrefixLists() for detail=none mode.
-** In this case the buffers consist of a delta-encoded list of rowids only.
-*/
-static void fts5MergeRowidLists(
- Fts5Index *p, /* FTS5 backend object */
- Fts5Buffer *p1, /* First list to merge */
+}
+
+#if 0
+/*
+** Append a doclist to buffer pBuf.
+**
+** This function assumes that space within the buffer has already been
+** allocated.
+*/
+static void fts5MergeAppendDocid(
+ Fts5Buffer *pBuf, /* Buffer to write to */
+ i64 *piLastRowid, /* IN/OUT: Previous rowid written (if any) */
+ i64 iRowid /* Rowid to append */
+){
+ assert( pBuf->n!=0 || (*piLastRowid)==0 );
+ fts5BufferSafeAppendVarint(pBuf, iRowid - *piLastRowid);
+ *piLastRowid = iRowid;
+}
+#endif
+
+#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \
+ assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \
+ fts5BufferSafeAppendVarint((pBuf), (iRowid) - (iLastRowid)); \
+ (iLastRowid) = (iRowid); \
+}
+
+/*
+** Swap the contents of buffer *p1 with that of *p2.
+*/
+static void fts5BufferSwap(Fts5Buffer *p1, Fts5Buffer *p2){
+ Fts5Buffer tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+}
+
+static void fts5NextRowid(Fts5Buffer *pBuf, int *piOff, i64 *piRowid){
+ int i = *piOff;
+ if( i>=pBuf->n ){
+ *piOff = -1;
+ }else{
+ u64 iVal;
+ *piOff = i + sqlite3Fts5GetVarint(&pBuf->p[i], &iVal);
+ *piRowid += iVal;
+ }
+}
+
+/*
+** This is the equivalent of fts5MergePrefixLists() for detail=none mode.
+** In this case the buffers consist of a delta-encoded list of rowids only.
+*/
+static void fts5MergeRowidLists(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5Buffer *p1, /* First list to merge */
int nBuf, /* Number of entries in apBuf[] */
Fts5Buffer *aBuf /* Array of other lists to merge into p1 */
-){
- int i1 = 0;
- int i2 = 0;
- i64 iRowid1 = 0;
- i64 iRowid2 = 0;
- i64 iOut = 0;
+){
+ int i1 = 0;
+ int i2 = 0;
+ i64 iRowid1 = 0;
+ i64 iRowid2 = 0;
+ i64 iOut = 0;
Fts5Buffer *p2 = &aBuf[0];
Fts5Buffer out;
-
+
(void)nBuf;
- memset(&out, 0, sizeof(out));
+ memset(&out, 0, sizeof(out));
assert( nBuf==1 );
- sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n);
- if( p->rc ) return;
-
- fts5NextRowid(p1, &i1, &iRowid1);
- fts5NextRowid(p2, &i2, &iRowid2);
- while( i1>=0 || i2>=0 ){
- if( i1>=0 && (i2<0 || iRowid1<iRowid2) ){
- assert( iOut==0 || iRowid1>iOut );
- fts5BufferSafeAppendVarint(&out, iRowid1 - iOut);
- iOut = iRowid1;
- fts5NextRowid(p1, &i1, &iRowid1);
- }else{
- assert( iOut==0 || iRowid2>iOut );
- fts5BufferSafeAppendVarint(&out, iRowid2 - iOut);
- iOut = iRowid2;
- if( i1>=0 && iRowid1==iRowid2 ){
- fts5NextRowid(p1, &i1, &iRowid1);
- }
- fts5NextRowid(p2, &i2, &iRowid2);
- }
- }
-
- fts5BufferSwap(&out, p1);
- fts5BufferFree(&out);
-}
-
+ sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n);
+ if( p->rc ) return;
+
+ fts5NextRowid(p1, &i1, &iRowid1);
+ fts5NextRowid(p2, &i2, &iRowid2);
+ while( i1>=0 || i2>=0 ){
+ if( i1>=0 && (i2<0 || iRowid1<iRowid2) ){
+ assert( iOut==0 || iRowid1>iOut );
+ fts5BufferSafeAppendVarint(&out, iRowid1 - iOut);
+ iOut = iRowid1;
+ fts5NextRowid(p1, &i1, &iRowid1);
+ }else{
+ assert( iOut==0 || iRowid2>iOut );
+ fts5BufferSafeAppendVarint(&out, iRowid2 - iOut);
+ iOut = iRowid2;
+ if( i1>=0 && iRowid1==iRowid2 ){
+ fts5NextRowid(p1, &i1, &iRowid1);
+ }
+ fts5NextRowid(p2, &i2, &iRowid2);
+ }
+ }
+
+ fts5BufferSwap(&out, p1);
+ fts5BufferFree(&out);
+}
+
typedef struct PrefixMerger PrefixMerger;
struct PrefixMerger {
Fts5DoclistIter iter; /* Doclist iterator */
@@ -227985,16 +227985,16 @@ static void fts5PrefixMergerInsertByPosition(
}
-/*
+/*
** Array aBuf[] contains nBuf doclists. These are all merged in with the
** doclist in buffer p1.
-*/
-static void fts5MergePrefixLists(
- Fts5Index *p, /* FTS5 backend object */
- Fts5Buffer *p1, /* First list to merge */
+*/
+static void fts5MergePrefixLists(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5Buffer *p1, /* First list to merge */
int nBuf, /* Number of buffers in array aBuf[] */
Fts5Buffer *aBuf /* Other lists to merge in */
-){
+){
#define fts5PrefixMergerNextPosition(p) \
sqlite3Fts5PoslistNext64((p)->aPos,(p)->iter.nPoslist,&(p)->iOff,&(p)->iPos)
#define FTS5_MERGE_NLIST 16
@@ -228005,7 +228005,7 @@ static void fts5MergePrefixLists(
Fts5Buffer out = {0, 0, 0};
Fts5Buffer tmp = {0, 0, 0};
i64 iLastRowid = 0;
-
+
/* Initialize a doclist-iterator for each input buffer. Arrange them in
** a linked-list starting at pHead in ascending order of rowid. Avoid
** linking any iterators already at EOF into the linked list at all. */
@@ -228020,7 +228020,7 @@ static void fts5MergePrefixLists(
}
if( nOut==0 ) return;
nOut += p1->n + 9 + 10*nBuf;
-
+
/* The maximum size of the output is equal to the sum of the
** input sizes + 1 varint (9 bytes). The extra varint is because if the
** first rowid in one input is a large negative number, and the first in
@@ -228058,13 +228058,13 @@ static void fts5MergePrefixLists(
nMerge++;
fts5PrefixMergerInsertByPosition(&pHead, pSave);
pSave = pNext;
- }
+ }
if( pHead==0 || pHead->pNext==0 ){
p->rc = FTS5_CORRUPT;
break;
- }
-
+ }
+
/* See the earlier comment in this function for an explanation of why
** corrupt input position lists might cause the output to consume
** at most nMerge*10 bytes of unexpected space. */
@@ -228072,28 +228072,28 @@ static void fts5MergePrefixLists(
break;
}
fts5BufferZero(&tmp);
-
+
pThis = pHead;
pHead = pThis->pNext;
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos);
fts5PrefixMergerNextPosition(pThis);
fts5PrefixMergerInsertByPosition(&pHead, pThis);
-
+
while( pHead->pNext ){
pThis = pHead;
if( pThis->iPos!=iPrev ){
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos);
- }
+ }
fts5PrefixMergerNextPosition(pThis);
pHead = pThis->pNext;
fts5PrefixMergerInsertByPosition(&pHead, pThis);
}
-
+
if( pHead->iPos!=iPrev ){
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pHead->iPos);
}
nTail = pHead->iter.nPoslist - pHead->iOff;
-
+
/* WRITEPOSLISTSIZE */
assert_nc( tmp.n+nTail<=nTmp );
assert( tmp.n+nTail<=nTmp+nMerge*10 );
@@ -228114,8 +228114,8 @@ static void fts5MergePrefixLists(
fts5DoclistIterNext(&pX->iter);
fts5PrefixMergerInsertByRowid(&pHead, pX);
}
- }
-
+ }
+
}else{
/* Copy poslist from pHead to output */
PrefixMerger *pThis = pHead;
@@ -228124,56 +228124,56 @@ static void fts5MergePrefixLists(
fts5DoclistIterNext(pI);
pHead = pThis->pNext;
fts5PrefixMergerInsertByRowid(&pHead, pThis);
- }
+ }
}
-
+
fts5BufferFree(p1);
fts5BufferFree(&tmp);
memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING);
*p1 = out;
-}
-
-static void fts5SetupPrefixIter(
- Fts5Index *p, /* Index to read from */
- int bDesc, /* True for "ORDER BY rowid DESC" */
+}
+
+static void fts5SetupPrefixIter(
+ Fts5Index *p, /* Index to read from */
+ int bDesc, /* True for "ORDER BY rowid DESC" */
int iIdx, /* Index to scan for data */
u8 *pToken, /* Buffer containing prefix to match */
- int nToken, /* Size of buffer pToken in bytes */
- Fts5Colset *pColset, /* Restrict matches to these columns */
- Fts5Iter **ppIter /* OUT: New iterator */
-){
- Fts5Structure *pStruct;
- Fts5Buffer *aBuf;
+ int nToken, /* Size of buffer pToken in bytes */
+ Fts5Colset *pColset, /* Restrict matches to these columns */
+ Fts5Iter **ppIter /* OUT: New iterator */
+){
+ Fts5Structure *pStruct;
+ Fts5Buffer *aBuf;
int nBuf = 32;
int nMerge = 1;
-
+
void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*);
- void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*);
- if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
- xMerge = fts5MergeRowidLists;
- xAppend = fts5AppendRowid;
- }else{
+ void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*);
+ if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
+ xMerge = fts5MergeRowidLists;
+ xAppend = fts5AppendRowid;
+ }else{
nMerge = FTS5_MERGE_NLIST-1;
nBuf = nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */
- xMerge = fts5MergePrefixLists;
- xAppend = fts5AppendPoslist;
- }
-
- aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
- pStruct = fts5StructureRead(p);
-
- if( aBuf && pStruct ){
+ xMerge = fts5MergePrefixLists;
+ xAppend = fts5AppendPoslist;
+ }
+
+ aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
+ pStruct = fts5StructureRead(p);
+
+ if( aBuf && pStruct ){
const int flags = FTS5INDEX_QUERY_SCAN
| FTS5INDEX_QUERY_SKIPEMPTY
- | FTS5INDEX_QUERY_NOOUTPUT;
- int i;
- i64 iLastRowid = 0;
- Fts5Iter *p1 = 0; /* Iterator used to gather data from index */
- Fts5Data *pData;
- Fts5Buffer doclist;
- int bNewTerm = 1;
-
- memset(&doclist, 0, sizeof(doclist));
+ | FTS5INDEX_QUERY_NOOUTPUT;
+ int i;
+ i64 iLastRowid = 0;
+ Fts5Iter *p1 = 0; /* Iterator used to gather data from index */
+ Fts5Data *pData;
+ Fts5Buffer doclist;
+ int bNewTerm = 1;
+
+ memset(&doclist, 0, sizeof(doclist));
if( iIdx!=0 ){
int dummy = 0;
const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT;
@@ -228195,26 +228195,26 @@ static void fts5SetupPrefixIter(
}
pToken[0] = FTS5_MAIN_PREFIX + iIdx;
- fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
- fts5IterSetOutputCb(&p->rc, p1);
- for( /* no-op */ ;
- fts5MultiIterEof(p, p1)==0;
- fts5MultiIterNext2(p, p1, &bNewTerm)
- ){
- Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
- int nTerm = pSeg->term.n;
- const u8 *pTerm = pSeg->term.p;
- p1->xSetOutputs(p1, pSeg);
-
- assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 );
- if( bNewTerm ){
- if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
- }
-
- if( p1->base.nData==0 ) continue;
-
- if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){
- for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
+ fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
+ fts5IterSetOutputCb(&p->rc, p1);
+ for( /* no-op */ ;
+ fts5MultiIterEof(p, p1)==0;
+ fts5MultiIterNext2(p, p1, &bNewTerm)
+ ){
+ Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
+ int nTerm = pSeg->term.n;
+ const u8 *pTerm = pSeg->term.p;
+ p1->xSetOutputs(p1, pSeg);
+
+ assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 );
+ if( bNewTerm ){
+ if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
+ }
+
+ if( p1->base.nData==0 ) continue;
+
+ if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){
+ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
int i1 = i*nMerge;
int iStore;
assert( i1+nMerge<=nBuf );
@@ -228224,193 +228224,193 @@ static void fts5SetupPrefixIter(
fts5BufferZero(&doclist);
break;
}
- }
+ }
if( iStore==i1+nMerge ){
xMerge(p, &doclist, nMerge, &aBuf[i1]);
for(iStore=i1; iStore<i1+nMerge; iStore++){
fts5BufferZero(&aBuf[iStore]);
}
}
- }
- iLastRowid = 0;
- }
-
- xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist);
- iLastRowid = p1->base.iRowid;
- }
-
+ }
+ iLastRowid = 0;
+ }
+
+ xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist);
+ iLastRowid = p1->base.iRowid;
+ }
+
assert( (nBuf%nMerge)==0 );
for(i=0; i<nBuf; i+=nMerge){
int iFree;
- if( p->rc==SQLITE_OK ){
+ if( p->rc==SQLITE_OK ){
xMerge(p, &doclist, nMerge, &aBuf[i]);
- }
+ }
for(iFree=i; iFree<i+nMerge; iFree++){
fts5BufferFree(&aBuf[iFree]);
}
- }
- fts5MultiIterFree(p1);
-
+ }
+ fts5MultiIterFree(p1);
+
pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING);
- if( pData ){
- pData->p = (u8*)&pData[1];
- pData->nn = pData->szLeaf = doclist.n;
- if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
- fts5MultiIterNew2(p, pData, bDesc, ppIter);
- }
- fts5BufferFree(&doclist);
- }
-
- fts5StructureRelease(pStruct);
- sqlite3_free(aBuf);
-}
-
-
-/*
-** Indicate that all subsequent calls to sqlite3Fts5IndexWrite() pertain
-** to the document with rowid iRowid.
-*/
-static int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
- assert( p->rc==SQLITE_OK );
-
- /* Allocate the hash table if it has not already been allocated */
- if( p->pHash==0 ){
- p->rc = sqlite3Fts5HashNew(p->pConfig, &p->pHash, &p->nPendingData);
- }
-
- /* Flush the hash table to disk if required */
+ if( pData ){
+ pData->p = (u8*)&pData[1];
+ pData->nn = pData->szLeaf = doclist.n;
+ if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
+ fts5MultiIterNew2(p, pData, bDesc, ppIter);
+ }
+ fts5BufferFree(&doclist);
+ }
+
+ fts5StructureRelease(pStruct);
+ sqlite3_free(aBuf);
+}
+
+
+/*
+** Indicate that all subsequent calls to sqlite3Fts5IndexWrite() pertain
+** to the document with rowid iRowid.
+*/
+static int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
+ assert( p->rc==SQLITE_OK );
+
+ /* Allocate the hash table if it has not already been allocated */
+ if( p->pHash==0 ){
+ p->rc = sqlite3Fts5HashNew(p->pConfig, &p->pHash, &p->nPendingData);
+ }
+
+ /* Flush the hash table to disk if required */
if( iRowid<p->iWriteRowid
- || (iRowid==p->iWriteRowid && p->bDelete==0)
+ || (iRowid==p->iWriteRowid && p->bDelete==0)
|| (p->nPendingData > p->pConfig->nHashSize)
- ){
- fts5IndexFlush(p);
- }
-
- p->iWriteRowid = iRowid;
- p->bDelete = bDelete;
- return fts5IndexReturn(p);
-}
-
-/*
-** Commit data to disk.
-*/
-static int sqlite3Fts5IndexSync(Fts5Index *p){
- assert( p->rc==SQLITE_OK );
- fts5IndexFlush(p);
+ ){
+ fts5IndexFlush(p);
+ }
+
+ p->iWriteRowid = iRowid;
+ p->bDelete = bDelete;
+ return fts5IndexReturn(p);
+}
+
+/*
+** Commit data to disk.
+*/
+static int sqlite3Fts5IndexSync(Fts5Index *p){
+ assert( p->rc==SQLITE_OK );
+ fts5IndexFlush(p);
sqlite3Fts5IndexCloseReader(p);
- return fts5IndexReturn(p);
-}
-
-/*
-** Discard any data stored in the in-memory hash tables. Do not write it
-** to the database. Additionally, assume that the contents of the %_data
+ return fts5IndexReturn(p);
+}
+
+/*
+** Discard any data stored in the in-memory hash tables. Do not write it
+** to the database. Additionally, assume that the contents of the %_data
** table may have changed on disk. So any in-memory caches of %_data
-** records must be invalidated.
-*/
-static int sqlite3Fts5IndexRollback(Fts5Index *p){
+** records must be invalidated.
+*/
+static int sqlite3Fts5IndexRollback(Fts5Index *p){
sqlite3Fts5IndexCloseReader(p);
- fts5IndexDiscardData(p);
- fts5StructureInvalidate(p);
- /* assert( p->rc==SQLITE_OK ); */
- return SQLITE_OK;
-}
-
-/*
-** The %_data table is completely empty when this function is called. This
-** function populates it with the initial structure objects for each index,
-** and the initial version of the "averages" record (a zero-byte blob).
-*/
-static int sqlite3Fts5IndexReinit(Fts5Index *p){
- Fts5Structure s;
- fts5StructureInvalidate(p);
fts5IndexDiscardData(p);
- memset(&s, 0, sizeof(Fts5Structure));
- fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
- fts5StructureWrite(p, &s);
- return fts5IndexReturn(p);
-}
-
-/*
-** Open a new Fts5Index handle. If the bCreate argument is true, create
-** and initialize the underlying %_data table.
-**
-** If successful, set *pp to point to the new object and return SQLITE_OK.
-** Otherwise, set *pp to NULL and return an SQLite error code.
-*/
-static int sqlite3Fts5IndexOpen(
+ fts5StructureInvalidate(p);
+ /* assert( p->rc==SQLITE_OK ); */
+ return SQLITE_OK;
+}
+
+/*
+** The %_data table is completely empty when this function is called. This
+** function populates it with the initial structure objects for each index,
+** and the initial version of the "averages" record (a zero-byte blob).
+*/
+static int sqlite3Fts5IndexReinit(Fts5Index *p){
+ Fts5Structure s;
+ fts5StructureInvalidate(p);
+ fts5IndexDiscardData(p);
+ memset(&s, 0, sizeof(Fts5Structure));
+ fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
+ fts5StructureWrite(p, &s);
+ return fts5IndexReturn(p);
+}
+
+/*
+** Open a new Fts5Index handle. If the bCreate argument is true, create
+** and initialize the underlying %_data table.
+**
+** If successful, set *pp to point to the new object and return SQLITE_OK.
+** Otherwise, set *pp to NULL and return an SQLite error code.
+*/
+static int sqlite3Fts5IndexOpen(
Fts5Config *pConfig,
int bCreate,
- Fts5Index **pp,
- char **pzErr
-){
- int rc = SQLITE_OK;
- Fts5Index *p; /* New object */
-
- *pp = p = (Fts5Index*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Index));
- if( rc==SQLITE_OK ){
- p->pConfig = pConfig;
- p->nWorkUnit = FTS5_WORK_UNIT;
- p->zDataTbl = sqlite3Fts5Mprintf(&rc, "%s_data", pConfig->zName);
- if( p->zDataTbl && bCreate ){
- rc = sqlite3Fts5CreateTable(
- pConfig, "data", "id INTEGER PRIMARY KEY, block BLOB", 0, pzErr
- );
- if( rc==SQLITE_OK ){
+ Fts5Index **pp,
+ char **pzErr
+){
+ int rc = SQLITE_OK;
+ Fts5Index *p; /* New object */
+
+ *pp = p = (Fts5Index*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Index));
+ if( rc==SQLITE_OK ){
+ p->pConfig = pConfig;
+ p->nWorkUnit = FTS5_WORK_UNIT;
+ p->zDataTbl = sqlite3Fts5Mprintf(&rc, "%s_data", pConfig->zName);
+ if( p->zDataTbl && bCreate ){
+ rc = sqlite3Fts5CreateTable(
+ pConfig, "data", "id INTEGER PRIMARY KEY, block BLOB", 0, pzErr
+ );
+ if( rc==SQLITE_OK ){
rc = sqlite3Fts5CreateTable(pConfig, "idx",
"segid, term, pgno, PRIMARY KEY(segid, term)",
- 1, pzErr
- );
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5IndexReinit(p);
- }
- }
- }
-
- assert( rc!=SQLITE_OK || p->rc==SQLITE_OK );
- if( rc ){
- sqlite3Fts5IndexClose(p);
- *pp = 0;
- }
- return rc;
-}
-
-/*
-** Close a handle opened by an earlier call to sqlite3Fts5IndexOpen().
-*/
-static int sqlite3Fts5IndexClose(Fts5Index *p){
- int rc = SQLITE_OK;
- if( p ){
- assert( p->pReader==0 );
- fts5StructureInvalidate(p);
- sqlite3_finalize(p->pWriter);
- sqlite3_finalize(p->pDeleter);
- sqlite3_finalize(p->pIdxWriter);
- sqlite3_finalize(p->pIdxDeleter);
- sqlite3_finalize(p->pIdxSelect);
- sqlite3_finalize(p->pDataVersion);
- sqlite3Fts5HashFree(p->pHash);
- sqlite3_free(p->zDataTbl);
- sqlite3_free(p);
- }
- return rc;
-}
-
-/*
+ 1, pzErr
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexReinit(p);
+ }
+ }
+ }
+
+ assert( rc!=SQLITE_OK || p->rc==SQLITE_OK );
+ if( rc ){
+ sqlite3Fts5IndexClose(p);
+ *pp = 0;
+ }
+ return rc;
+}
+
+/*
+** Close a handle opened by an earlier call to sqlite3Fts5IndexOpen().
+*/
+static int sqlite3Fts5IndexClose(Fts5Index *p){
+ int rc = SQLITE_OK;
+ if( p ){
+ assert( p->pReader==0 );
+ fts5StructureInvalidate(p);
+ sqlite3_finalize(p->pWriter);
+ sqlite3_finalize(p->pDeleter);
+ sqlite3_finalize(p->pIdxWriter);
+ sqlite3_finalize(p->pIdxDeleter);
+ sqlite3_finalize(p->pIdxSelect);
+ sqlite3_finalize(p->pDataVersion);
+ sqlite3Fts5HashFree(p->pHash);
+ sqlite3_free(p->zDataTbl);
+ sqlite3_free(p);
+ }
+ return rc;
+}
+
+/*
** Argument p points to a buffer containing utf-8 text that is n bytes in
-** size. Return the number of bytes in the nChar character prefix of the
-** buffer, or 0 if there are less than nChar characters in total.
-*/
-static int sqlite3Fts5IndexCharlenToBytelen(
+** size. Return the number of bytes in the nChar character prefix of the
+** buffer, or 0 if there are less than nChar characters in total.
+*/
+static int sqlite3Fts5IndexCharlenToBytelen(
const char *p,
int nByte,
- int nChar
-){
- int n = 0;
- int i;
- for(i=0; i<nChar; i++){
- if( n>=nByte ) return 0; /* Input contains fewer than nChar chars */
- if( (unsigned char)p[n++]>=0xc0 ){
+ int nChar
+){
+ int n = 0;
+ int i;
+ for(i=0; i<nChar; i++){
+ if( n>=nByte ) return 0; /* Input contains fewer than nChar chars */
+ if( (unsigned char)p[n++]>=0xc0 ){
if( n>=nByte ) return 0;
while( (p[n] & 0xc0)==0x80 ){
n++;
@@ -228419,130 +228419,130 @@ static int sqlite3Fts5IndexCharlenToBytelen(
return 0;
}
}
- }
- }
- return n;
-}
-
-/*
-** pIn is a UTF-8 encoded string, nIn bytes in size. Return the number of
-** unicode characters in the string.
-*/
-static int fts5IndexCharlen(const char *pIn, int nIn){
+ }
+ }
+ return n;
+}
+
+/*
+** pIn is a UTF-8 encoded string, nIn bytes in size. Return the number of
+** unicode characters in the string.
+*/
+static int fts5IndexCharlen(const char *pIn, int nIn){
int nChar = 0;
- int i = 0;
- while( i<nIn ){
- if( (unsigned char)pIn[i++]>=0xc0 ){
- while( i<nIn && (pIn[i] & 0xc0)==0x80 ) i++;
- }
- nChar++;
- }
- return nChar;
-}
-
-/*
+ int i = 0;
+ while( i<nIn ){
+ if( (unsigned char)pIn[i++]>=0xc0 ){
+ while( i<nIn && (pIn[i] & 0xc0)==0x80 ) i++;
+ }
+ nChar++;
+ }
+ return nChar;
+}
+
+/*
** Insert or remove data to or from the index. Each time a document is
-** added to or removed from the index, this function is called one or more
-** times.
-**
-** For an insert, it must be called once for each token in the new document.
-** If the operation is a delete, it must be called (at least) once for each
-** unique token in the document with an iCol value less than zero. The iPos
-** argument is ignored for a delete.
-*/
-static int sqlite3Fts5IndexWrite(
- Fts5Index *p, /* Index to write to */
- int iCol, /* Column token appears in (-ve -> delete) */
- int iPos, /* Position of token within column */
- const char *pToken, int nToken /* Token to add or remove to or from index */
-){
- int i; /* Used to iterate through indexes */
- int rc = SQLITE_OK; /* Return code */
- Fts5Config *pConfig = p->pConfig;
-
- assert( p->rc==SQLITE_OK );
- assert( (iCol<0)==p->bDelete );
-
- /* Add the entry to the main terms index. */
- rc = sqlite3Fts5HashWrite(
- p->pHash, p->iWriteRowid, iCol, iPos, FTS5_MAIN_PREFIX, pToken, nToken
- );
-
- for(i=0; i<pConfig->nPrefix && rc==SQLITE_OK; i++){
- const int nChar = pConfig->aPrefix[i];
- int nByte = sqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar);
- if( nByte ){
+** added to or removed from the index, this function is called one or more
+** times.
+**
+** For an insert, it must be called once for each token in the new document.
+** If the operation is a delete, it must be called (at least) once for each
+** unique token in the document with an iCol value less than zero. The iPos
+** argument is ignored for a delete.
+*/
+static int sqlite3Fts5IndexWrite(
+ Fts5Index *p, /* Index to write to */
+ int iCol, /* Column token appears in (-ve -> delete) */
+ int iPos, /* Position of token within column */
+ const char *pToken, int nToken /* Token to add or remove to or from index */
+){
+ int i; /* Used to iterate through indexes */
+ int rc = SQLITE_OK; /* Return code */
+ Fts5Config *pConfig = p->pConfig;
+
+ assert( p->rc==SQLITE_OK );
+ assert( (iCol<0)==p->bDelete );
+
+ /* Add the entry to the main terms index. */
+ rc = sqlite3Fts5HashWrite(
+ p->pHash, p->iWriteRowid, iCol, iPos, FTS5_MAIN_PREFIX, pToken, nToken
+ );
+
+ for(i=0; i<pConfig->nPrefix && rc==SQLITE_OK; i++){
+ const int nChar = pConfig->aPrefix[i];
+ int nByte = sqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar);
+ if( nByte ){
rc = sqlite3Fts5HashWrite(p->pHash,
- p->iWriteRowid, iCol, iPos, (char)(FTS5_MAIN_PREFIX+i+1), pToken,
- nByte
- );
- }
- }
-
- return rc;
-}
-
-/*
+ p->iWriteRowid, iCol, iPos, (char)(FTS5_MAIN_PREFIX+i+1), pToken,
+ nByte
+ );
+ }
+ }
+
+ return rc;
+}
+
+/*
** Open a new iterator to iterate though all rowid that match the
-** specified token or token prefix.
-*/
-static int sqlite3Fts5IndexQuery(
- Fts5Index *p, /* FTS index to query */
- const char *pToken, int nToken, /* Token (or prefix) to query for */
- int flags, /* Mask of FTS5INDEX_QUERY_X flags */
- Fts5Colset *pColset, /* Match these columns only */
- Fts5IndexIter **ppIter /* OUT: New iterator object */
-){
- Fts5Config *pConfig = p->pConfig;
- Fts5Iter *pRet = 0;
- Fts5Buffer buf = {0, 0, 0};
-
- /* If the QUERY_SCAN flag is set, all other flags must be clear. */
- assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
-
- if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
- int iIdx = 0; /* Index to search */
+** specified token or token prefix.
+*/
+static int sqlite3Fts5IndexQuery(
+ Fts5Index *p, /* FTS index to query */
+ const char *pToken, int nToken, /* Token (or prefix) to query for */
+ int flags, /* Mask of FTS5INDEX_QUERY_X flags */
+ Fts5Colset *pColset, /* Match these columns only */
+ Fts5IndexIter **ppIter /* OUT: New iterator object */
+){
+ Fts5Config *pConfig = p->pConfig;
+ Fts5Iter *pRet = 0;
+ Fts5Buffer buf = {0, 0, 0};
+
+ /* If the QUERY_SCAN flag is set, all other flags must be clear. */
+ assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
+
+ if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
+ int iIdx = 0; /* Index to search */
int iPrefixIdx = 0; /* +1 prefix index */
- if( nToken ) memcpy(&buf.p[1], pToken, nToken);
-
- /* Figure out which index to search and set iIdx accordingly. If this
- ** is a prefix query for which there is no prefix index, set iIdx to
- ** greater than pConfig->nPrefix to indicate that the query will be
- ** satisfied by scanning multiple terms in the main index.
- **
- ** If the QUERY_TEST_NOIDX flag was specified, then this must be a
+ if( nToken ) memcpy(&buf.p[1], pToken, nToken);
+
+ /* Figure out which index to search and set iIdx accordingly. If this
+ ** is a prefix query for which there is no prefix index, set iIdx to
+ ** greater than pConfig->nPrefix to indicate that the query will be
+ ** satisfied by scanning multiple terms in the main index.
+ **
+ ** If the QUERY_TEST_NOIDX flag was specified, then this must be a
** prefix-query. Instead of using a prefix-index (if one exists),
- ** evaluate the prefix query using the main FTS index. This is used
+ ** evaluate the prefix query using the main FTS index. This is used
** for internal sanity checking by the integrity-check in debug
- ** mode only. */
-#ifdef SQLITE_DEBUG
- if( pConfig->bPrefixIndex==0 || (flags & FTS5INDEX_QUERY_TEST_NOIDX) ){
- assert( flags & FTS5INDEX_QUERY_PREFIX );
- iIdx = 1+pConfig->nPrefix;
- }else
-#endif
- if( flags & FTS5INDEX_QUERY_PREFIX ){
- int nChar = fts5IndexCharlen(pToken, nToken);
- for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){
+ ** mode only. */
+#ifdef SQLITE_DEBUG
+ if( pConfig->bPrefixIndex==0 || (flags & FTS5INDEX_QUERY_TEST_NOIDX) ){
+ assert( flags & FTS5INDEX_QUERY_PREFIX );
+ iIdx = 1+pConfig->nPrefix;
+ }else
+#endif
+ if( flags & FTS5INDEX_QUERY_PREFIX ){
+ int nChar = fts5IndexCharlen(pToken, nToken);
+ for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){
int nIdxChar = pConfig->aPrefix[iIdx-1];
if( nIdxChar==nChar ) break;
if( nIdxChar==nChar+1 ) iPrefixIdx = iIdx;
- }
- }
-
- if( iIdx<=pConfig->nPrefix ){
- /* Straight index lookup */
- Fts5Structure *pStruct = fts5StructureRead(p);
- buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
- if( pStruct ){
+ }
+ }
+
+ if( iIdx<=pConfig->nPrefix ){
+ /* Straight index lookup */
+ Fts5Structure *pStruct = fts5StructureRead(p);
+ buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
+ if( pStruct ){
fts5MultiIterNew(p, pStruct, flags | FTS5INDEX_QUERY_SKIPEMPTY,
- pColset, buf.p, nToken+1, -1, 0, &pRet
- );
- fts5StructureRelease(pStruct);
- }
- }else{
- /* Scan multiple terms in the main index */
- int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
+ pColset, buf.p, nToken+1, -1, 0, &pRet
+ );
+ fts5StructureRelease(pStruct);
+ }
+ }else{
+ /* Scan multiple terms in the main index */
+ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet);
if( pRet==0 ){
assert( p->rc!=SQLITE_OK );
@@ -228553,279 +228553,279 @@ static int sqlite3Fts5IndexQuery(
Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
}
- }
- }
-
- if( p->rc ){
- sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
- pRet = 0;
+ }
+ }
+
+ if( p->rc ){
+ sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
+ pRet = 0;
sqlite3Fts5IndexCloseReader(p);
- }
-
+ }
+
*ppIter = (Fts5IndexIter*)pRet;
- sqlite3Fts5BufferFree(&buf);
- }
- return fts5IndexReturn(p);
-}
-
-/*
-** Return true if the iterator passed as the only argument is at EOF.
-*/
-/*
+ sqlite3Fts5BufferFree(&buf);
+ }
+ return fts5IndexReturn(p);
+}
+
+/*
+** Return true if the iterator passed as the only argument is at EOF.
+*/
+/*
** Move to the next matching rowid.
-*/
-static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
- Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
- assert( pIter->pIndex->rc==SQLITE_OK );
- fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
- return fts5IndexReturn(pIter->pIndex);
-}
-
-/*
-** Move to the next matching term/rowid. Used by the fts5vocab module.
-*/
-static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){
- Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
- Fts5Index *p = pIter->pIndex;
-
- assert( pIter->pIndex->rc==SQLITE_OK );
-
- fts5MultiIterNext(p, pIter, 0, 0);
- if( p->rc==SQLITE_OK ){
- Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
- if( pSeg->pLeaf && pSeg->term.p[0]!=FTS5_MAIN_PREFIX ){
- fts5DataRelease(pSeg->pLeaf);
- pSeg->pLeaf = 0;
- pIter->base.bEof = 1;
- }
- }
-
- return fts5IndexReturn(pIter->pIndex);
-}
-
-/*
-** Move to the next matching rowid that occurs at or after iMatch. The
-** definition of "at or after" depends on whether this iterator iterates
-** in ascending or descending rowid order.
-*/
-static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
- Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
- fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
- return fts5IndexReturn(pIter->pIndex);
-}
-
-/*
-** Return the current term.
-*/
-static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){
- int n;
- const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
+*/
+static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
+ Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
+ assert( pIter->pIndex->rc==SQLITE_OK );
+ fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
+ return fts5IndexReturn(pIter->pIndex);
+}
+
+/*
+** Move to the next matching term/rowid. Used by the fts5vocab module.
+*/
+static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){
+ Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
+ Fts5Index *p = pIter->pIndex;
+
+ assert( pIter->pIndex->rc==SQLITE_OK );
+
+ fts5MultiIterNext(p, pIter, 0, 0);
+ if( p->rc==SQLITE_OK ){
+ Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ if( pSeg->pLeaf && pSeg->term.p[0]!=FTS5_MAIN_PREFIX ){
+ fts5DataRelease(pSeg->pLeaf);
+ pSeg->pLeaf = 0;
+ pIter->base.bEof = 1;
+ }
+ }
+
+ return fts5IndexReturn(pIter->pIndex);
+}
+
+/*
+** Move to the next matching rowid that occurs at or after iMatch. The
+** definition of "at or after" depends on whether this iterator iterates
+** in ascending or descending rowid order.
+*/
+static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
+ Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
+ fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
+ return fts5IndexReturn(pIter->pIndex);
+}
+
+/*
+** Return the current term.
+*/
+static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){
+ int n;
+ const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
assert_nc( z || n<=1 );
- *pn = n-1;
+ *pn = n-1;
return (z ? &z[1] : 0);
-}
-
-/*
-** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
-*/
-static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
- if( pIndexIter ){
- Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
- Fts5Index *pIndex = pIter->pIndex;
- fts5MultiIterFree(pIter);
+}
+
+/*
+** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
+*/
+static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
+ if( pIndexIter ){
+ Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
+ Fts5Index *pIndex = pIter->pIndex;
+ fts5MultiIterFree(pIter);
sqlite3Fts5IndexCloseReader(pIndex);
- }
-}
-
-/*
+ }
+}
+
+/*
** Read and decode the "averages" record from the database.
-**
-** Parameter anSize must point to an array of size nCol, where nCol is
-** the number of user defined columns in the FTS table.
-*/
-static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize){
- int nCol = p->pConfig->nCol;
- Fts5Data *pData;
-
- *pnRow = 0;
- memset(anSize, 0, sizeof(i64) * nCol);
- pData = fts5DataRead(p, FTS5_AVERAGES_ROWID);
- if( p->rc==SQLITE_OK && pData->nn ){
- int i = 0;
- int iCol;
- i += fts5GetVarint(&pData->p[i], (u64*)pnRow);
- for(iCol=0; i<pData->nn && iCol<nCol; iCol++){
- i += fts5GetVarint(&pData->p[i], (u64*)&anSize[iCol]);
- }
- }
-
- fts5DataRelease(pData);
- return fts5IndexReturn(p);
-}
-
-/*
+**
+** Parameter anSize must point to an array of size nCol, where nCol is
+** the number of user defined columns in the FTS table.
+*/
+static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize){
+ int nCol = p->pConfig->nCol;
+ Fts5Data *pData;
+
+ *pnRow = 0;
+ memset(anSize, 0, sizeof(i64) * nCol);
+ pData = fts5DataRead(p, FTS5_AVERAGES_ROWID);
+ if( p->rc==SQLITE_OK && pData->nn ){
+ int i = 0;
+ int iCol;
+ i += fts5GetVarint(&pData->p[i], (u64*)pnRow);
+ for(iCol=0; i<pData->nn && iCol<nCol; iCol++){
+ i += fts5GetVarint(&pData->p[i], (u64*)&anSize[iCol]);
+ }
+ }
+
+ fts5DataRelease(pData);
+ return fts5IndexReturn(p);
+}
+
+/*
** Replace the current "averages" record with the contents of the buffer
-** supplied as the second argument.
-*/
-static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8 *pData, int nData){
- assert( p->rc==SQLITE_OK );
- fts5DataWrite(p, FTS5_AVERAGES_ROWID, pData, nData);
- return fts5IndexReturn(p);
-}
-
-/*
-** Return the total number of blocks this module has read from the %_data
-** table since it was created.
-*/
-static int sqlite3Fts5IndexReads(Fts5Index *p){
- return p->nRead;
-}
-
-/*
+** supplied as the second argument.
+*/
+static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8 *pData, int nData){
+ assert( p->rc==SQLITE_OK );
+ fts5DataWrite(p, FTS5_AVERAGES_ROWID, pData, nData);
+ return fts5IndexReturn(p);
+}
+
+/*
+** Return the total number of blocks this module has read from the %_data
+** table since it was created.
+*/
+static int sqlite3Fts5IndexReads(Fts5Index *p){
+ return p->nRead;
+}
+
+/*
** Set the 32-bit cookie value stored at the start of all structure
-** records to the value passed as the second argument.
-**
-** Return SQLITE_OK if successful, or an SQLite error code if an error
-** occurs.
-*/
-static int sqlite3Fts5IndexSetCookie(Fts5Index *p, int iNew){
- int rc; /* Return code */
- Fts5Config *pConfig = p->pConfig; /* Configuration object */
- u8 aCookie[4]; /* Binary representation of iNew */
- sqlite3_blob *pBlob = 0;
-
- assert( p->rc==SQLITE_OK );
- sqlite3Fts5Put32(aCookie, iNew);
-
+** records to the value passed as the second argument.
+**
+** Return SQLITE_OK if successful, or an SQLite error code if an error
+** occurs.
+*/
+static int sqlite3Fts5IndexSetCookie(Fts5Index *p, int iNew){
+ int rc; /* Return code */
+ Fts5Config *pConfig = p->pConfig; /* Configuration object */
+ u8 aCookie[4]; /* Binary representation of iNew */
+ sqlite3_blob *pBlob = 0;
+
+ assert( p->rc==SQLITE_OK );
+ sqlite3Fts5Put32(aCookie, iNew);
+
rc = sqlite3_blob_open(pConfig->db, pConfig->zDb, p->zDataTbl,
- "block", FTS5_STRUCTURE_ROWID, 1, &pBlob
- );
- if( rc==SQLITE_OK ){
- sqlite3_blob_write(pBlob, aCookie, 4, 0);
- rc = sqlite3_blob_close(pBlob);
- }
-
- return rc;
-}
-
-static int sqlite3Fts5IndexLoadConfig(Fts5Index *p){
- Fts5Structure *pStruct;
- pStruct = fts5StructureRead(p);
- fts5StructureRelease(pStruct);
- return fts5IndexReturn(p);
-}
-
-
-/*************************************************************************
-**************************************************************************
+ "block", FTS5_STRUCTURE_ROWID, 1, &pBlob
+ );
+ if( rc==SQLITE_OK ){
+ sqlite3_blob_write(pBlob, aCookie, 4, 0);
+ rc = sqlite3_blob_close(pBlob);
+ }
+
+ return rc;
+}
+
+static int sqlite3Fts5IndexLoadConfig(Fts5Index *p){
+ Fts5Structure *pStruct;
+ pStruct = fts5StructureRead(p);
+ fts5StructureRelease(pStruct);
+ return fts5IndexReturn(p);
+}
+
+
+/*************************************************************************
+**************************************************************************
** Below this point is the implementation of the integrity-check
-** functionality.
-*/
-
-/*
-** Return a simple checksum value based on the arguments.
-*/
-static u64 sqlite3Fts5IndexEntryCksum(
+** functionality.
+*/
+
+/*
+** Return a simple checksum value based on the arguments.
+*/
+static u64 sqlite3Fts5IndexEntryCksum(
i64 iRowid,
int iCol,
int iPos,
- int iIdx,
- const char *pTerm,
- int nTerm
-){
- int i;
- u64 ret = iRowid;
- ret += (ret<<3) + iCol;
- ret += (ret<<3) + iPos;
- if( iIdx>=0 ) ret += (ret<<3) + (FTS5_MAIN_PREFIX + iIdx);
- for(i=0; i<nTerm; i++) ret += (ret<<3) + pTerm[i];
- return ret;
-}
-
-#ifdef SQLITE_DEBUG
-/*
+ int iIdx,
+ const char *pTerm,
+ int nTerm
+){
+ int i;
+ u64 ret = iRowid;
+ ret += (ret<<3) + iCol;
+ ret += (ret<<3) + iPos;
+ if( iIdx>=0 ) ret += (ret<<3) + (FTS5_MAIN_PREFIX + iIdx);
+ for(i=0; i<nTerm; i++) ret += (ret<<3) + pTerm[i];
+ return ret;
+}
+
+#ifdef SQLITE_DEBUG
+/*
** This function is purely an internal test. It does not contribute to
-** FTS functionality, or even the integrity-check, in any way.
-**
+** FTS functionality, or even the integrity-check, in any way.
+**
** Instead, it tests that the same set of pgno/rowid combinations are
-** visited regardless of whether the doclist-index identified by parameters
-** iSegid/iLeaf is iterated in forwards or reverse order.
-*/
-static void fts5TestDlidxReverse(
+** visited regardless of whether the doclist-index identified by parameters
+** iSegid/iLeaf is iterated in forwards or reverse order.
+*/
+static void fts5TestDlidxReverse(
Fts5Index *p,
- int iSegid, /* Segment id to load from */
- int iLeaf /* Load doclist-index for this leaf */
-){
- Fts5DlidxIter *pDlidx = 0;
- u64 cksum1 = 13;
- u64 cksum2 = 13;
-
- for(pDlidx=fts5DlidxIterInit(p, 0, iSegid, iLeaf);
- fts5DlidxIterEof(p, pDlidx)==0;
- fts5DlidxIterNext(p, pDlidx)
- ){
- i64 iRowid = fts5DlidxIterRowid(pDlidx);
- int pgno = fts5DlidxIterPgno(pDlidx);
- assert( pgno>iLeaf );
- cksum1 += iRowid + ((i64)pgno<<32);
- }
- fts5DlidxIterFree(pDlidx);
- pDlidx = 0;
-
- for(pDlidx=fts5DlidxIterInit(p, 1, iSegid, iLeaf);
- fts5DlidxIterEof(p, pDlidx)==0;
- fts5DlidxIterPrev(p, pDlidx)
- ){
- i64 iRowid = fts5DlidxIterRowid(pDlidx);
- int pgno = fts5DlidxIterPgno(pDlidx);
- assert( fts5DlidxIterPgno(pDlidx)>iLeaf );
- cksum2 += iRowid + ((i64)pgno<<32);
- }
- fts5DlidxIterFree(pDlidx);
- pDlidx = 0;
-
- if( p->rc==SQLITE_OK && cksum1!=cksum2 ) p->rc = FTS5_CORRUPT;
-}
-
-static int fts5QueryCksum(
- Fts5Index *p, /* Fts5 index object */
- int iIdx,
- const char *z, /* Index key to query for */
- int n, /* Size of index key in bytes */
- int flags, /* Flags for Fts5IndexQuery */
- u64 *pCksum /* IN/OUT: Checksum value */
-){
- int eDetail = p->pConfig->eDetail;
- u64 cksum = *pCksum;
- Fts5IndexIter *pIter = 0;
- int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
-
+ int iSegid, /* Segment id to load from */
+ int iLeaf /* Load doclist-index for this leaf */
+){
+ Fts5DlidxIter *pDlidx = 0;
+ u64 cksum1 = 13;
+ u64 cksum2 = 13;
+
+ for(pDlidx=fts5DlidxIterInit(p, 0, iSegid, iLeaf);
+ fts5DlidxIterEof(p, pDlidx)==0;
+ fts5DlidxIterNext(p, pDlidx)
+ ){
+ i64 iRowid = fts5DlidxIterRowid(pDlidx);
+ int pgno = fts5DlidxIterPgno(pDlidx);
+ assert( pgno>iLeaf );
+ cksum1 += iRowid + ((i64)pgno<<32);
+ }
+ fts5DlidxIterFree(pDlidx);
+ pDlidx = 0;
+
+ for(pDlidx=fts5DlidxIterInit(p, 1, iSegid, iLeaf);
+ fts5DlidxIterEof(p, pDlidx)==0;
+ fts5DlidxIterPrev(p, pDlidx)
+ ){
+ i64 iRowid = fts5DlidxIterRowid(pDlidx);
+ int pgno = fts5DlidxIterPgno(pDlidx);
+ assert( fts5DlidxIterPgno(pDlidx)>iLeaf );
+ cksum2 += iRowid + ((i64)pgno<<32);
+ }
+ fts5DlidxIterFree(pDlidx);
+ pDlidx = 0;
+
+ if( p->rc==SQLITE_OK && cksum1!=cksum2 ) p->rc = FTS5_CORRUPT;
+}
+
+static int fts5QueryCksum(
+ Fts5Index *p, /* Fts5 index object */
+ int iIdx,
+ const char *z, /* Index key to query for */
+ int n, /* Size of index key in bytes */
+ int flags, /* Flags for Fts5IndexQuery */
+ u64 *pCksum /* IN/OUT: Checksum value */
+){
+ int eDetail = p->pConfig->eDetail;
+ u64 cksum = *pCksum;
+ Fts5IndexIter *pIter = 0;
+ int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
+
while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){
- i64 rowid = pIter->iRowid;
-
- if( eDetail==FTS5_DETAIL_NONE ){
- cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n);
- }else{
- Fts5PoslistReader sReader;
- for(sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &sReader);
- sReader.bEof==0;
- sqlite3Fts5PoslistReaderNext(&sReader)
- ){
- int iCol = FTS5_POS2COLUMN(sReader.iPos);
- int iOff = FTS5_POS2OFFSET(sReader.iPos);
- cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
- }
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5IterNext(pIter);
- }
- }
- sqlite3Fts5IterClose(pIter);
-
- *pCksum = cksum;
- return rc;
-}
-
+ i64 rowid = pIter->iRowid;
+
+ if( eDetail==FTS5_DETAIL_NONE ){
+ cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n);
+ }else{
+ Fts5PoslistReader sReader;
+ for(sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &sReader);
+ sReader.bEof==0;
+ sqlite3Fts5PoslistReaderNext(&sReader)
+ ){
+ int iCol = FTS5_POS2COLUMN(sReader.iPos);
+ int iOff = FTS5_POS2OFFSET(sReader.iPos);
+ cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
+ }
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IterNext(pIter);
+ }
+ }
+ sqlite3Fts5IterClose(pIter);
+
+ *pCksum = cksum;
+ return rc;
+}
+
/*
** Check if buffer z[], size n bytes, contains as series of valid utf-8
** encoded codepoints. If so, return 0. Otherwise, if the buffer does not
@@ -228854,49 +228854,49 @@ static int fts5TestUtf8(const char *z, int n){
return 1;
}
}
-
+
return 0;
}
-/*
+/*
** This function is also purely an internal test. It does not contribute to
-** FTS functionality, or even the integrity-check, in any way.
-*/
-static void fts5TestTerm(
+** FTS functionality, or even the integrity-check, in any way.
+*/
+static void fts5TestTerm(
Fts5Index *p,
- Fts5Buffer *pPrev, /* Previous term */
- const char *z, int n, /* Possibly new term to test */
- u64 expected,
- u64 *pCksum
-){
- int rc = p->rc;
- if( pPrev->n==0 ){
- fts5BufferSet(&rc, pPrev, n, (const u8*)z);
- }else
- if( rc==SQLITE_OK && (pPrev->n!=n || memcmp(pPrev->p, z, n)) ){
- u64 cksum3 = *pCksum;
- const char *zTerm = (const char*)&pPrev->p[1]; /* term sans prefix-byte */
- int nTerm = pPrev->n-1; /* Size of zTerm in bytes */
- int iIdx = (pPrev->p[0] - FTS5_MAIN_PREFIX);
- int flags = (iIdx==0 ? 0 : FTS5INDEX_QUERY_PREFIX);
- u64 ck1 = 0;
- u64 ck2 = 0;
-
- /* Check that the results returned for ASC and DESC queries are
- ** the same. If not, call this corruption. */
- rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, flags, &ck1);
- if( rc==SQLITE_OK ){
- int f = flags|FTS5INDEX_QUERY_DESC;
- rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
- }
- if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
-
- /* If this is a prefix query, check that the results returned if the
+ Fts5Buffer *pPrev, /* Previous term */
+ const char *z, int n, /* Possibly new term to test */
+ u64 expected,
+ u64 *pCksum
+){
+ int rc = p->rc;
+ if( pPrev->n==0 ){
+ fts5BufferSet(&rc, pPrev, n, (const u8*)z);
+ }else
+ if( rc==SQLITE_OK && (pPrev->n!=n || memcmp(pPrev->p, z, n)) ){
+ u64 cksum3 = *pCksum;
+ const char *zTerm = (const char*)&pPrev->p[1]; /* term sans prefix-byte */
+ int nTerm = pPrev->n-1; /* Size of zTerm in bytes */
+ int iIdx = (pPrev->p[0] - FTS5_MAIN_PREFIX);
+ int flags = (iIdx==0 ? 0 : FTS5INDEX_QUERY_PREFIX);
+ u64 ck1 = 0;
+ u64 ck2 = 0;
+
+ /* Check that the results returned for ASC and DESC queries are
+ ** the same. If not, call this corruption. */
+ rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, flags, &ck1);
+ if( rc==SQLITE_OK ){
+ int f = flags|FTS5INDEX_QUERY_DESC;
+ rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
+ }
+ if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
+
+ /* If this is a prefix query, check that the results returned if the
** the index is disabled are the same. In both ASC and DESC order.
- **
- ** This check may only be performed if the hash table is empty. This
- ** is because the hash table only supports a single scan query at
- ** a time, and the multi-iter loop from which this function is called
+ **
+ ** This check may only be performed if the hash table is empty. This
+ ** is because the hash table only supports a single scan query at
+ ** a time, and the multi-iter loop from which this function is called
** is already performing such a scan.
**
** Also only do this if buffer zTerm contains nTerm bytes of valid
@@ -228905,1325 +228905,1325 @@ static void fts5TestTerm(
** character stored in the main fts index, which will cause the
** test to fail. */
if( p->nPendingData==0 && 0==fts5TestUtf8(zTerm, nTerm) ){
- if( iIdx>0 && rc==SQLITE_OK ){
- int f = flags|FTS5INDEX_QUERY_TEST_NOIDX;
- ck2 = 0;
- rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
- if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
- }
- if( iIdx>0 && rc==SQLITE_OK ){
- int f = flags|FTS5INDEX_QUERY_TEST_NOIDX|FTS5INDEX_QUERY_DESC;
- ck2 = 0;
- rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
- if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
- }
- }
-
- cksum3 ^= ck1;
- fts5BufferSet(&rc, pPrev, n, (const u8*)z);
-
- if( rc==SQLITE_OK && cksum3!=expected ){
- rc = FTS5_CORRUPT;
- }
- *pCksum = cksum3;
- }
- p->rc = rc;
-}
-
-#else
-# define fts5TestDlidxReverse(x,y,z)
-# define fts5TestTerm(u,v,w,x,y,z)
-#endif
-
-/*
-** Check that:
-**
-** 1) All leaves of pSeg between iFirst and iLast (inclusive) exist and
-** contain zero terms.
-** 2) All leaves of pSeg between iNoRowid and iLast (inclusive) exist and
-** contain zero rowids.
-*/
-static void fts5IndexIntegrityCheckEmpty(
- Fts5Index *p,
- Fts5StructureSegment *pSeg, /* Segment to check internal consistency */
- int iFirst,
- int iNoRowid,
- int iLast
-){
- int i;
-
- /* Now check that the iter.nEmpty leaves following the current leaf
- ** (a) exist and (b) contain no terms. */
- for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){
- Fts5Data *pLeaf = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
- if( pLeaf ){
- if( !fts5LeafIsTermless(pLeaf) ) p->rc = FTS5_CORRUPT;
- if( i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf) ) p->rc = FTS5_CORRUPT;
- }
- fts5DataRelease(pLeaf);
- }
-}
-
-static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
- int iTermOff = 0;
- int ii;
-
- Fts5Buffer buf1 = {0,0,0};
- Fts5Buffer buf2 = {0,0,0};
-
- ii = pLeaf->szLeaf;
- while( ii<pLeaf->nn && p->rc==SQLITE_OK ){
- int res;
- int iOff;
- int nIncr;
-
- ii += fts5GetVarint32(&pLeaf->p[ii], nIncr);
- iTermOff += nIncr;
- iOff = iTermOff;
-
- if( iOff>=pLeaf->szLeaf ){
- p->rc = FTS5_CORRUPT;
- }else if( iTermOff==nIncr ){
- int nByte;
- iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
- if( (iOff+nByte)>pLeaf->szLeaf ){
- p->rc = FTS5_CORRUPT;
- }else{
- fts5BufferSet(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
- }
- }else{
- int nKeep, nByte;
- iOff += fts5GetVarint32(&pLeaf->p[iOff], nKeep);
- iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
- if( nKeep>buf1.n || (iOff+nByte)>pLeaf->szLeaf ){
- p->rc = FTS5_CORRUPT;
- }else{
- buf1.n = nKeep;
- fts5BufferAppendBlob(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
- }
-
- if( p->rc==SQLITE_OK ){
- res = fts5BufferCompare(&buf1, &buf2);
- if( res<=0 ) p->rc = FTS5_CORRUPT;
- }
- }
- fts5BufferSet(&p->rc, &buf2, buf1.n, buf1.p);
- }
-
- fts5BufferFree(&buf1);
- fts5BufferFree(&buf2);
-}
-
-static void fts5IndexIntegrityCheckSegment(
- Fts5Index *p, /* FTS5 backend object */
- Fts5StructureSegment *pSeg /* Segment to check internal consistency */
-){
- Fts5Config *pConfig = p->pConfig;
- sqlite3_stmt *pStmt = 0;
- int rc2;
- int iIdxPrevLeaf = pSeg->pgnoFirst-1;
- int iDlidxPrevLeaf = pSeg->pgnoLast;
-
- if( pSeg->pgnoFirst==0 ) return;
-
- fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf(
+ if( iIdx>0 && rc==SQLITE_OK ){
+ int f = flags|FTS5INDEX_QUERY_TEST_NOIDX;
+ ck2 = 0;
+ rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
+ if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
+ }
+ if( iIdx>0 && rc==SQLITE_OK ){
+ int f = flags|FTS5INDEX_QUERY_TEST_NOIDX|FTS5INDEX_QUERY_DESC;
+ ck2 = 0;
+ rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
+ if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
+ }
+ }
+
+ cksum3 ^= ck1;
+ fts5BufferSet(&rc, pPrev, n, (const u8*)z);
+
+ if( rc==SQLITE_OK && cksum3!=expected ){
+ rc = FTS5_CORRUPT;
+ }
+ *pCksum = cksum3;
+ }
+ p->rc = rc;
+}
+
+#else
+# define fts5TestDlidxReverse(x,y,z)
+# define fts5TestTerm(u,v,w,x,y,z)
+#endif
+
+/*
+** Check that:
+**
+** 1) All leaves of pSeg between iFirst and iLast (inclusive) exist and
+** contain zero terms.
+** 2) All leaves of pSeg between iNoRowid and iLast (inclusive) exist and
+** contain zero rowids.
+*/
+static void fts5IndexIntegrityCheckEmpty(
+ Fts5Index *p,
+ Fts5StructureSegment *pSeg, /* Segment to check internal consistency */
+ int iFirst,
+ int iNoRowid,
+ int iLast
+){
+ int i;
+
+ /* Now check that the iter.nEmpty leaves following the current leaf
+ ** (a) exist and (b) contain no terms. */
+ for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){
+ Fts5Data *pLeaf = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
+ if( pLeaf ){
+ if( !fts5LeafIsTermless(pLeaf) ) p->rc = FTS5_CORRUPT;
+ if( i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf) ) p->rc = FTS5_CORRUPT;
+ }
+ fts5DataRelease(pLeaf);
+ }
+}
+
+static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
+ int iTermOff = 0;
+ int ii;
+
+ Fts5Buffer buf1 = {0,0,0};
+ Fts5Buffer buf2 = {0,0,0};
+
+ ii = pLeaf->szLeaf;
+ while( ii<pLeaf->nn && p->rc==SQLITE_OK ){
+ int res;
+ int iOff;
+ int nIncr;
+
+ ii += fts5GetVarint32(&pLeaf->p[ii], nIncr);
+ iTermOff += nIncr;
+ iOff = iTermOff;
+
+ if( iOff>=pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ }else if( iTermOff==nIncr ){
+ int nByte;
+ iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
+ if( (iOff+nByte)>pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ fts5BufferSet(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
+ }
+ }else{
+ int nKeep, nByte;
+ iOff += fts5GetVarint32(&pLeaf->p[iOff], nKeep);
+ iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
+ if( nKeep>buf1.n || (iOff+nByte)>pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ buf1.n = nKeep;
+ fts5BufferAppendBlob(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
+ }
+
+ if( p->rc==SQLITE_OK ){
+ res = fts5BufferCompare(&buf1, &buf2);
+ if( res<=0 ) p->rc = FTS5_CORRUPT;
+ }
+ }
+ fts5BufferSet(&p->rc, &buf2, buf1.n, buf1.p);
+ }
+
+ fts5BufferFree(&buf1);
+ fts5BufferFree(&buf2);
+}
+
+static void fts5IndexIntegrityCheckSegment(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5StructureSegment *pSeg /* Segment to check internal consistency */
+){
+ Fts5Config *pConfig = p->pConfig;
+ sqlite3_stmt *pStmt = 0;
+ int rc2;
+ int iIdxPrevLeaf = pSeg->pgnoFirst-1;
+ int iDlidxPrevLeaf = pSeg->pgnoLast;
+
+ if( pSeg->pgnoFirst==0 ) return;
+
+ fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf(
"SELECT segid, term, (pgno>>1), (pgno&1) FROM %Q.'%q_idx' WHERE segid=%d "
"ORDER BY 1, 2",
- pConfig->zDb, pConfig->zName, pSeg->iSegid
- ));
-
- /* Iterate through the b-tree hierarchy. */
- while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
- i64 iRow; /* Rowid for this leaf */
- Fts5Data *pLeaf; /* Data for this leaf */
-
+ pConfig->zDb, pConfig->zName, pSeg->iSegid
+ ));
+
+ /* Iterate through the b-tree hierarchy. */
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
+ i64 iRow; /* Rowid for this leaf */
+ Fts5Data *pLeaf; /* Data for this leaf */
+
const char *zIdxTerm = (const char*)sqlite3_column_blob(pStmt, 1);
- int nIdxTerm = sqlite3_column_bytes(pStmt, 1);
- int iIdxLeaf = sqlite3_column_int(pStmt, 2);
- int bIdxDlidx = sqlite3_column_int(pStmt, 3);
-
+ int nIdxTerm = sqlite3_column_bytes(pStmt, 1);
+ int iIdxLeaf = sqlite3_column_int(pStmt, 2);
+ int bIdxDlidx = sqlite3_column_int(pStmt, 3);
+
/* If the leaf in question has already been trimmed from the segment,
- ** ignore this b-tree entry. Otherwise, load it into memory. */
- if( iIdxLeaf<pSeg->pgnoFirst ) continue;
- iRow = FTS5_SEGMENT_ROWID(pSeg->iSegid, iIdxLeaf);
- pLeaf = fts5LeafRead(p, iRow);
- if( pLeaf==0 ) break;
-
- /* Check that the leaf contains at least one term, and that it is equal
- ** to or larger than the split-key in zIdxTerm. Also check that if there
- ** is also a rowid pointer within the leaf page header, it points to a
- ** location before the term. */
- if( pLeaf->nn<=pLeaf->szLeaf ){
- p->rc = FTS5_CORRUPT;
- }else{
- int iOff; /* Offset of first term on leaf */
- int iRowidOff; /* Offset of first rowid on leaf */
- int nTerm; /* Size of term on leaf in bytes */
- int res; /* Comparison of term and split-key */
-
- iOff = fts5LeafFirstTermOff(pLeaf);
- iRowidOff = fts5LeafFirstRowidOff(pLeaf);
+ ** ignore this b-tree entry. Otherwise, load it into memory. */
+ if( iIdxLeaf<pSeg->pgnoFirst ) continue;
+ iRow = FTS5_SEGMENT_ROWID(pSeg->iSegid, iIdxLeaf);
+ pLeaf = fts5LeafRead(p, iRow);
+ if( pLeaf==0 ) break;
+
+ /* Check that the leaf contains at least one term, and that it is equal
+ ** to or larger than the split-key in zIdxTerm. Also check that if there
+ ** is also a rowid pointer within the leaf page header, it points to a
+ ** location before the term. */
+ if( pLeaf->nn<=pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ int iOff; /* Offset of first term on leaf */
+ int iRowidOff; /* Offset of first rowid on leaf */
+ int nTerm; /* Size of term on leaf in bytes */
+ int res; /* Comparison of term and split-key */
+
+ iOff = fts5LeafFirstTermOff(pLeaf);
+ iRowidOff = fts5LeafFirstRowidOff(pLeaf);
if( iRowidOff>=iOff || iOff>=pLeaf->szLeaf ){
- p->rc = FTS5_CORRUPT;
- }else{
- iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
+ p->rc = FTS5_CORRUPT;
+ }else{
+ iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
- if( res==0 ) res = nTerm - nIdxTerm;
- if( res<0 ) p->rc = FTS5_CORRUPT;
- }
-
- fts5IntegrityCheckPgidx(p, pLeaf);
- }
- fts5DataRelease(pLeaf);
- if( p->rc ) break;
-
- /* Now check that the iter.nEmpty leaves following the current leaf
- ** (a) exist and (b) contain no terms. */
- fts5IndexIntegrityCheckEmpty(
- p, pSeg, iIdxPrevLeaf+1, iDlidxPrevLeaf+1, iIdxLeaf-1
- );
- if( p->rc ) break;
-
- /* If there is a doclist-index, check that it looks right. */
- if( bIdxDlidx ){
- Fts5DlidxIter *pDlidx = 0; /* For iterating through doclist index */
- int iPrevLeaf = iIdxLeaf;
- int iSegid = pSeg->iSegid;
- int iPg = 0;
- i64 iKey;
-
- for(pDlidx=fts5DlidxIterInit(p, 0, iSegid, iIdxLeaf);
- fts5DlidxIterEof(p, pDlidx)==0;
- fts5DlidxIterNext(p, pDlidx)
- ){
-
- /* Check any rowid-less pages that occur before the current leaf. */
- for(iPg=iPrevLeaf+1; iPg<fts5DlidxIterPgno(pDlidx); iPg++){
- iKey = FTS5_SEGMENT_ROWID(iSegid, iPg);
- pLeaf = fts5DataRead(p, iKey);
- if( pLeaf ){
- if( fts5LeafFirstRowidOff(pLeaf)!=0 ) p->rc = FTS5_CORRUPT;
- fts5DataRelease(pLeaf);
- }
- }
- iPrevLeaf = fts5DlidxIterPgno(pDlidx);
-
- /* Check that the leaf page indicated by the iterator really does
- ** contain the rowid suggested by the same. */
- iKey = FTS5_SEGMENT_ROWID(iSegid, iPrevLeaf);
- pLeaf = fts5DataRead(p, iKey);
- if( pLeaf ){
- i64 iRowid;
- int iRowidOff = fts5LeafFirstRowidOff(pLeaf);
- ASSERT_SZLEAF_OK(pLeaf);
- if( iRowidOff>=pLeaf->szLeaf ){
- p->rc = FTS5_CORRUPT;
- }else{
- fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid);
- if( iRowid!=fts5DlidxIterRowid(pDlidx) ) p->rc = FTS5_CORRUPT;
- }
- fts5DataRelease(pLeaf);
- }
- }
-
- iDlidxPrevLeaf = iPg;
- fts5DlidxIterFree(pDlidx);
- fts5TestDlidxReverse(p, iSegid, iIdxLeaf);
- }else{
- iDlidxPrevLeaf = pSeg->pgnoLast;
- /* TODO: Check there is no doclist index */
- }
-
- iIdxPrevLeaf = iIdxLeaf;
- }
-
- rc2 = sqlite3_finalize(pStmt);
- if( p->rc==SQLITE_OK ) p->rc = rc2;
-
- /* Page iter.iLeaf must now be the rightmost leaf-page in the segment */
-#if 0
- if( p->rc==SQLITE_OK && iter.iLeaf!=pSeg->pgnoLast ){
- p->rc = FTS5_CORRUPT;
- }
-#endif
-}
-
-
-/*
+ if( res==0 ) res = nTerm - nIdxTerm;
+ if( res<0 ) p->rc = FTS5_CORRUPT;
+ }
+
+ fts5IntegrityCheckPgidx(p, pLeaf);
+ }
+ fts5DataRelease(pLeaf);
+ if( p->rc ) break;
+
+ /* Now check that the iter.nEmpty leaves following the current leaf
+ ** (a) exist and (b) contain no terms. */
+ fts5IndexIntegrityCheckEmpty(
+ p, pSeg, iIdxPrevLeaf+1, iDlidxPrevLeaf+1, iIdxLeaf-1
+ );
+ if( p->rc ) break;
+
+ /* If there is a doclist-index, check that it looks right. */
+ if( bIdxDlidx ){
+ Fts5DlidxIter *pDlidx = 0; /* For iterating through doclist index */
+ int iPrevLeaf = iIdxLeaf;
+ int iSegid = pSeg->iSegid;
+ int iPg = 0;
+ i64 iKey;
+
+ for(pDlidx=fts5DlidxIterInit(p, 0, iSegid, iIdxLeaf);
+ fts5DlidxIterEof(p, pDlidx)==0;
+ fts5DlidxIterNext(p, pDlidx)
+ ){
+
+ /* Check any rowid-less pages that occur before the current leaf. */
+ for(iPg=iPrevLeaf+1; iPg<fts5DlidxIterPgno(pDlidx); iPg++){
+ iKey = FTS5_SEGMENT_ROWID(iSegid, iPg);
+ pLeaf = fts5DataRead(p, iKey);
+ if( pLeaf ){
+ if( fts5LeafFirstRowidOff(pLeaf)!=0 ) p->rc = FTS5_CORRUPT;
+ fts5DataRelease(pLeaf);
+ }
+ }
+ iPrevLeaf = fts5DlidxIterPgno(pDlidx);
+
+ /* Check that the leaf page indicated by the iterator really does
+ ** contain the rowid suggested by the same. */
+ iKey = FTS5_SEGMENT_ROWID(iSegid, iPrevLeaf);
+ pLeaf = fts5DataRead(p, iKey);
+ if( pLeaf ){
+ i64 iRowid;
+ int iRowidOff = fts5LeafFirstRowidOff(pLeaf);
+ ASSERT_SZLEAF_OK(pLeaf);
+ if( iRowidOff>=pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid);
+ if( iRowid!=fts5DlidxIterRowid(pDlidx) ) p->rc = FTS5_CORRUPT;
+ }
+ fts5DataRelease(pLeaf);
+ }
+ }
+
+ iDlidxPrevLeaf = iPg;
+ fts5DlidxIterFree(pDlidx);
+ fts5TestDlidxReverse(p, iSegid, iIdxLeaf);
+ }else{
+ iDlidxPrevLeaf = pSeg->pgnoLast;
+ /* TODO: Check there is no doclist index */
+ }
+
+ iIdxPrevLeaf = iIdxLeaf;
+ }
+
+ rc2 = sqlite3_finalize(pStmt);
+ if( p->rc==SQLITE_OK ) p->rc = rc2;
+
+ /* Page iter.iLeaf must now be the rightmost leaf-page in the segment */
+#if 0
+ if( p->rc==SQLITE_OK && iter.iLeaf!=pSeg->pgnoLast ){
+ p->rc = FTS5_CORRUPT;
+ }
+#endif
+}
+
+
+/*
** Run internal checks to ensure that the FTS index (a) is internally
-** consistent and (b) contains entries for which the XOR of the checksums
-** as calculated by sqlite3Fts5IndexEntryCksum() is cksum.
-**
-** Return SQLITE_CORRUPT if any of the internal checks fail, or if the
-** checksum does not match. Return SQLITE_OK if all checks pass without
-** error, or some other SQLite error code if another error (e.g. OOM)
-** occurs.
-*/
+** consistent and (b) contains entries for which the XOR of the checksums
+** as calculated by sqlite3Fts5IndexEntryCksum() is cksum.
+**
+** Return SQLITE_CORRUPT if any of the internal checks fail, or if the
+** checksum does not match. Return SQLITE_OK if all checks pass without
+** error, or some other SQLite error code if another error (e.g. OOM)
+** occurs.
+*/
static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){
- int eDetail = p->pConfig->eDetail;
- u64 cksum2 = 0; /* Checksum based on contents of indexes */
- Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */
- Fts5Iter *pIter; /* Used to iterate through entire index */
- Fts5Structure *pStruct; /* Index structure */
+ int eDetail = p->pConfig->eDetail;
+ u64 cksum2 = 0; /* Checksum based on contents of indexes */
+ Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */
+ Fts5Iter *pIter; /* Used to iterate through entire index */
+ Fts5Structure *pStruct; /* Index structure */
int iLvl, iSeg;
-
-#ifdef SQLITE_DEBUG
- /* Used by extra internal tests only run if NDEBUG is not defined */
- u64 cksum3 = 0; /* Checksum based on contents of indexes */
- Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */
-#endif
- const int flags = FTS5INDEX_QUERY_NOOUTPUT;
-
- /* Load the FTS index structure */
- pStruct = fts5StructureRead(p);
+
+#ifdef SQLITE_DEBUG
+ /* Used by extra internal tests only run if NDEBUG is not defined */
+ u64 cksum3 = 0; /* Checksum based on contents of indexes */
+ Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */
+#endif
+ const int flags = FTS5INDEX_QUERY_NOOUTPUT;
+
+ /* Load the FTS index structure */
+ pStruct = fts5StructureRead(p);
if( pStruct==0 ){
assert( p->rc!=SQLITE_OK );
return fts5IndexReturn(p);
}
-
- /* Check that the internal nodes of each segment match the leaves */
+
+ /* Check that the internal nodes of each segment match the leaves */
for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
fts5IndexIntegrityCheckSegment(p, pSeg);
- }
- }
-
- /* The cksum argument passed to this function is a checksum calculated
- ** based on all expected entries in the FTS index (including prefix index
- ** entries). This block checks that a checksum calculated based on the
- ** actual contents of FTS index is identical.
- **
- ** Two versions of the same checksum are calculated. The first (stack
- ** variable cksum2) based on entries extracted from the full-text index
+ }
+ }
+
+ /* The cksum argument passed to this function is a checksum calculated
+ ** based on all expected entries in the FTS index (including prefix index
+ ** entries). This block checks that a checksum calculated based on the
+ ** actual contents of FTS index is identical.
+ **
+ ** Two versions of the same checksum are calculated. The first (stack
+ ** variable cksum2) based on entries extracted from the full-text index
** while doing a linear scan of each individual index in turn.
- **
- ** As each term visited by the linear scans, a separate query for the
- ** same term is performed. cksum3 is calculated based on the entries
- ** extracted by these queries.
- */
- for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, -1, 0, &pIter);
- fts5MultiIterEof(p, pIter)==0;
- fts5MultiIterNext(p, pIter, 0, 0)
- ){
- int n; /* Size of term in bytes */
- i64 iPos = 0; /* Position read from poslist */
- int iOff = 0; /* Offset within poslist */
- i64 iRowid = fts5MultiIterRowid(pIter);
- char *z = (char*)fts5MultiIterTerm(pIter, &n);
-
- /* If this is a new term, query for it. Update cksum3 with the results. */
- fts5TestTerm(p, &term, z, n, cksum2, &cksum3);
-
- if( eDetail==FTS5_DETAIL_NONE ){
- if( 0==fts5MultiIterIsEmpty(p, pIter) ){
- cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, 0, 0, -1, z, n);
- }
- }else{
- poslist.n = 0;
- fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst], 0, &poslist);
+ **
+ ** As each term visited by the linear scans, a separate query for the
+ ** same term is performed. cksum3 is calculated based on the entries
+ ** extracted by these queries.
+ */
+ for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, -1, 0, &pIter);
+ fts5MultiIterEof(p, pIter)==0;
+ fts5MultiIterNext(p, pIter, 0, 0)
+ ){
+ int n; /* Size of term in bytes */
+ i64 iPos = 0; /* Position read from poslist */
+ int iOff = 0; /* Offset within poslist */
+ i64 iRowid = fts5MultiIterRowid(pIter);
+ char *z = (char*)fts5MultiIterTerm(pIter, &n);
+
+ /* If this is a new term, query for it. Update cksum3 with the results. */
+ fts5TestTerm(p, &term, z, n, cksum2, &cksum3);
+
+ if( eDetail==FTS5_DETAIL_NONE ){
+ if( 0==fts5MultiIterIsEmpty(p, pIter) ){
+ cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, 0, 0, -1, z, n);
+ }
+ }else{
+ poslist.n = 0;
+ fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst], 0, &poslist);
fts5BufferAppendBlob(&p->rc, &poslist, 4, (const u8*)"\0\0\0\0");
- while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){
- int iCol = FTS5_POS2COLUMN(iPos);
- int iTokOff = FTS5_POS2OFFSET(iPos);
- cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n);
- }
- }
- }
- fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
-
- fts5MultiIterFree(pIter);
+ while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){
+ int iCol = FTS5_POS2COLUMN(iPos);
+ int iTokOff = FTS5_POS2OFFSET(iPos);
+ cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n);
+ }
+ }
+ }
+ fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
+
+ fts5MultiIterFree(pIter);
if( p->rc==SQLITE_OK && bUseCksum && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
-
- fts5StructureRelease(pStruct);
-#ifdef SQLITE_DEBUG
- fts5BufferFree(&term);
-#endif
- fts5BufferFree(&poslist);
- return fts5IndexReturn(p);
-}
-
-/*************************************************************************
-**************************************************************************
-** Below this point is the implementation of the fts5_decode() scalar
-** function only.
-*/
-
+
+ fts5StructureRelease(pStruct);
+#ifdef SQLITE_DEBUG
+ fts5BufferFree(&term);
+#endif
+ fts5BufferFree(&poslist);
+ return fts5IndexReturn(p);
+}
+
+/*************************************************************************
+**************************************************************************
+** Below this point is the implementation of the fts5_decode() scalar
+** function only.
+*/
+
#ifdef SQLITE_TEST
-/*
-** Decode a segment-data rowid from the %_data table. This function is
-** the opposite of macro FTS5_SEGMENT_ROWID().
-*/
-static void fts5DecodeRowid(
- i64 iRowid, /* Rowid from %_data table */
- int *piSegid, /* OUT: Segment id */
- int *pbDlidx, /* OUT: Dlidx flag */
- int *piHeight, /* OUT: Height */
- int *piPgno /* OUT: Page number */
-){
- *piPgno = (int)(iRowid & (((i64)1 << FTS5_DATA_PAGE_B) - 1));
- iRowid >>= FTS5_DATA_PAGE_B;
-
- *piHeight = (int)(iRowid & (((i64)1 << FTS5_DATA_HEIGHT_B) - 1));
- iRowid >>= FTS5_DATA_HEIGHT_B;
-
- *pbDlidx = (int)(iRowid & 0x0001);
- iRowid >>= FTS5_DATA_DLI_B;
-
- *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1));
-}
+/*
+** Decode a segment-data rowid from the %_data table. This function is
+** the opposite of macro FTS5_SEGMENT_ROWID().
+*/
+static void fts5DecodeRowid(
+ i64 iRowid, /* Rowid from %_data table */
+ int *piSegid, /* OUT: Segment id */
+ int *pbDlidx, /* OUT: Dlidx flag */
+ int *piHeight, /* OUT: Height */
+ int *piPgno /* OUT: Page number */
+){
+ *piPgno = (int)(iRowid & (((i64)1 << FTS5_DATA_PAGE_B) - 1));
+ iRowid >>= FTS5_DATA_PAGE_B;
+
+ *piHeight = (int)(iRowid & (((i64)1 << FTS5_DATA_HEIGHT_B) - 1));
+ iRowid >>= FTS5_DATA_HEIGHT_B;
+
+ *pbDlidx = (int)(iRowid & 0x0001);
+ iRowid >>= FTS5_DATA_DLI_B;
+
+ *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1));
+}
#endif /* SQLITE_TEST */
-
+
#ifdef SQLITE_TEST
-static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){
- int iSegid, iHeight, iPgno, bDlidx; /* Rowid compenents */
- fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno);
-
- if( iSegid==0 ){
- if( iKey==FTS5_AVERAGES_ROWID ){
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} ");
- }else{
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}");
- }
- }
- else{
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}",
- bDlidx ? "dlidx " : "", iSegid, iHeight, iPgno
- );
- }
-}
+static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){
+ int iSegid, iHeight, iPgno, bDlidx; /* Rowid compenents */
+ fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno);
+
+ if( iSegid==0 ){
+ if( iKey==FTS5_AVERAGES_ROWID ){
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} ");
+ }else{
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}");
+ }
+ }
+ else{
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}",
+ bDlidx ? "dlidx " : "", iSegid, iHeight, iPgno
+ );
+ }
+}
#endif /* SQLITE_TEST */
-
+
#ifdef SQLITE_TEST
-static void fts5DebugStructure(
- int *pRc, /* IN/OUT: error code */
- Fts5Buffer *pBuf,
- Fts5Structure *p
-){
- int iLvl, iSeg; /* Iterate through levels, segments */
-
- for(iLvl=0; iLvl<p->nLevel; iLvl++){
- Fts5StructureLevel *pLvl = &p->aLevel[iLvl];
+static void fts5DebugStructure(
+ int *pRc, /* IN/OUT: error code */
+ Fts5Buffer *pBuf,
+ Fts5Structure *p
+){
+ int iLvl, iSeg; /* Iterate through levels, segments */
+
+ for(iLvl=0; iLvl<p->nLevel; iLvl++){
+ Fts5StructureLevel *pLvl = &p->aLevel[iLvl];
sqlite3Fts5BufferAppendPrintf(pRc, pBuf,
- " {lvl=%d nMerge=%d nSeg=%d", iLvl, pLvl->nMerge, pLvl->nSeg
- );
- for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
- Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
+ " {lvl=%d nMerge=%d nSeg=%d", iLvl, pLvl->nMerge, pLvl->nSeg
+ );
+ for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
+ Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d}",
- pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast
- );
- }
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}");
- }
-}
+ pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast
+ );
+ }
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}");
+ }
+}
#endif /* SQLITE_TEST */
-
+
#ifdef SQLITE_TEST
-/*
-** This is part of the fts5_decode() debugging aid.
-**
-** Arguments pBlob/nBlob contain a serialized Fts5Structure object. This
-** function appends a human-readable representation of the same object
+/*
+** This is part of the fts5_decode() debugging aid.
+**
+** Arguments pBlob/nBlob contain a serialized Fts5Structure object. This
+** function appends a human-readable representation of the same object
** to the buffer passed as the second argument.
-*/
-static void fts5DecodeStructure(
- int *pRc, /* IN/OUT: error code */
- Fts5Buffer *pBuf,
- const u8 *pBlob, int nBlob
-){
- int rc; /* Return code */
- Fts5Structure *p = 0; /* Decoded structure object */
-
- rc = fts5StructureDecode(pBlob, nBlob, 0, &p);
- if( rc!=SQLITE_OK ){
- *pRc = rc;
- return;
- }
-
- fts5DebugStructure(pRc, pBuf, p);
- fts5StructureRelease(p);
-}
+*/
+static void fts5DecodeStructure(
+ int *pRc, /* IN/OUT: error code */
+ Fts5Buffer *pBuf,
+ const u8 *pBlob, int nBlob
+){
+ int rc; /* Return code */
+ Fts5Structure *p = 0; /* Decoded structure object */
+
+ rc = fts5StructureDecode(pBlob, nBlob, 0, &p);
+ if( rc!=SQLITE_OK ){
+ *pRc = rc;
+ return;
+ }
+
+ fts5DebugStructure(pRc, pBuf, p);
+ fts5StructureRelease(p);
+}
#endif /* SQLITE_TEST */
-
+
#ifdef SQLITE_TEST
-/*
-** This is part of the fts5_decode() debugging aid.
-**
+/*
+** This is part of the fts5_decode() debugging aid.
+**
** Arguments pBlob/nBlob contain an "averages" record. This function
** appends a human-readable representation of record to the buffer passed
** as the second argument.
-*/
-static void fts5DecodeAverages(
- int *pRc, /* IN/OUT: error code */
- Fts5Buffer *pBuf,
- const u8 *pBlob, int nBlob
-){
- int i = 0;
- const char *zSpace = "";
-
- while( i<nBlob ){
- u64 iVal;
- i += sqlite3Fts5GetVarint(&pBlob[i], &iVal);
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "%s%d", zSpace, (int)iVal);
- zSpace = " ";
- }
-}
+*/
+static void fts5DecodeAverages(
+ int *pRc, /* IN/OUT: error code */
+ Fts5Buffer *pBuf,
+ const u8 *pBlob, int nBlob
+){
+ int i = 0;
+ const char *zSpace = "";
+
+ while( i<nBlob ){
+ u64 iVal;
+ i += sqlite3Fts5GetVarint(&pBlob[i], &iVal);
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "%s%d", zSpace, (int)iVal);
+ zSpace = " ";
+ }
+}
#endif /* SQLITE_TEST */
-
+
#ifdef SQLITE_TEST
-/*
-** Buffer (a/n) is assumed to contain a list of serialized varints. Read
-** each varint and append its string representation to buffer pBuf. Return
-** after either the input buffer is exhausted or a 0 value is read.
-**
-** The return value is the number of bytes read from the input buffer.
-*/
-static int fts5DecodePoslist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){
- int iOff = 0;
- while( iOff<n ){
- int iVal;
- iOff += fts5GetVarint32(&a[iOff], iVal);
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %d", iVal);
- }
- return iOff;
-}
+/*
+** Buffer (a/n) is assumed to contain a list of serialized varints. Read
+** each varint and append its string representation to buffer pBuf. Return
+** after either the input buffer is exhausted or a 0 value is read.
+**
+** The return value is the number of bytes read from the input buffer.
+*/
+static int fts5DecodePoslist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){
+ int iOff = 0;
+ while( iOff<n ){
+ int iVal;
+ iOff += fts5GetVarint32(&a[iOff], iVal);
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %d", iVal);
+ }
+ return iOff;
+}
#endif /* SQLITE_TEST */
-
+
#ifdef SQLITE_TEST
-/*
-** The start of buffer (a/n) contains the start of a doclist. The doclist
-** may or may not finish within the buffer. This function appends a text
-** representation of the part of the doclist that is present to buffer
+/*
+** The start of buffer (a/n) contains the start of a doclist. The doclist
+** may or may not finish within the buffer. This function appends a text
+** representation of the part of the doclist that is present to buffer
** pBuf.
-**
-** The return value is the number of bytes read from the input buffer.
-*/
-static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){
- i64 iDocid = 0;
- int iOff = 0;
-
- if( n>0 ){
- iOff = sqlite3Fts5GetVarint(a, (u64*)&iDocid);
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid);
- }
- while( iOff<n ){
- int nPos;
- int bDel;
- iOff += fts5GetPoslistSize(&a[iOff], &nPos, &bDel);
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " nPos=%d%s", nPos, bDel?"*":"");
- iOff += fts5DecodePoslist(pRc, pBuf, &a[iOff], MIN(n-iOff, nPos));
- if( iOff<n ){
- i64 iDelta;
- iOff += sqlite3Fts5GetVarint(&a[iOff], (u64*)&iDelta);
- iDocid += iDelta;
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid);
- }
- }
-
- return iOff;
-}
+**
+** The return value is the number of bytes read from the input buffer.
+*/
+static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){
+ i64 iDocid = 0;
+ int iOff = 0;
+
+ if( n>0 ){
+ iOff = sqlite3Fts5GetVarint(a, (u64*)&iDocid);
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid);
+ }
+ while( iOff<n ){
+ int nPos;
+ int bDel;
+ iOff += fts5GetPoslistSize(&a[iOff], &nPos, &bDel);
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " nPos=%d%s", nPos, bDel?"*":"");
+ iOff += fts5DecodePoslist(pRc, pBuf, &a[iOff], MIN(n-iOff, nPos));
+ if( iOff<n ){
+ i64 iDelta;
+ iOff += sqlite3Fts5GetVarint(&a[iOff], (u64*)&iDelta);
+ iDocid += iDelta;
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid);
+ }
+ }
+
+ return iOff;
+}
#endif /* SQLITE_TEST */
-
+
#ifdef SQLITE_TEST
-/*
+/*
** This function is part of the fts5_decode() debugging function. It is
-** only ever used with detail=none tables.
-**
-** Buffer (pData/nData) contains a doclist in the format used by detail=none
-** tables. This function appends a human-readable version of that list to
-** buffer pBuf.
-**
-** If *pRc is other than SQLITE_OK when this function is called, it is a
-** no-op. If an OOM or other error occurs within this function, *pRc is
-** set to an SQLite error code before returning. The final state of buffer
-** pBuf is undefined in this case.
-*/
-static void fts5DecodeRowidList(
- int *pRc, /* IN/OUT: Error code */
- Fts5Buffer *pBuf, /* Buffer to append text to */
- const u8 *pData, int nData /* Data to decode list-of-rowids from */
-){
- int i = 0;
- i64 iRowid = 0;
-
- while( i<nData ){
- const char *zApp = "";
- u64 iVal;
- i += sqlite3Fts5GetVarint(&pData[i], &iVal);
- iRowid += iVal;
-
- if( i<nData && pData[i]==0x00 ){
- i++;
- if( i<nData && pData[i]==0x00 ){
- i++;
- zApp = "+";
- }else{
- zApp = "*";
- }
- }
-
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp);
- }
-}
+** only ever used with detail=none tables.
+**
+** Buffer (pData/nData) contains a doclist in the format used by detail=none
+** tables. This function appends a human-readable version of that list to
+** buffer pBuf.
+**
+** If *pRc is other than SQLITE_OK when this function is called, it is a
+** no-op. If an OOM or other error occurs within this function, *pRc is
+** set to an SQLite error code before returning. The final state of buffer
+** pBuf is undefined in this case.
+*/
+static void fts5DecodeRowidList(
+ int *pRc, /* IN/OUT: Error code */
+ Fts5Buffer *pBuf, /* Buffer to append text to */
+ const u8 *pData, int nData /* Data to decode list-of-rowids from */
+){
+ int i = 0;
+ i64 iRowid = 0;
+
+ while( i<nData ){
+ const char *zApp = "";
+ u64 iVal;
+ i += sqlite3Fts5GetVarint(&pData[i], &iVal);
+ iRowid += iVal;
+
+ if( i<nData && pData[i]==0x00 ){
+ i++;
+ if( i<nData && pData[i]==0x00 ){
+ i++;
+ zApp = "+";
+ }else{
+ zApp = "*";
+ }
+ }
+
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp);
+ }
+}
#endif /* SQLITE_TEST */
-
+
#ifdef SQLITE_TEST
-/*
-** The implementation of user-defined scalar function fts5_decode().
-*/
-static void fts5DecodeFunction(
- sqlite3_context *pCtx, /* Function call context */
- int nArg, /* Number of args (always 2) */
- sqlite3_value **apVal /* Function arguments */
-){
- i64 iRowid; /* Rowid for record being decoded */
- int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */
- const u8 *aBlob; int n; /* Record to decode */
- u8 *a = 0;
- Fts5Buffer s; /* Build up text to return here */
- int rc = SQLITE_OK; /* Return code */
+/*
+** The implementation of user-defined scalar function fts5_decode().
+*/
+static void fts5DecodeFunction(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args (always 2) */
+ sqlite3_value **apVal /* Function arguments */
+){
+ i64 iRowid; /* Rowid for record being decoded */
+ int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */
+ const u8 *aBlob; int n; /* Record to decode */
+ u8 *a = 0;
+ Fts5Buffer s; /* Build up text to return here */
+ int rc = SQLITE_OK; /* Return code */
sqlite3_int64 nSpace = 0;
- int eDetailNone = (sqlite3_user_data(pCtx)!=0);
-
- assert( nArg==2 );
- UNUSED_PARAM(nArg);
- memset(&s, 0, sizeof(Fts5Buffer));
- iRowid = sqlite3_value_int64(apVal[0]);
-
- /* Make a copy of the second argument (a blob) in aBlob[]. The aBlob[]
- ** copy is followed by FTS5_DATA_ZERO_PADDING 0x00 bytes, which prevents
- ** buffer overreads even if the record is corrupt. */
- n = sqlite3_value_bytes(apVal[1]);
- aBlob = sqlite3_value_blob(apVal[1]);
- nSpace = n + FTS5_DATA_ZERO_PADDING;
- a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
- if( a==0 ) goto decode_out;
+ int eDetailNone = (sqlite3_user_data(pCtx)!=0);
+
+ assert( nArg==2 );
+ UNUSED_PARAM(nArg);
+ memset(&s, 0, sizeof(Fts5Buffer));
+ iRowid = sqlite3_value_int64(apVal[0]);
+
+ /* Make a copy of the second argument (a blob) in aBlob[]. The aBlob[]
+ ** copy is followed by FTS5_DATA_ZERO_PADDING 0x00 bytes, which prevents
+ ** buffer overreads even if the record is corrupt. */
+ n = sqlite3_value_bytes(apVal[1]);
+ aBlob = sqlite3_value_blob(apVal[1]);
+ nSpace = n + FTS5_DATA_ZERO_PADDING;
+ a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
+ if( a==0 ) goto decode_out;
if( n>0 ) memcpy(a, aBlob, n);
-
- fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);
-
- fts5DebugRowid(&rc, &s, iRowid);
- if( bDlidx ){
- Fts5Data dlidx;
- Fts5DlidxLvl lvl;
-
- dlidx.p = a;
- dlidx.nn = n;
-
- memset(&lvl, 0, sizeof(Fts5DlidxLvl));
- lvl.pData = &dlidx;
- lvl.iLeafPgno = iPgno;
-
- for(fts5DlidxLvlNext(&lvl); lvl.bEof==0; fts5DlidxLvlNext(&lvl)){
+
+ fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);
+
+ fts5DebugRowid(&rc, &s, iRowid);
+ if( bDlidx ){
+ Fts5Data dlidx;
+ Fts5DlidxLvl lvl;
+
+ dlidx.p = a;
+ dlidx.nn = n;
+
+ memset(&lvl, 0, sizeof(Fts5DlidxLvl));
+ lvl.pData = &dlidx;
+ lvl.iLeafPgno = iPgno;
+
+ for(fts5DlidxLvlNext(&lvl); lvl.bEof==0; fts5DlidxLvlNext(&lvl)){
sqlite3Fts5BufferAppendPrintf(&rc, &s,
- " %d(%lld)", lvl.iLeafPgno, lvl.iRowid
- );
- }
- }else if( iSegid==0 ){
- if( iRowid==FTS5_AVERAGES_ROWID ){
- fts5DecodeAverages(&rc, &s, a, n);
- }else{
- fts5DecodeStructure(&rc, &s, a, n);
- }
- }else if( eDetailNone ){
- Fts5Buffer term; /* Current term read from page */
- int szLeaf;
- int iPgidxOff = szLeaf = fts5GetU16(&a[2]);
- int iTermOff;
- int nKeep = 0;
- int iOff;
-
- memset(&term, 0, sizeof(Fts5Buffer));
-
- /* Decode any entries that occur before the first term. */
- if( szLeaf<n ){
- iPgidxOff += fts5GetVarint32(&a[iPgidxOff], iTermOff);
- }else{
- iTermOff = szLeaf;
- }
- fts5DecodeRowidList(&rc, &s, &a[4], iTermOff-4);
-
- iOff = iTermOff;
- while( iOff<szLeaf ){
- int nAppend;
-
- /* Read the term data for the next term*/
- iOff += fts5GetVarint32(&a[iOff], nAppend);
- term.n = nKeep;
- fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]);
- sqlite3Fts5BufferAppendPrintf(
- &rc, &s, " term=%.*s", term.n, (const char*)term.p
- );
- iOff += nAppend;
-
- /* Figure out where the doclist for this term ends */
- if( iPgidxOff<n ){
- int nIncr;
- iPgidxOff += fts5GetVarint32(&a[iPgidxOff], nIncr);
- iTermOff += nIncr;
- }else{
- iTermOff = szLeaf;
- }
-
- fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff);
- iOff = iTermOff;
- if( iOff<szLeaf ){
- iOff += fts5GetVarint32(&a[iOff], nKeep);
- }
- }
-
- fts5BufferFree(&term);
- }else{
- Fts5Buffer term; /* Current term read from page */
- int szLeaf; /* Offset of pgidx in a[] */
- int iPgidxOff;
- int iPgidxPrev = 0; /* Previous value read from pgidx */
- int iTermOff = 0;
- int iRowidOff = 0;
- int iOff;
- int nDoclist;
-
- memset(&term, 0, sizeof(Fts5Buffer));
-
- if( n<4 ){
- sqlite3Fts5BufferSet(&rc, &s, 7, (const u8*)"corrupt");
- goto decode_out;
- }else{
- iRowidOff = fts5GetU16(&a[0]);
- iPgidxOff = szLeaf = fts5GetU16(&a[2]);
- if( iPgidxOff<n ){
- fts5GetVarint32(&a[iPgidxOff], iTermOff);
+ " %d(%lld)", lvl.iLeafPgno, lvl.iRowid
+ );
+ }
+ }else if( iSegid==0 ){
+ if( iRowid==FTS5_AVERAGES_ROWID ){
+ fts5DecodeAverages(&rc, &s, a, n);
+ }else{
+ fts5DecodeStructure(&rc, &s, a, n);
+ }
+ }else if( eDetailNone ){
+ Fts5Buffer term; /* Current term read from page */
+ int szLeaf;
+ int iPgidxOff = szLeaf = fts5GetU16(&a[2]);
+ int iTermOff;
+ int nKeep = 0;
+ int iOff;
+
+ memset(&term, 0, sizeof(Fts5Buffer));
+
+ /* Decode any entries that occur before the first term. */
+ if( szLeaf<n ){
+ iPgidxOff += fts5GetVarint32(&a[iPgidxOff], iTermOff);
+ }else{
+ iTermOff = szLeaf;
+ }
+ fts5DecodeRowidList(&rc, &s, &a[4], iTermOff-4);
+
+ iOff = iTermOff;
+ while( iOff<szLeaf ){
+ int nAppend;
+
+ /* Read the term data for the next term*/
+ iOff += fts5GetVarint32(&a[iOff], nAppend);
+ term.n = nKeep;
+ fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]);
+ sqlite3Fts5BufferAppendPrintf(
+ &rc, &s, " term=%.*s", term.n, (const char*)term.p
+ );
+ iOff += nAppend;
+
+ /* Figure out where the doclist for this term ends */
+ if( iPgidxOff<n ){
+ int nIncr;
+ iPgidxOff += fts5GetVarint32(&a[iPgidxOff], nIncr);
+ iTermOff += nIncr;
+ }else{
+ iTermOff = szLeaf;
+ }
+
+ fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff);
+ iOff = iTermOff;
+ if( iOff<szLeaf ){
+ iOff += fts5GetVarint32(&a[iOff], nKeep);
+ }
+ }
+
+ fts5BufferFree(&term);
+ }else{
+ Fts5Buffer term; /* Current term read from page */
+ int szLeaf; /* Offset of pgidx in a[] */
+ int iPgidxOff;
+ int iPgidxPrev = 0; /* Previous value read from pgidx */
+ int iTermOff = 0;
+ int iRowidOff = 0;
+ int iOff;
+ int nDoclist;
+
+ memset(&term, 0, sizeof(Fts5Buffer));
+
+ if( n<4 ){
+ sqlite3Fts5BufferSet(&rc, &s, 7, (const u8*)"corrupt");
+ goto decode_out;
+ }else{
+ iRowidOff = fts5GetU16(&a[0]);
+ iPgidxOff = szLeaf = fts5GetU16(&a[2]);
+ if( iPgidxOff<n ){
+ fts5GetVarint32(&a[iPgidxOff], iTermOff);
}else if( iPgidxOff>n ){
rc = FTS5_CORRUPT;
goto decode_out;
- }
- }
-
- /* Decode the position list tail at the start of the page */
- if( iRowidOff!=0 ){
- iOff = iRowidOff;
- }else if( iTermOff!=0 ){
- iOff = iTermOff;
- }else{
- iOff = szLeaf;
- }
+ }
+ }
+
+ /* Decode the position list tail at the start of the page */
+ if( iRowidOff!=0 ){
+ iOff = iRowidOff;
+ }else if( iTermOff!=0 ){
+ iOff = iTermOff;
+ }else{
+ iOff = szLeaf;
+ }
if( iOff>n ){
rc = FTS5_CORRUPT;
goto decode_out;
}
- fts5DecodePoslist(&rc, &s, &a[4], iOff-4);
-
- /* Decode any more doclist data that appears on the page before the
- ** first term. */
- nDoclist = (iTermOff ? iTermOff : szLeaf) - iOff;
+ fts5DecodePoslist(&rc, &s, &a[4], iOff-4);
+
+ /* Decode any more doclist data that appears on the page before the
+ ** first term. */
+ nDoclist = (iTermOff ? iTermOff : szLeaf) - iOff;
if( nDoclist+iOff>n ){
rc = FTS5_CORRUPT;
goto decode_out;
}
- fts5DecodeDoclist(&rc, &s, &a[iOff], nDoclist);
-
+ fts5DecodeDoclist(&rc, &s, &a[iOff], nDoclist);
+
while( iPgidxOff<n && rc==SQLITE_OK ){
- int bFirst = (iPgidxOff==szLeaf); /* True for first term on page */
- int nByte; /* Bytes of data */
- int iEnd;
-
- iPgidxOff += fts5GetVarint32(&a[iPgidxOff], nByte);
- iPgidxPrev += nByte;
- iOff = iPgidxPrev;
-
- if( iPgidxOff<n ){
- fts5GetVarint32(&a[iPgidxOff], nByte);
- iEnd = iPgidxPrev + nByte;
- }else{
- iEnd = szLeaf;
- }
+ int bFirst = (iPgidxOff==szLeaf); /* True for first term on page */
+ int nByte; /* Bytes of data */
+ int iEnd;
+
+ iPgidxOff += fts5GetVarint32(&a[iPgidxOff], nByte);
+ iPgidxPrev += nByte;
+ iOff = iPgidxPrev;
+
+ if( iPgidxOff<n ){
+ fts5GetVarint32(&a[iPgidxOff], nByte);
+ iEnd = iPgidxPrev + nByte;
+ }else{
+ iEnd = szLeaf;
+ }
if( iEnd>szLeaf ){
rc = FTS5_CORRUPT;
break;
}
-
- if( bFirst==0 ){
- iOff += fts5GetVarint32(&a[iOff], nByte);
+
+ if( bFirst==0 ){
+ iOff += fts5GetVarint32(&a[iOff], nByte);
if( nByte>term.n ){
rc = FTS5_CORRUPT;
break;
}
- term.n = nByte;
- }
- iOff += fts5GetVarint32(&a[iOff], nByte);
+ term.n = nByte;
+ }
+ iOff += fts5GetVarint32(&a[iOff], nByte);
if( iOff+nByte>n ){
rc = FTS5_CORRUPT;
break;
}
- fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]);
- iOff += nByte;
-
- sqlite3Fts5BufferAppendPrintf(
- &rc, &s, " term=%.*s", term.n, (const char*)term.p
- );
- iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff);
- }
-
- fts5BufferFree(&term);
- }
-
- decode_out:
- sqlite3_free(a);
- if( rc==SQLITE_OK ){
- sqlite3_result_text(pCtx, (const char*)s.p, s.n, SQLITE_TRANSIENT);
- }else{
- sqlite3_result_error_code(pCtx, rc);
- }
- fts5BufferFree(&s);
-}
+ fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]);
+ iOff += nByte;
+
+ sqlite3Fts5BufferAppendPrintf(
+ &rc, &s, " term=%.*s", term.n, (const char*)term.p
+ );
+ iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff);
+ }
+
+ fts5BufferFree(&term);
+ }
+
+ decode_out:
+ sqlite3_free(a);
+ if( rc==SQLITE_OK ){
+ sqlite3_result_text(pCtx, (const char*)s.p, s.n, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_result_error_code(pCtx, rc);
+ }
+ fts5BufferFree(&s);
+}
#endif /* SQLITE_TEST */
-
+
#ifdef SQLITE_TEST
-/*
-** The implementation of user-defined scalar function fts5_rowid().
-*/
-static void fts5RowidFunction(
- sqlite3_context *pCtx, /* Function call context */
- int nArg, /* Number of args (always 2) */
- sqlite3_value **apVal /* Function arguments */
-){
- const char *zArg;
- if( nArg==0 ){
- sqlite3_result_error(pCtx, "should be: fts5_rowid(subject, ....)", -1);
- }else{
- zArg = (const char*)sqlite3_value_text(apVal[0]);
- if( 0==sqlite3_stricmp(zArg, "segment") ){
- i64 iRowid;
- int segid, pgno;
- if( nArg!=3 ){
+/*
+** The implementation of user-defined scalar function fts5_rowid().
+*/
+static void fts5RowidFunction(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args (always 2) */
+ sqlite3_value **apVal /* Function arguments */
+){
+ const char *zArg;
+ if( nArg==0 ){
+ sqlite3_result_error(pCtx, "should be: fts5_rowid(subject, ....)", -1);
+ }else{
+ zArg = (const char*)sqlite3_value_text(apVal[0]);
+ if( 0==sqlite3_stricmp(zArg, "segment") ){
+ i64 iRowid;
+ int segid, pgno;
+ if( nArg!=3 ){
sqlite3_result_error(pCtx,
- "should be: fts5_rowid('segment', segid, pgno))", -1
- );
- }else{
- segid = sqlite3_value_int(apVal[1]);
- pgno = sqlite3_value_int(apVal[2]);
- iRowid = FTS5_SEGMENT_ROWID(segid, pgno);
- sqlite3_result_int64(pCtx, iRowid);
- }
- }else{
+ "should be: fts5_rowid('segment', segid, pgno))", -1
+ );
+ }else{
+ segid = sqlite3_value_int(apVal[1]);
+ pgno = sqlite3_value_int(apVal[2]);
+ iRowid = FTS5_SEGMENT_ROWID(segid, pgno);
+ sqlite3_result_int64(pCtx, iRowid);
+ }
+ }else{
sqlite3_result_error(pCtx,
- "first arg to fts5_rowid() must be 'segment'" , -1
- );
- }
- }
-}
+ "first arg to fts5_rowid() must be 'segment'" , -1
+ );
+ }
+ }
+}
#endif /* SQLITE_TEST */
-
-/*
-** This is called as part of registering the FTS5 module with database
-** connection db. It registers several user-defined scalar functions useful
-** with FTS5.
-**
-** If successful, SQLITE_OK is returned. If an error occurs, some other
-** SQLite error code is returned instead.
-*/
-static int sqlite3Fts5IndexInit(sqlite3 *db){
+
+/*
+** This is called as part of registering the FTS5 module with database
+** connection db. It registers several user-defined scalar functions useful
+** with FTS5.
+**
+** If successful, SQLITE_OK is returned. If an error occurs, some other
+** SQLite error code is returned instead.
+*/
+static int sqlite3Fts5IndexInit(sqlite3 *db){
#ifdef SQLITE_TEST
- int rc = sqlite3_create_function(
- db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0
- );
-
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(
+ int rc = sqlite3_create_function(
+ db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0
+ );
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(
db, "fts5_decode_none", 2,
- SQLITE_UTF8, (void*)db, fts5DecodeFunction, 0, 0
- );
- }
-
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(
- db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0
- );
- }
- return rc;
+ SQLITE_UTF8, (void*)db, fts5DecodeFunction, 0, 0
+ );
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(
+ db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0
+ );
+ }
+ return rc;
#else
return SQLITE_OK;
UNUSED_PARAM(db);
#endif
-}
-
-
-static int sqlite3Fts5IndexReset(Fts5Index *p){
- assert( p->pStruct==0 || p->iStructVersion!=0 );
- if( fts5IndexDataVersion(p)!=p->iStructVersion ){
- fts5StructureInvalidate(p);
- }
- return fts5IndexReturn(p);
-}
-
-/*
-** 2014 Jun 09
-**
-** 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 is an SQLite module implementing full-text search.
-*/
-
-
-/* #include "fts5Int.h" */
-
-/*
-** This variable is set to false when running tests for which the on disk
-** structures should not be corrupt. Otherwise, true. If it is false, extra
-** assert() conditions in the fts5 code are activated - conditions that are
-** only true if it is guaranteed that the fts5 database is not corrupt.
-*/
+}
+
+
+static int sqlite3Fts5IndexReset(Fts5Index *p){
+ assert( p->pStruct==0 || p->iStructVersion!=0 );
+ if( fts5IndexDataVersion(p)!=p->iStructVersion ){
+ fts5StructureInvalidate(p);
+ }
+ return fts5IndexReturn(p);
+}
+
+/*
+** 2014 Jun 09
+**
+** 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 is an SQLite module implementing full-text search.
+*/
+
+
+/* #include "fts5Int.h" */
+
+/*
+** This variable is set to false when running tests for which the on disk
+** structures should not be corrupt. Otherwise, true. If it is false, extra
+** assert() conditions in the fts5 code are activated - conditions that are
+** only true if it is guaranteed that the fts5 database is not corrupt.
+*/
#ifdef SQLITE_DEBUG
-SQLITE_API int sqlite3_fts5_may_be_corrupt = 1;
+SQLITE_API int sqlite3_fts5_may_be_corrupt = 1;
#endif
-
-
-typedef struct Fts5Auxdata Fts5Auxdata;
-typedef struct Fts5Auxiliary Fts5Auxiliary;
-typedef struct Fts5Cursor Fts5Cursor;
+
+
+typedef struct Fts5Auxdata Fts5Auxdata;
+typedef struct Fts5Auxiliary Fts5Auxiliary;
+typedef struct Fts5Cursor Fts5Cursor;
typedef struct Fts5FullTable Fts5FullTable;
-typedef struct Fts5Sorter Fts5Sorter;
-typedef struct Fts5TokenizerModule Fts5TokenizerModule;
-
-/*
+typedef struct Fts5Sorter Fts5Sorter;
+typedef struct Fts5TokenizerModule Fts5TokenizerModule;
+
+/*
** NOTES ON TRANSACTIONS:
-**
+**
** SQLite invokes the following virtual table methods as transactions are
-** opened and closed by the user:
-**
-** xBegin(): Start of a new transaction.
-** xSync(): Initial part of two-phase commit.
-** xCommit(): Final part of two-phase commit.
-** xRollback(): Rollback the transaction.
-**
-** Anything that is required as part of a commit that may fail is performed
+** opened and closed by the user:
+**
+** xBegin(): Start of a new transaction.
+** xSync(): Initial part of two-phase commit.
+** xCommit(): Final part of two-phase commit.
+** xRollback(): Rollback the transaction.
+**
+** Anything that is required as part of a commit that may fail is performed
** in the xSync() callback. Current versions of SQLite ignore any errors
-** returned by xCommit().
-**
-** And as sub-transactions are opened/closed:
-**
-** xSavepoint(int S): Open savepoint S.
-** xRelease(int S): Commit and close savepoint S.
-** xRollbackTo(int S): Rollback to start of savepoint S.
-**
+** returned by xCommit().
+**
+** And as sub-transactions are opened/closed:
+**
+** xSavepoint(int S): Open savepoint S.
+** xRelease(int S): Commit and close savepoint S.
+** xRollbackTo(int S): Rollback to start of savepoint S.
+**
** During a write-transaction the fts5_index.c module may cache some data
-** in-memory. It is flushed to disk whenever xSync(), xRelease() or
+** in-memory. It is flushed to disk whenever xSync(), xRelease() or
** xSavepoint() is called. And discarded whenever xRollback() or xRollbackTo()
-** is called.
-**
-** Additionally, if SQLITE_DEBUG is defined, an instance of the following
-** structure is used to record the current transaction state. This information
-** is not required, but it is used in the assert() statements executed by
-** function fts5CheckTransactionState() (see below).
-*/
-struct Fts5TransactionState {
- int eState; /* 0==closed, 1==open, 2==synced */
- int iSavepoint; /* Number of open savepoints (0 -> none) */
-};
-
-/*
+** is called.
+**
+** Additionally, if SQLITE_DEBUG is defined, an instance of the following
+** structure is used to record the current transaction state. This information
+** is not required, but it is used in the assert() statements executed by
+** function fts5CheckTransactionState() (see below).
+*/
+struct Fts5TransactionState {
+ int eState; /* 0==closed, 1==open, 2==synced */
+ int iSavepoint; /* Number of open savepoints (0 -> none) */
+};
+
+/*
** A single object of this type is allocated when the FTS5 module is
-** registered with a database handle. It is used to store pointers to
-** all registered FTS5 extensions - tokenizers and auxiliary functions.
-*/
-struct Fts5Global {
- fts5_api api; /* User visible part of object (see fts5.h) */
+** registered with a database handle. It is used to store pointers to
+** all registered FTS5 extensions - tokenizers and auxiliary functions.
+*/
+struct Fts5Global {
+ fts5_api api; /* User visible part of object (see fts5.h) */
sqlite3 *db; /* Associated database connection */
- i64 iNextId; /* Used to allocate unique cursor ids */
- Fts5Auxiliary *pAux; /* First in list of all aux. functions */
- Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */
- Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */
- Fts5Cursor *pCsr; /* First in list of all open cursors */
-};
-
-/*
-** Each auxiliary function registered with the FTS5 module is represented
-** by an object of the following type. All such objects are stored as part
-** of the Fts5Global.pAux list.
-*/
-struct Fts5Auxiliary {
- Fts5Global *pGlobal; /* Global context for this function */
- char *zFunc; /* Function name (nul-terminated) */
- void *pUserData; /* User-data pointer */
- fts5_extension_function xFunc; /* Callback function */
- void (*xDestroy)(void*); /* Destructor function */
- Fts5Auxiliary *pNext; /* Next registered auxiliary function */
-};
-
-/*
-** Each tokenizer module registered with the FTS5 module is represented
-** by an object of the following type. All such objects are stored as part
-** of the Fts5Global.pTok list.
-*/
-struct Fts5TokenizerModule {
- char *zName; /* Name of tokenizer */
- void *pUserData; /* User pointer passed to xCreate() */
- fts5_tokenizer x; /* Tokenizer functions */
- void (*xDestroy)(void*); /* Destructor function */
- Fts5TokenizerModule *pNext; /* Next registered tokenizer module */
-};
-
+ i64 iNextId; /* Used to allocate unique cursor ids */
+ Fts5Auxiliary *pAux; /* First in list of all aux. functions */
+ Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */
+ Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */
+ Fts5Cursor *pCsr; /* First in list of all open cursors */
+};
+
+/*
+** Each auxiliary function registered with the FTS5 module is represented
+** by an object of the following type. All such objects are stored as part
+** of the Fts5Global.pAux list.
+*/
+struct Fts5Auxiliary {
+ Fts5Global *pGlobal; /* Global context for this function */
+ char *zFunc; /* Function name (nul-terminated) */
+ void *pUserData; /* User-data pointer */
+ fts5_extension_function xFunc; /* Callback function */
+ void (*xDestroy)(void*); /* Destructor function */
+ Fts5Auxiliary *pNext; /* Next registered auxiliary function */
+};
+
+/*
+** Each tokenizer module registered with the FTS5 module is represented
+** by an object of the following type. All such objects are stored as part
+** of the Fts5Global.pTok list.
+*/
+struct Fts5TokenizerModule {
+ char *zName; /* Name of tokenizer */
+ void *pUserData; /* User pointer passed to xCreate() */
+ fts5_tokenizer x; /* Tokenizer functions */
+ void (*xDestroy)(void*); /* Destructor function */
+ Fts5TokenizerModule *pNext; /* Next registered tokenizer module */
+};
+
struct Fts5FullTable {
Fts5Table p; /* Public class members from fts5Int.h */
- Fts5Storage *pStorage; /* Document store */
- Fts5Global *pGlobal; /* Global (connection wide) data */
- Fts5Cursor *pSortCsr; /* Sort data from this cursor */
-#ifdef SQLITE_DEBUG
- struct Fts5TransactionState ts;
-#endif
-};
-
-struct Fts5MatchPhrase {
- Fts5Buffer *pPoslist; /* Pointer to current poslist */
- int nTerm; /* Size of phrase in terms */
-};
-
-/*
-** pStmt:
-** SELECT rowid, <fts> FROM <fts> ORDER BY +rank;
-**
-** aIdx[]:
-** There is one entry in the aIdx[] array for each phrase in the query,
+ Fts5Storage *pStorage; /* Document store */
+ Fts5Global *pGlobal; /* Global (connection wide) data */
+ Fts5Cursor *pSortCsr; /* Sort data from this cursor */
+#ifdef SQLITE_DEBUG
+ struct Fts5TransactionState ts;
+#endif
+};
+
+struct Fts5MatchPhrase {
+ Fts5Buffer *pPoslist; /* Pointer to current poslist */
+ int nTerm; /* Size of phrase in terms */
+};
+
+/*
+** pStmt:
+** SELECT rowid, <fts> FROM <fts> ORDER BY +rank;
+**
+** aIdx[]:
+** There is one entry in the aIdx[] array for each phrase in the query,
** the value of which is the offset within aPoslist[] following the last
-** byte of the position list for the corresponding phrase.
-*/
-struct Fts5Sorter {
- sqlite3_stmt *pStmt;
- i64 iRowid; /* Current rowid */
- const u8 *aPoslist; /* Position lists for current row */
- int nIdx; /* Number of entries in aIdx[] */
- int aIdx[1]; /* Offsets into aPoslist for current row */
-};
-
-
-/*
-** Virtual-table cursor object.
-**
-** iSpecial:
+** byte of the position list for the corresponding phrase.
+*/
+struct Fts5Sorter {
+ sqlite3_stmt *pStmt;
+ i64 iRowid; /* Current rowid */
+ const u8 *aPoslist; /* Position lists for current row */
+ int nIdx; /* Number of entries in aIdx[] */
+ int aIdx[1]; /* Offsets into aPoslist for current row */
+};
+
+
+/*
+** Virtual-table cursor object.
+**
+** iSpecial:
** If this is a 'special' query (refer to function fts5SpecialMatch()),
** then this variable contains the result of the query.
-**
-** iFirstRowid, iLastRowid:
-** These variables are only used for FTS5_PLAN_MATCH cursors. Assuming the
-** cursor iterates in ascending order of rowids, iFirstRowid is the lower
-** limit of rowids to return, and iLastRowid the upper. In other words, the
-** WHERE clause in the user's query might have been:
-**
-** <tbl> MATCH <expr> AND rowid BETWEEN $iFirstRowid AND $iLastRowid
-**
-** If the cursor iterates in descending order of rowid, iFirstRowid
-** is the upper limit (i.e. the "first" rowid visited) and iLastRowid
-** the lower.
-*/
-struct Fts5Cursor {
- sqlite3_vtab_cursor base; /* Base class used by SQLite core */
- Fts5Cursor *pNext; /* Next cursor in Fts5Cursor.pCsr list */
- int *aColumnSize; /* Values for xColumnSize() */
- i64 iCsrId; /* Cursor id */
-
- /* Zero from this point onwards on cursor reset */
- int ePlan; /* FTS5_PLAN_XXX value */
- int bDesc; /* True for "ORDER BY rowid DESC" queries */
- i64 iFirstRowid; /* Return no rowids earlier than this */
- i64 iLastRowid; /* Return no rowids later than this */
- sqlite3_stmt *pStmt; /* Statement used to read %_content */
- Fts5Expr *pExpr; /* Expression for MATCH queries */
- Fts5Sorter *pSorter; /* Sorter for "ORDER BY rank" queries */
- int csrflags; /* Mask of cursor flags (see below) */
- i64 iSpecial; /* Result of special query */
-
- /* "rank" function. Populated on demand from vtab.xColumn(). */
- char *zRank; /* Custom rank function */
- char *zRankArgs; /* Custom rank function args */
- Fts5Auxiliary *pRank; /* Rank callback (or NULL) */
- int nRankArg; /* Number of trailing arguments for rank() */
- sqlite3_value **apRankArg; /* Array of trailing arguments */
- sqlite3_stmt *pRankArgStmt; /* Origin of objects in apRankArg[] */
-
- /* Auxiliary data storage */
- Fts5Auxiliary *pAux; /* Currently executing extension function */
- Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */
-
- /* Cache used by auxiliary functions xInst() and xInstCount() */
- Fts5PoslistReader *aInstIter; /* One for each phrase */
- int nInstAlloc; /* Size of aInst[] array (entries / 3) */
- int nInstCount; /* Number of phrase instances */
- int *aInst; /* 3 integers per phrase instance */
-};
-
-/*
+**
+** iFirstRowid, iLastRowid:
+** These variables are only used for FTS5_PLAN_MATCH cursors. Assuming the
+** cursor iterates in ascending order of rowids, iFirstRowid is the lower
+** limit of rowids to return, and iLastRowid the upper. In other words, the
+** WHERE clause in the user's query might have been:
+**
+** <tbl> MATCH <expr> AND rowid BETWEEN $iFirstRowid AND $iLastRowid
+**
+** If the cursor iterates in descending order of rowid, iFirstRowid
+** is the upper limit (i.e. the "first" rowid visited) and iLastRowid
+** the lower.
+*/
+struct Fts5Cursor {
+ sqlite3_vtab_cursor base; /* Base class used by SQLite core */
+ Fts5Cursor *pNext; /* Next cursor in Fts5Cursor.pCsr list */
+ int *aColumnSize; /* Values for xColumnSize() */
+ i64 iCsrId; /* Cursor id */
+
+ /* Zero from this point onwards on cursor reset */
+ int ePlan; /* FTS5_PLAN_XXX value */
+ int bDesc; /* True for "ORDER BY rowid DESC" queries */
+ i64 iFirstRowid; /* Return no rowids earlier than this */
+ i64 iLastRowid; /* Return no rowids later than this */
+ sqlite3_stmt *pStmt; /* Statement used to read %_content */
+ Fts5Expr *pExpr; /* Expression for MATCH queries */
+ Fts5Sorter *pSorter; /* Sorter for "ORDER BY rank" queries */
+ int csrflags; /* Mask of cursor flags (see below) */
+ i64 iSpecial; /* Result of special query */
+
+ /* "rank" function. Populated on demand from vtab.xColumn(). */
+ char *zRank; /* Custom rank function */
+ char *zRankArgs; /* Custom rank function args */
+ Fts5Auxiliary *pRank; /* Rank callback (or NULL) */
+ int nRankArg; /* Number of trailing arguments for rank() */
+ sqlite3_value **apRankArg; /* Array of trailing arguments */
+ sqlite3_stmt *pRankArgStmt; /* Origin of objects in apRankArg[] */
+
+ /* Auxiliary data storage */
+ Fts5Auxiliary *pAux; /* Currently executing extension function */
+ Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */
+
+ /* Cache used by auxiliary functions xInst() and xInstCount() */
+ Fts5PoslistReader *aInstIter; /* One for each phrase */
+ int nInstAlloc; /* Size of aInst[] array (entries / 3) */
+ int nInstCount; /* Number of phrase instances */
+ int *aInst; /* 3 integers per phrase instance */
+};
+
+/*
** Bits that make up the "idxNum" parameter passed indirectly by
-** xBestIndex() to xFilter().
-*/
-#define FTS5_BI_MATCH 0x0001 /* <tbl> MATCH ? */
-#define FTS5_BI_RANK 0x0002 /* rank MATCH ? */
-#define FTS5_BI_ROWID_EQ 0x0004 /* rowid == ? */
-#define FTS5_BI_ROWID_LE 0x0008 /* rowid <= ? */
-#define FTS5_BI_ROWID_GE 0x0010 /* rowid >= ? */
-
-#define FTS5_BI_ORDER_RANK 0x0020
-#define FTS5_BI_ORDER_ROWID 0x0040
-#define FTS5_BI_ORDER_DESC 0x0080
-
-/*
-** Values for Fts5Cursor.csrflags
-*/
-#define FTS5CSR_EOF 0x01
-#define FTS5CSR_REQUIRE_CONTENT 0x02
-#define FTS5CSR_REQUIRE_DOCSIZE 0x04
-#define FTS5CSR_REQUIRE_INST 0x08
-#define FTS5CSR_FREE_ZRANK 0x10
-#define FTS5CSR_REQUIRE_RESEEK 0x20
-#define FTS5CSR_REQUIRE_POSLIST 0x40
-
-#define BitFlagAllTest(x,y) (((x) & (y))==(y))
-#define BitFlagTest(x,y) (((x) & (y))!=0)
-
-
-/*
-** Macros to Set(), Clear() and Test() cursor flags.
-*/
-#define CsrFlagSet(pCsr, flag) ((pCsr)->csrflags |= (flag))
-#define CsrFlagClear(pCsr, flag) ((pCsr)->csrflags &= ~(flag))
-#define CsrFlagTest(pCsr, flag) ((pCsr)->csrflags & (flag))
-
-struct Fts5Auxdata {
- Fts5Auxiliary *pAux; /* Extension to which this belongs */
- void *pPtr; /* Pointer value */
- void(*xDelete)(void*); /* Destructor */
- Fts5Auxdata *pNext; /* Next object in linked list */
-};
-
-#ifdef SQLITE_DEBUG
-#define FTS5_BEGIN 1
-#define FTS5_SYNC 2
-#define FTS5_COMMIT 3
-#define FTS5_ROLLBACK 4
-#define FTS5_SAVEPOINT 5
-#define FTS5_RELEASE 6
-#define FTS5_ROLLBACKTO 7
+** xBestIndex() to xFilter().
+*/
+#define FTS5_BI_MATCH 0x0001 /* <tbl> MATCH ? */
+#define FTS5_BI_RANK 0x0002 /* rank MATCH ? */
+#define FTS5_BI_ROWID_EQ 0x0004 /* rowid == ? */
+#define FTS5_BI_ROWID_LE 0x0008 /* rowid <= ? */
+#define FTS5_BI_ROWID_GE 0x0010 /* rowid >= ? */
+
+#define FTS5_BI_ORDER_RANK 0x0020
+#define FTS5_BI_ORDER_ROWID 0x0040
+#define FTS5_BI_ORDER_DESC 0x0080
+
+/*
+** Values for Fts5Cursor.csrflags
+*/
+#define FTS5CSR_EOF 0x01
+#define FTS5CSR_REQUIRE_CONTENT 0x02
+#define FTS5CSR_REQUIRE_DOCSIZE 0x04
+#define FTS5CSR_REQUIRE_INST 0x08
+#define FTS5CSR_FREE_ZRANK 0x10
+#define FTS5CSR_REQUIRE_RESEEK 0x20
+#define FTS5CSR_REQUIRE_POSLIST 0x40
+
+#define BitFlagAllTest(x,y) (((x) & (y))==(y))
+#define BitFlagTest(x,y) (((x) & (y))!=0)
+
+
+/*
+** Macros to Set(), Clear() and Test() cursor flags.
+*/
+#define CsrFlagSet(pCsr, flag) ((pCsr)->csrflags |= (flag))
+#define CsrFlagClear(pCsr, flag) ((pCsr)->csrflags &= ~(flag))
+#define CsrFlagTest(pCsr, flag) ((pCsr)->csrflags & (flag))
+
+struct Fts5Auxdata {
+ Fts5Auxiliary *pAux; /* Extension to which this belongs */
+ void *pPtr; /* Pointer value */
+ void(*xDelete)(void*); /* Destructor */
+ Fts5Auxdata *pNext; /* Next object in linked list */
+};
+
+#ifdef SQLITE_DEBUG
+#define FTS5_BEGIN 1
+#define FTS5_SYNC 2
+#define FTS5_COMMIT 3
+#define FTS5_ROLLBACK 4
+#define FTS5_SAVEPOINT 5
+#define FTS5_RELEASE 6
+#define FTS5_ROLLBACKTO 7
static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){
- switch( op ){
- case FTS5_BEGIN:
- assert( p->ts.eState==0 );
- p->ts.eState = 1;
- p->ts.iSavepoint = -1;
- break;
-
- case FTS5_SYNC:
- assert( p->ts.eState==1 );
- p->ts.eState = 2;
- break;
-
- case FTS5_COMMIT:
- assert( p->ts.eState==2 );
- p->ts.eState = 0;
- break;
-
- case FTS5_ROLLBACK:
- assert( p->ts.eState==1 || p->ts.eState==2 || p->ts.eState==0 );
- p->ts.eState = 0;
- break;
-
- case FTS5_SAVEPOINT:
- assert( p->ts.eState==1 );
- assert( iSavepoint>=0 );
+ switch( op ){
+ case FTS5_BEGIN:
+ assert( p->ts.eState==0 );
+ p->ts.eState = 1;
+ p->ts.iSavepoint = -1;
+ break;
+
+ case FTS5_SYNC:
+ assert( p->ts.eState==1 );
+ p->ts.eState = 2;
+ break;
+
+ case FTS5_COMMIT:
+ assert( p->ts.eState==2 );
+ p->ts.eState = 0;
+ break;
+
+ case FTS5_ROLLBACK:
+ assert( p->ts.eState==1 || p->ts.eState==2 || p->ts.eState==0 );
+ p->ts.eState = 0;
+ break;
+
+ case FTS5_SAVEPOINT:
+ assert( p->ts.eState==1 );
+ assert( iSavepoint>=0 );
assert( iSavepoint>=p->ts.iSavepoint );
- p->ts.iSavepoint = iSavepoint;
- break;
-
- case FTS5_RELEASE:
- assert( p->ts.eState==1 );
- assert( iSavepoint>=0 );
- assert( iSavepoint<=p->ts.iSavepoint );
- p->ts.iSavepoint = iSavepoint-1;
- break;
-
- case FTS5_ROLLBACKTO:
- assert( p->ts.eState==1 );
+ p->ts.iSavepoint = iSavepoint;
+ break;
+
+ case FTS5_RELEASE:
+ assert( p->ts.eState==1 );
+ assert( iSavepoint>=0 );
+ assert( iSavepoint<=p->ts.iSavepoint );
+ p->ts.iSavepoint = iSavepoint-1;
+ break;
+
+ case FTS5_ROLLBACKTO:
+ assert( p->ts.eState==1 );
assert( iSavepoint>=-1 );
/* The following assert() can fail if another vtab strikes an error
** within an xSavepoint() call then SQLite calls xRollbackTo() - without
** having called xSavepoint() on this vtab. */
/* assert( iSavepoint<=p->ts.iSavepoint ); */
- p->ts.iSavepoint = iSavepoint;
- break;
- }
-}
-#else
-# define fts5CheckTransactionState(x,y,z)
-#endif
-
-/*
-** Return true if pTab is a contentless table.
-*/
+ p->ts.iSavepoint = iSavepoint;
+ break;
+ }
+}
+#else
+# define fts5CheckTransactionState(x,y,z)
+#endif
+
+/*
+** Return true if pTab is a contentless table.
+*/
static int fts5IsContentless(Fts5FullTable *pTab){
return pTab->p.pConfig->eContent==FTS5_CONTENT_NONE;
-}
-
-/*
+}
+
+/*
** Delete a virtual table handle allocated by fts5InitVtab().
-*/
+*/
static void fts5FreeVtab(Fts5FullTable *pTab){
- if( pTab ){
+ if( pTab ){
sqlite3Fts5IndexClose(pTab->p.pIndex);
- sqlite3Fts5StorageClose(pTab->pStorage);
+ sqlite3Fts5StorageClose(pTab->pStorage);
sqlite3Fts5ConfigFree(pTab->p.pConfig);
- sqlite3_free(pTab);
- }
-}
-
-/*
-** The xDisconnect() virtual table method.
-*/
-static int fts5DisconnectMethod(sqlite3_vtab *pVtab){
+ sqlite3_free(pTab);
+ }
+}
+
+/*
+** The xDisconnect() virtual table method.
+*/
+static int fts5DisconnectMethod(sqlite3_vtab *pVtab){
fts5FreeVtab((Fts5FullTable*)pVtab);
- return SQLITE_OK;
-}
-
-/*
-** The xDestroy() virtual table method.
-*/
-static int fts5DestroyMethod(sqlite3_vtab *pVtab){
- Fts5Table *pTab = (Fts5Table*)pVtab;
- int rc = sqlite3Fts5DropAll(pTab->pConfig);
- if( rc==SQLITE_OK ){
+ return SQLITE_OK;
+}
+
+/*
+** The xDestroy() virtual table method.
+*/
+static int fts5DestroyMethod(sqlite3_vtab *pVtab){
+ Fts5Table *pTab = (Fts5Table*)pVtab;
+ int rc = sqlite3Fts5DropAll(pTab->pConfig);
+ if( rc==SQLITE_OK ){
fts5FreeVtab((Fts5FullTable*)pVtab);
- }
- return rc;
-}
-
-/*
-** This function is the implementation of both the xConnect and xCreate
-** methods of the FTS3 virtual table.
-**
-** The argv[] array contains the following:
-**
-** argv[0] -> module name ("fts5")
-** argv[1] -> database name
-** argv[2] -> table name
-** argv[...] -> "column name" and other module argument fields.
-*/
-static int fts5InitVtab(
- int bCreate, /* True for xCreate, false for xConnect */
- sqlite3 *db, /* The SQLite database connection */
- void *pAux, /* Hash table containing tokenizers */
- int argc, /* Number of elements in argv array */
- const char * const *argv, /* xCreate/xConnect argument array */
- sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */
- char **pzErr /* Write any error message here */
-){
- Fts5Global *pGlobal = (Fts5Global*)pAux;
- const char **azConfig = (const char**)argv;
- int rc = SQLITE_OK; /* Return code */
- Fts5Config *pConfig = 0; /* Results of parsing argc/argv */
+ }
+ return rc;
+}
+
+/*
+** This function is the implementation of both the xConnect and xCreate
+** methods of the FTS3 virtual table.
+**
+** The argv[] array contains the following:
+**
+** argv[0] -> module name ("fts5")
+** argv[1] -> database name
+** argv[2] -> table name
+** argv[...] -> "column name" and other module argument fields.
+*/
+static int fts5InitVtab(
+ int bCreate, /* True for xCreate, false for xConnect */
+ sqlite3 *db, /* The SQLite database connection */
+ void *pAux, /* Hash table containing tokenizers */
+ int argc, /* Number of elements in argv array */
+ const char * const *argv, /* xCreate/xConnect argument array */
+ sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */
+ char **pzErr /* Write any error message here */
+){
+ Fts5Global *pGlobal = (Fts5Global*)pAux;
+ const char **azConfig = (const char**)argv;
+ int rc = SQLITE_OK; /* Return code */
+ Fts5Config *pConfig = 0; /* Results of parsing argc/argv */
Fts5FullTable *pTab = 0; /* New virtual table object */
-
- /* Allocate the new vtab object and parse the configuration */
+
+ /* Allocate the new vtab object and parse the configuration */
pTab = (Fts5FullTable*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5FullTable));
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr);
- assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 );
- }
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr);
+ assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 );
+ }
+ if( rc==SQLITE_OK ){
pTab->p.pConfig = pConfig;
- pTab->pGlobal = pGlobal;
- }
-
- /* Open the index sub-system */
- if( rc==SQLITE_OK ){
+ pTab->pGlobal = pGlobal;
+ }
+
+ /* Open the index sub-system */
+ if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->p.pIndex, pzErr);
- }
-
- /* Open the storage sub-system */
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageOpen(
+ }
+
+ /* Open the storage sub-system */
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageOpen(
pConfig, pTab->p.pIndex, bCreate, &pTab->pStorage, pzErr
- );
- }
-
- /* Call sqlite3_declare_vtab() */
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5ConfigDeclareVtab(pConfig);
- }
-
- /* Load the initial configuration */
- if( rc==SQLITE_OK ){
- assert( pConfig->pzErrmsg==0 );
- pConfig->pzErrmsg = pzErr;
+ );
+ }
+
+ /* Call sqlite3_declare_vtab() */
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5ConfigDeclareVtab(pConfig);
+ }
+
+ /* Load the initial configuration */
+ if( rc==SQLITE_OK ){
+ assert( pConfig->pzErrmsg==0 );
+ pConfig->pzErrmsg = pzErr;
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
sqlite3Fts5IndexRollback(pTab->p.pIndex);
- pConfig->pzErrmsg = 0;
- }
-
- if( rc!=SQLITE_OK ){
- fts5FreeVtab(pTab);
- pTab = 0;
- }else if( bCreate ){
- fts5CheckTransactionState(pTab, FTS5_BEGIN, 0);
- }
- *ppVTab = (sqlite3_vtab*)pTab;
- return rc;
-}
-
-/*
-** The xConnect() and xCreate() methods for the virtual table. All the
-** work is done in function fts5InitVtab().
-*/
-static int fts5ConnectMethod(
- sqlite3 *db, /* Database connection */
- void *pAux, /* Pointer to tokenizer hash table */
- int argc, /* Number of elements in argv array */
- const char * const *argv, /* xCreate/xConnect argument array */
- sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
- char **pzErr /* OUT: sqlite3_malloc'd error message */
-){
- return fts5InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr);
-}
-static int fts5CreateMethod(
- sqlite3 *db, /* Database connection */
- void *pAux, /* Pointer to tokenizer hash table */
- int argc, /* Number of elements in argv array */
- const char * const *argv, /* xCreate/xConnect argument array */
- sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
- char **pzErr /* OUT: sqlite3_malloc'd error message */
-){
- return fts5InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr);
-}
-
-/*
-** The different query plans.
-*/
-#define FTS5_PLAN_MATCH 1 /* (<tbl> MATCH ?) */
-#define FTS5_PLAN_SOURCE 2 /* A source cursor for SORTED_MATCH */
-#define FTS5_PLAN_SPECIAL 3 /* An internal query */
-#define FTS5_PLAN_SORTED_MATCH 4 /* (<tbl> MATCH ? ORDER BY rank) */
-#define FTS5_PLAN_SCAN 5 /* No usable constraint */
-#define FTS5_PLAN_ROWID 6 /* (rowid = ?) */
-
-/*
-** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
-** extension is currently being used by a version of SQLite too old to
-** support index-info flags. In that case this function is a no-op.
-*/
-static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
-#if SQLITE_VERSION_NUMBER>=3008012
-#ifndef SQLITE_CORE
- if( sqlite3_libversion_number()>=3008012 )
-#endif
- {
- pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
- }
-#endif
-}
-
+ pConfig->pzErrmsg = 0;
+ }
+
+ if( rc!=SQLITE_OK ){
+ fts5FreeVtab(pTab);
+ pTab = 0;
+ }else if( bCreate ){
+ fts5CheckTransactionState(pTab, FTS5_BEGIN, 0);
+ }
+ *ppVTab = (sqlite3_vtab*)pTab;
+ return rc;
+}
+
+/*
+** The xConnect() and xCreate() methods for the virtual table. All the
+** work is done in function fts5InitVtab().
+*/
+static int fts5ConnectMethod(
+ sqlite3 *db, /* Database connection */
+ void *pAux, /* Pointer to tokenizer hash table */
+ int argc, /* Number of elements in argv array */
+ const char * const *argv, /* xCreate/xConnect argument array */
+ sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
+ char **pzErr /* OUT: sqlite3_malloc'd error message */
+){
+ return fts5InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr);
+}
+static int fts5CreateMethod(
+ sqlite3 *db, /* Database connection */
+ void *pAux, /* Pointer to tokenizer hash table */
+ int argc, /* Number of elements in argv array */
+ const char * const *argv, /* xCreate/xConnect argument array */
+ sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
+ char **pzErr /* OUT: sqlite3_malloc'd error message */
+){
+ return fts5InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr);
+}
+
+/*
+** The different query plans.
+*/
+#define FTS5_PLAN_MATCH 1 /* (<tbl> MATCH ?) */
+#define FTS5_PLAN_SOURCE 2 /* A source cursor for SORTED_MATCH */
+#define FTS5_PLAN_SPECIAL 3 /* An internal query */
+#define FTS5_PLAN_SORTED_MATCH 4 /* (<tbl> MATCH ? ORDER BY rank) */
+#define FTS5_PLAN_SCAN 5 /* No usable constraint */
+#define FTS5_PLAN_ROWID 6 /* (rowid = ?) */
+
+/*
+** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
+** extension is currently being used by a version of SQLite too old to
+** support index-info flags. In that case this function is a no-op.
+*/
+static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
+#if SQLITE_VERSION_NUMBER>=3008012
+#ifndef SQLITE_CORE
+ if( sqlite3_libversion_number()>=3008012 )
+#endif
+ {
+ pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
+ }
+#endif
+}
+
static int fts5UsePatternMatch(
Fts5Config *pConfig,
struct sqlite3_index_constraint *p
@@ -230241,22 +230241,22 @@ static int fts5UsePatternMatch(
return 0;
}
-/*
+/*
** Implementation of the xBestIndex method for FTS5 tables. Within the
-** WHERE constraint, it searches for the following:
-**
+** WHERE constraint, it searches for the following:
+**
** 1. A MATCH constraint against the table column.
-** 2. A MATCH constraint against the "rank" column.
+** 2. A MATCH constraint against the "rank" column.
** 3. A MATCH constraint against some other column.
** 4. An == constraint against the rowid column.
** 5. A < or <= constraint against the rowid column.
** 6. A > or >= constraint against the rowid column.
-**
+**
** Within the ORDER BY, the following are supported:
-**
-** 5. ORDER BY rank [ASC|DESC]
-** 6. ORDER BY rowid [ASC|DESC]
-**
+**
+** 5. ORDER BY rank [ASC|DESC]
+** 6. ORDER BY rowid [ASC|DESC]
+**
** Information for the xFilter call is passed via both the idxNum and
** idxStr variables. Specifically, idxNum is a bitmask of the following
** flags used to encode the ORDER BY clause:
@@ -230280,45 +230280,45 @@ static int fts5UsePatternMatch(
** This function ensures that there is at most one "r" or "=". And that if
** there exists an "=" then there is no "<" or ">".
**
-** Costs are assigned as follows:
-**
-** a) If an unusable MATCH operator is present in the WHERE clause, the
-** cost is unconditionally set to 1e50 (a really big number).
-**
-** a) If a MATCH operator is present, the cost depends on the other
-** constraints also present. As follows:
-**
-** * No other constraints: cost=1000.0
-** * One rowid range constraint: cost=750.0
-** * Both rowid range constraints: cost=500.0
-** * An == rowid constraint: cost=100.0
-**
-** b) Otherwise, if there is no MATCH:
-**
-** * No other constraints: cost=1000000.0
-** * One rowid range constraint: cost=750000.0
-** * Both rowid range constraints: cost=250000.0
-** * An == rowid constraint: cost=10.0
-**
-** Costs are not modified by the ORDER BY clause.
-*/
-static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
- Fts5Table *pTab = (Fts5Table*)pVTab;
- Fts5Config *pConfig = pTab->pConfig;
- const int nCol = pConfig->nCol;
- int idxFlags = 0; /* Parameter passed through to xFilter() */
- int i;
-
+** Costs are assigned as follows:
+**
+** a) If an unusable MATCH operator is present in the WHERE clause, the
+** cost is unconditionally set to 1e50 (a really big number).
+**
+** a) If a MATCH operator is present, the cost depends on the other
+** constraints also present. As follows:
+**
+** * No other constraints: cost=1000.0
+** * One rowid range constraint: cost=750.0
+** * Both rowid range constraints: cost=500.0
+** * An == rowid constraint: cost=100.0
+**
+** b) Otherwise, if there is no MATCH:
+**
+** * No other constraints: cost=1000000.0
+** * One rowid range constraint: cost=750000.0
+** * Both rowid range constraints: cost=250000.0
+** * An == rowid constraint: cost=10.0
+**
+** Costs are not modified by the ORDER BY clause.
+*/
+static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
+ Fts5Table *pTab = (Fts5Table*)pVTab;
+ Fts5Config *pConfig = pTab->pConfig;
+ const int nCol = pConfig->nCol;
+ int idxFlags = 0; /* Parameter passed through to xFilter() */
+ int i;
+
char *idxStr;
int iIdxStr = 0;
int iCons = 0;
-
+
int bSeenEq = 0;
int bSeenGt = 0;
int bSeenLt = 0;
int bSeenMatch = 0;
int bSeenRank = 0;
-
+
assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH );
assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH );
@@ -230338,20 +230338,20 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
pInfo->idxStr = idxStr;
pInfo->needToFreeIdxStr = 1;
- for(i=0; i<pInfo->nConstraint; i++){
- struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
- int iCol = p->iColumn;
+ for(i=0; i<pInfo->nConstraint; i++){
+ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
+ int iCol = p->iColumn;
if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH
|| (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol)
- ){
- /* A MATCH operator or equivalent */
+ ){
+ /* A MATCH operator or equivalent */
if( p->usable==0 || iCol<0 ){
/* As there exists an unusable MATCH constraint this is an
- ** unusable plan. Set a prohibitively high cost. */
- pInfo->estimatedCost = 1e50;
+ ** unusable plan. Set a prohibitively high cost. */
+ pInfo->estimatedCost = 1e50;
assert( iIdxStr < pInfo->nConstraint*6 + 1 );
idxStr[iIdxStr] = 0;
- return SQLITE_OK;
+ return SQLITE_OK;
}else{
if( iCol==nCol+1 ){
if( bSeenRank ) continue;
@@ -230366,7 +230366,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
}
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
pInfo->aConstraintUsage[i].omit = 1;
- }
+ }
}else if( p->usable ){
if( iCol>=0 && iCol<nCol && fts5UsePatternMatch(pConfig, p) ){
assert( p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB );
@@ -230399,29 +230399,29 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
idxStr[iIdxStr++] = '>';
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
bSeenGt = 1;
- }
- }
- }
- }
+ }
+ }
+ }
+ }
idxStr[iIdxStr] = '\0';
-
- /* Set idxFlags flags for the ORDER BY clause */
- if( pInfo->nOrderBy==1 ){
- int iSort = pInfo->aOrderBy[0].iColumn;
+
+ /* Set idxFlags flags for the ORDER BY clause */
+ if( pInfo->nOrderBy==1 ){
+ int iSort = pInfo->aOrderBy[0].iColumn;
if( iSort==(pConfig->nCol+1) && bSeenMatch ){
- idxFlags |= FTS5_BI_ORDER_RANK;
- }else if( iSort==-1 ){
- idxFlags |= FTS5_BI_ORDER_ROWID;
- }
- if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){
- pInfo->orderByConsumed = 1;
- if( pInfo->aOrderBy[0].desc ){
- idxFlags |= FTS5_BI_ORDER_DESC;
- }
- }
- }
-
- /* Calculate the estimated cost based on the flags set in idxFlags. */
+ idxFlags |= FTS5_BI_ORDER_RANK;
+ }else if( iSort==-1 ){
+ idxFlags |= FTS5_BI_ORDER_ROWID;
+ }
+ if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){
+ pInfo->orderByConsumed = 1;
+ if( pInfo->aOrderBy[0].desc ){
+ idxFlags |= FTS5_BI_ORDER_DESC;
+ }
+ }
+ }
+
+ /* Calculate the estimated cost based on the flags set in idxFlags. */
if( bSeenEq ){
pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0;
if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo);
@@ -230429,583 +230429,583 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0;
}else if( bSeenLt || bSeenGt ){
pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0;
- }else{
+ }else{
pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0;
- }
-
- pInfo->idxNum = idxFlags;
- return SQLITE_OK;
-}
-
+ }
+
+ pInfo->idxNum = idxFlags;
+ return SQLITE_OK;
+}
+
static int fts5NewTransaction(Fts5FullTable *pTab){
- Fts5Cursor *pCsr;
- for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
- if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK;
- }
- return sqlite3Fts5StorageReset(pTab->pStorage);
-}
-
-/*
-** Implementation of xOpen method.
-*/
-static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
+ Fts5Cursor *pCsr;
+ for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
+ if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK;
+ }
+ return sqlite3Fts5StorageReset(pTab->pStorage);
+}
+
+/*
+** Implementation of xOpen method.
+*/
+static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
Fts5FullTable *pTab = (Fts5FullTable*)pVTab;
Fts5Config *pConfig = pTab->p.pConfig;
- Fts5Cursor *pCsr = 0; /* New cursor object */
+ Fts5Cursor *pCsr = 0; /* New cursor object */
sqlite3_int64 nByte; /* Bytes of space to allocate */
- int rc; /* Return code */
-
- rc = fts5NewTransaction(pTab);
- if( rc==SQLITE_OK ){
- nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
+ int rc; /* Return code */
+
+ rc = fts5NewTransaction(pTab);
+ if( rc==SQLITE_OK ){
+ nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
pCsr = (Fts5Cursor*)sqlite3_malloc64(nByte);
- if( pCsr ){
- Fts5Global *pGlobal = pTab->pGlobal;
+ if( pCsr ){
+ Fts5Global *pGlobal = pTab->pGlobal;
memset(pCsr, 0, (size_t)nByte);
- pCsr->aColumnSize = (int*)&pCsr[1];
- pCsr->pNext = pGlobal->pCsr;
- pGlobal->pCsr = pCsr;
- pCsr->iCsrId = ++pGlobal->iNextId;
- }else{
- rc = SQLITE_NOMEM;
- }
- }
- *ppCsr = (sqlite3_vtab_cursor*)pCsr;
- return rc;
-}
-
-static int fts5StmtType(Fts5Cursor *pCsr){
- if( pCsr->ePlan==FTS5_PLAN_SCAN ){
- return (pCsr->bDesc) ? FTS5_STMT_SCAN_DESC : FTS5_STMT_SCAN_ASC;
- }
- return FTS5_STMT_LOOKUP;
-}
-
-/*
-** This function is called after the cursor passed as the only argument
+ pCsr->aColumnSize = (int*)&pCsr[1];
+ pCsr->pNext = pGlobal->pCsr;
+ pGlobal->pCsr = pCsr;
+ pCsr->iCsrId = ++pGlobal->iNextId;
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ }
+ *ppCsr = (sqlite3_vtab_cursor*)pCsr;
+ return rc;
+}
+
+static int fts5StmtType(Fts5Cursor *pCsr){
+ if( pCsr->ePlan==FTS5_PLAN_SCAN ){
+ return (pCsr->bDesc) ? FTS5_STMT_SCAN_DESC : FTS5_STMT_SCAN_ASC;
+ }
+ return FTS5_STMT_LOOKUP;
+}
+
+/*
+** This function is called after the cursor passed as the only argument
** is moved to point at a different row. It clears all cached data
-** specific to the previous row stored by the cursor object.
-*/
-static void fts5CsrNewrow(Fts5Cursor *pCsr){
+** specific to the previous row stored by the cursor object.
+*/
+static void fts5CsrNewrow(Fts5Cursor *pCsr){
CsrFlagSet(pCsr,
FTS5CSR_REQUIRE_CONTENT
| FTS5CSR_REQUIRE_DOCSIZE
| FTS5CSR_REQUIRE_INST
| FTS5CSR_REQUIRE_POSLIST
- );
-}
-
-static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
+ );
+}
+
+static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
- Fts5Auxdata *pData;
- Fts5Auxdata *pNext;
-
- sqlite3_free(pCsr->aInstIter);
- sqlite3_free(pCsr->aInst);
- if( pCsr->pStmt ){
- int eStmt = fts5StmtType(pCsr);
- sqlite3Fts5StorageStmtRelease(pTab->pStorage, eStmt, pCsr->pStmt);
- }
- if( pCsr->pSorter ){
- Fts5Sorter *pSorter = pCsr->pSorter;
- sqlite3_finalize(pSorter->pStmt);
- sqlite3_free(pSorter);
- }
-
- if( pCsr->ePlan!=FTS5_PLAN_SOURCE ){
- sqlite3Fts5ExprFree(pCsr->pExpr);
- }
-
- for(pData=pCsr->pAuxdata; pData; pData=pNext){
- pNext = pData->pNext;
- if( pData->xDelete ) pData->xDelete(pData->pPtr);
- sqlite3_free(pData);
- }
-
- sqlite3_finalize(pCsr->pRankArgStmt);
- sqlite3_free(pCsr->apRankArg);
-
- if( CsrFlagTest(pCsr, FTS5CSR_FREE_ZRANK) ){
- sqlite3_free(pCsr->zRank);
- sqlite3_free(pCsr->zRankArgs);
- }
-
+ Fts5Auxdata *pData;
+ Fts5Auxdata *pNext;
+
+ sqlite3_free(pCsr->aInstIter);
+ sqlite3_free(pCsr->aInst);
+ if( pCsr->pStmt ){
+ int eStmt = fts5StmtType(pCsr);
+ sqlite3Fts5StorageStmtRelease(pTab->pStorage, eStmt, pCsr->pStmt);
+ }
+ if( pCsr->pSorter ){
+ Fts5Sorter *pSorter = pCsr->pSorter;
+ sqlite3_finalize(pSorter->pStmt);
+ sqlite3_free(pSorter);
+ }
+
+ if( pCsr->ePlan!=FTS5_PLAN_SOURCE ){
+ sqlite3Fts5ExprFree(pCsr->pExpr);
+ }
+
+ for(pData=pCsr->pAuxdata; pData; pData=pNext){
+ pNext = pData->pNext;
+ if( pData->xDelete ) pData->xDelete(pData->pPtr);
+ sqlite3_free(pData);
+ }
+
+ sqlite3_finalize(pCsr->pRankArgStmt);
+ sqlite3_free(pCsr->apRankArg);
+
+ if( CsrFlagTest(pCsr, FTS5CSR_FREE_ZRANK) ){
+ sqlite3_free(pCsr->zRank);
+ sqlite3_free(pCsr->zRankArgs);
+ }
+
sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
- memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan - (u8*)pCsr));
-}
-
-
-/*
-** Close the cursor. For additional information see the documentation
-** on the xClose method of the virtual table interface.
-*/
-static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){
- if( pCursor ){
+ memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan - (u8*)pCsr));
+}
+
+
+/*
+** Close the cursor. For additional information see the documentation
+** on the xClose method of the virtual table interface.
+*/
+static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){
+ if( pCursor ){
Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
- Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
- Fts5Cursor **pp;
-
- fts5FreeCursorComponents(pCsr);
- /* Remove the cursor from the Fts5Global.pCsr list */
- for(pp=&pTab->pGlobal->pCsr; (*pp)!=pCsr; pp=&(*pp)->pNext);
- *pp = pCsr->pNext;
-
- sqlite3_free(pCsr);
- }
- return SQLITE_OK;
-}
-
-static int fts5SorterNext(Fts5Cursor *pCsr){
- Fts5Sorter *pSorter = pCsr->pSorter;
- int rc;
-
- rc = sqlite3_step(pSorter->pStmt);
- if( rc==SQLITE_DONE ){
- rc = SQLITE_OK;
- CsrFlagSet(pCsr, FTS5CSR_EOF);
- }else if( rc==SQLITE_ROW ){
- const u8 *a;
- const u8 *aBlob;
- int nBlob;
- int i;
- int iOff = 0;
- rc = SQLITE_OK;
-
- pSorter->iRowid = sqlite3_column_int64(pSorter->pStmt, 0);
- nBlob = sqlite3_column_bytes(pSorter->pStmt, 1);
- aBlob = a = sqlite3_column_blob(pSorter->pStmt, 1);
-
- /* nBlob==0 in detail=none mode. */
- if( nBlob>0 ){
- for(i=0; i<(pSorter->nIdx-1); i++){
- int iVal;
- a += fts5GetVarint32(a, iVal);
- iOff += iVal;
- pSorter->aIdx[i] = iOff;
- }
- pSorter->aIdx[i] = &aBlob[nBlob] - a;
- pSorter->aPoslist = a;
- }
-
- fts5CsrNewrow(pCsr);
- }
-
- return rc;
-}
-
-
-/*
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ Fts5Cursor **pp;
+
+ fts5FreeCursorComponents(pCsr);
+ /* Remove the cursor from the Fts5Global.pCsr list */
+ for(pp=&pTab->pGlobal->pCsr; (*pp)!=pCsr; pp=&(*pp)->pNext);
+ *pp = pCsr->pNext;
+
+ sqlite3_free(pCsr);
+ }
+ return SQLITE_OK;
+}
+
+static int fts5SorterNext(Fts5Cursor *pCsr){
+ Fts5Sorter *pSorter = pCsr->pSorter;
+ int rc;
+
+ rc = sqlite3_step(pSorter->pStmt);
+ if( rc==SQLITE_DONE ){
+ rc = SQLITE_OK;
+ CsrFlagSet(pCsr, FTS5CSR_EOF);
+ }else if( rc==SQLITE_ROW ){
+ const u8 *a;
+ const u8 *aBlob;
+ int nBlob;
+ int i;
+ int iOff = 0;
+ rc = SQLITE_OK;
+
+ pSorter->iRowid = sqlite3_column_int64(pSorter->pStmt, 0);
+ nBlob = sqlite3_column_bytes(pSorter->pStmt, 1);
+ aBlob = a = sqlite3_column_blob(pSorter->pStmt, 1);
+
+ /* nBlob==0 in detail=none mode. */
+ if( nBlob>0 ){
+ for(i=0; i<(pSorter->nIdx-1); i++){
+ int iVal;
+ a += fts5GetVarint32(a, iVal);
+ iOff += iVal;
+ pSorter->aIdx[i] = iOff;
+ }
+ pSorter->aIdx[i] = &aBlob[nBlob] - a;
+ pSorter->aPoslist = a;
+ }
+
+ fts5CsrNewrow(pCsr);
+ }
+
+ return rc;
+}
+
+
+/*
** Set the FTS5CSR_REQUIRE_RESEEK flag on all FTS5_PLAN_MATCH cursors
-** open on table pTab.
-*/
+** open on table pTab.
+*/
static void fts5TripCursors(Fts5FullTable *pTab){
- Fts5Cursor *pCsr;
- for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
- if( pCsr->ePlan==FTS5_PLAN_MATCH
+ Fts5Cursor *pCsr;
+ for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
+ if( pCsr->ePlan==FTS5_PLAN_MATCH
&& pCsr->base.pVtab==(sqlite3_vtab*)pTab
- ){
- CsrFlagSet(pCsr, FTS5CSR_REQUIRE_RESEEK);
- }
- }
-}
-
-/*
-** If the REQUIRE_RESEEK flag is set on the cursor passed as the first
+ ){
+ CsrFlagSet(pCsr, FTS5CSR_REQUIRE_RESEEK);
+ }
+ }
+}
+
+/*
+** If the REQUIRE_RESEEK flag is set on the cursor passed as the first
** argument, close and reopen all Fts5IndexIter iterators that the cursor
-** is using. Then attempt to move the cursor to a rowid equal to or laster
+** is using. Then attempt to move the cursor to a rowid equal to or laster
** (in the cursors sort order - ASC or DESC) than the current rowid.
-**
-** If the new rowid is not equal to the old, set output parameter *pbSkip
-** to 1 before returning. Otherwise, leave it unchanged.
-**
+**
+** If the new rowid is not equal to the old, set output parameter *pbSkip
+** to 1 before returning. Otherwise, leave it unchanged.
+**
** Return SQLITE_OK if successful or if no reseek was required, or an
-** error code if an error occurred.
-*/
-static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
- int rc = SQLITE_OK;
- assert( *pbSkip==0 );
- if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
+** error code if an error occurred.
+*/
+static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
+ int rc = SQLITE_OK;
+ assert( *pbSkip==0 );
+ if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
- int bDesc = pCsr->bDesc;
- i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
-
+ int bDesc = pCsr->bDesc;
+ i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
+
rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->p.pIndex, iRowid, bDesc);
- if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
- *pbSkip = 1;
- }
-
- CsrFlagClear(pCsr, FTS5CSR_REQUIRE_RESEEK);
- fts5CsrNewrow(pCsr);
- if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
- CsrFlagSet(pCsr, FTS5CSR_EOF);
- *pbSkip = 1;
- }
- }
- return rc;
-}
-
-
-/*
+ if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
+ *pbSkip = 1;
+ }
+
+ CsrFlagClear(pCsr, FTS5CSR_REQUIRE_RESEEK);
+ fts5CsrNewrow(pCsr);
+ if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
+ CsrFlagSet(pCsr, FTS5CSR_EOF);
+ *pbSkip = 1;
+ }
+ }
+ return rc;
+}
+
+
+/*
** Advance the cursor to the next row in the table that matches the
-** search criteria.
-**
-** Return SQLITE_OK if nothing goes wrong. SQLITE_OK is returned
-** even if we reach end-of-file. The fts5EofMethod() will be called
-** subsequently to determine whether or not an EOF was hit.
-*/
-static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
- int rc;
-
- assert( (pCsr->ePlan<3)==
+** search criteria.
+**
+** Return SQLITE_OK if nothing goes wrong. SQLITE_OK is returned
+** even if we reach end-of-file. The fts5EofMethod() will be called
+** subsequently to determine whether or not an EOF was hit.
+*/
+static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ int rc;
+
+ assert( (pCsr->ePlan<3)==
(pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE)
- );
- assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) );
-
- if( pCsr->ePlan<3 ){
- int bSkip = 0;
- if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
- rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
- CsrFlagSet(pCsr, sqlite3Fts5ExprEof(pCsr->pExpr));
- fts5CsrNewrow(pCsr);
- }else{
- switch( pCsr->ePlan ){
- case FTS5_PLAN_SPECIAL: {
- CsrFlagSet(pCsr, FTS5CSR_EOF);
- rc = SQLITE_OK;
- break;
- }
-
- case FTS5_PLAN_SORTED_MATCH: {
- rc = fts5SorterNext(pCsr);
- break;
- }
+ );
+ assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) );
+
+ if( pCsr->ePlan<3 ){
+ int bSkip = 0;
+ if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
+ rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
+ CsrFlagSet(pCsr, sqlite3Fts5ExprEof(pCsr->pExpr));
+ fts5CsrNewrow(pCsr);
+ }else{
+ switch( pCsr->ePlan ){
+ case FTS5_PLAN_SPECIAL: {
+ CsrFlagSet(pCsr, FTS5CSR_EOF);
+ rc = SQLITE_OK;
+ break;
+ }
+
+ case FTS5_PLAN_SORTED_MATCH: {
+ rc = fts5SorterNext(pCsr);
+ break;
+ }
default: {
Fts5Config *pConfig = ((Fts5Table*)pCursor->pVtab)->pConfig;
pConfig->bLock++;
- rc = sqlite3_step(pCsr->pStmt);
+ rc = sqlite3_step(pCsr->pStmt);
pConfig->bLock--;
- if( rc!=SQLITE_ROW ){
- CsrFlagSet(pCsr, FTS5CSR_EOF);
- rc = sqlite3_reset(pCsr->pStmt);
+ if( rc!=SQLITE_ROW ){
+ CsrFlagSet(pCsr, FTS5CSR_EOF);
+ rc = sqlite3_reset(pCsr->pStmt);
if( rc!=SQLITE_OK ){
pCursor->pVtab->zErrMsg = sqlite3_mprintf(
"%s", sqlite3_errmsg(pConfig->db)
);
}
- }else{
- rc = SQLITE_OK;
- }
- break;
- }
- }
- }
-
- return rc;
-}
-
-
-static int fts5PrepareStatement(
- sqlite3_stmt **ppStmt,
+ }else{
+ rc = SQLITE_OK;
+ }
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+
+static int fts5PrepareStatement(
+ sqlite3_stmt **ppStmt,
Fts5Config *pConfig,
- const char *zFmt,
- ...
-){
- sqlite3_stmt *pRet = 0;
- int rc;
- char *zSql;
- va_list ap;
-
- va_start(ap, zFmt);
- zSql = sqlite3_vmprintf(zFmt, ap);
- if( zSql==0 ){
+ const char *zFmt,
+ ...
+){
+ sqlite3_stmt *pRet = 0;
+ int rc;
+ char *zSql;
+ va_list ap;
+
+ va_start(ap, zFmt);
+ zSql = sqlite3_vmprintf(zFmt, ap);
+ if( zSql==0 ){
rc = SQLITE_NOMEM;
- }else{
+ }else{
rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
- SQLITE_PREPARE_PERSISTENT, &pRet, 0);
- if( rc!=SQLITE_OK ){
- *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db));
- }
- sqlite3_free(zSql);
- }
-
- va_end(ap);
- *ppStmt = pRet;
- return rc;
-}
-
+ SQLITE_PREPARE_PERSISTENT, &pRet, 0);
+ if( rc!=SQLITE_OK ){
+ *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db));
+ }
+ sqlite3_free(zSql);
+ }
+
+ va_end(ap);
+ *ppStmt = pRet;
+ return rc;
+}
+
static int fts5CursorFirstSorted(
Fts5FullTable *pTab,
Fts5Cursor *pCsr,
int bDesc
){
Fts5Config *pConfig = pTab->p.pConfig;
- Fts5Sorter *pSorter;
- int nPhrase;
+ Fts5Sorter *pSorter;
+ int nPhrase;
sqlite3_int64 nByte;
- int rc;
- const char *zRank = pCsr->zRank;
- const char *zRankArgs = pCsr->zRankArgs;
+ int rc;
+ const char *zRank = pCsr->zRank;
+ const char *zRankArgs = pCsr->zRankArgs;
- nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
- nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1);
+ nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
+ nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1);
pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte);
- if( pSorter==0 ) return SQLITE_NOMEM;
+ if( pSorter==0 ) return SQLITE_NOMEM;
memset(pSorter, 0, (size_t)nByte);
- pSorter->nIdx = nPhrase;
-
- /* TODO: It would be better to have some system for reusing statement
- ** handles here, rather than preparing a new one for each query. But that
- ** is not possible as SQLite reference counts the virtual table objects.
+ pSorter->nIdx = nPhrase;
+
+ /* TODO: It would be better to have some system for reusing statement
+ ** handles here, rather than preparing a new one for each query. But that
+ ** is not possible as SQLite reference counts the virtual table objects.
** And since the statement required here reads from this very virtual
- ** table, saving it creates a circular reference.
- **
- ** If SQLite a built-in statement cache, this wouldn't be a problem. */
- rc = fts5PrepareStatement(&pSorter->pStmt, pConfig,
+ ** table, saving it creates a circular reference.
+ **
+ ** If SQLite a built-in statement cache, this wouldn't be a problem. */
+ rc = fts5PrepareStatement(&pSorter->pStmt, pConfig,
"SELECT rowid, rank FROM %Q.%Q ORDER BY %s(\"%w\"%s%s) %s",
- pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
- (zRankArgs ? ", " : ""),
- (zRankArgs ? zRankArgs : ""),
- bDesc ? "DESC" : "ASC"
- );
-
- pCsr->pSorter = pSorter;
- if( rc==SQLITE_OK ){
- assert( pTab->pSortCsr==0 );
- pTab->pSortCsr = pCsr;
- rc = fts5SorterNext(pCsr);
- pTab->pSortCsr = 0;
- }
-
- if( rc!=SQLITE_OK ){
- sqlite3_finalize(pSorter->pStmt);
- sqlite3_free(pSorter);
- pCsr->pSorter = 0;
- }
-
- return rc;
-}
-
+ pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
+ (zRankArgs ? ", " : ""),
+ (zRankArgs ? zRankArgs : ""),
+ bDesc ? "DESC" : "ASC"
+ );
+
+ pCsr->pSorter = pSorter;
+ if( rc==SQLITE_OK ){
+ assert( pTab->pSortCsr==0 );
+ pTab->pSortCsr = pCsr;
+ rc = fts5SorterNext(pCsr);
+ pTab->pSortCsr = 0;
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3_finalize(pSorter->pStmt);
+ sqlite3_free(pSorter);
+ pCsr->pSorter = 0;
+ }
+
+ return rc;
+}
+
static int fts5CursorFirst(Fts5FullTable *pTab, Fts5Cursor *pCsr, int bDesc){
- int rc;
- Fts5Expr *pExpr = pCsr->pExpr;
+ int rc;
+ Fts5Expr *pExpr = pCsr->pExpr;
rc = sqlite3Fts5ExprFirst(pExpr, pTab->p.pIndex, pCsr->iFirstRowid, bDesc);
- if( sqlite3Fts5ExprEof(pExpr) ){
- CsrFlagSet(pCsr, FTS5CSR_EOF);
- }
- fts5CsrNewrow(pCsr);
- return rc;
-}
-
-/*
-** Process a "special" query. A special query is identified as one with a
-** MATCH expression that begins with a '*' character. The remainder of
-** the text passed to the MATCH operator are used as the special query
-** parameters.
-*/
-static int fts5SpecialMatch(
+ if( sqlite3Fts5ExprEof(pExpr) ){
+ CsrFlagSet(pCsr, FTS5CSR_EOF);
+ }
+ fts5CsrNewrow(pCsr);
+ return rc;
+}
+
+/*
+** Process a "special" query. A special query is identified as one with a
+** MATCH expression that begins with a '*' character. The remainder of
+** the text passed to the MATCH operator are used as the special query
+** parameters.
+*/
+static int fts5SpecialMatch(
Fts5FullTable *pTab,
Fts5Cursor *pCsr,
- const char *zQuery
-){
- int rc = SQLITE_OK; /* Return code */
- const char *z = zQuery; /* Special query text */
- int n; /* Number of bytes in text at z */
-
- while( z[0]==' ' ) z++;
- for(n=0; z[n] && z[n]!=' '; n++);
-
+ const char *zQuery
+){
+ int rc = SQLITE_OK; /* Return code */
+ const char *z = zQuery; /* Special query text */
+ int n; /* Number of bytes in text at z */
+
+ while( z[0]==' ' ) z++;
+ for(n=0; z[n] && z[n]!=' '; n++);
+
assert( pTab->p.base.zErrMsg==0 );
- pCsr->ePlan = FTS5_PLAN_SPECIAL;
-
+ pCsr->ePlan = FTS5_PLAN_SPECIAL;
+
if( n==5 && 0==sqlite3_strnicmp("reads", z, n) ){
pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex);
- }
+ }
else if( n==2 && 0==sqlite3_strnicmp("id", z, n) ){
- pCsr->iSpecial = pCsr->iCsrId;
- }
- else{
- /* An unrecognized directive. Return an error message. */
+ pCsr->iSpecial = pCsr->iCsrId;
+ }
+ else{
+ /* An unrecognized directive. Return an error message. */
pTab->p.base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
- rc = SQLITE_ERROR;
- }
-
- return rc;
-}
-
-/*
-** Search for an auxiliary function named zName that can be used with table
-** pTab. If one is found, return a pointer to the corresponding Fts5Auxiliary
-** structure. Otherwise, if no such function exists, return NULL.
-*/
+ rc = SQLITE_ERROR;
+ }
+
+ return rc;
+}
+
+/*
+** Search for an auxiliary function named zName that can be used with table
+** pTab. If one is found, return a pointer to the corresponding Fts5Auxiliary
+** structure. Otherwise, if no such function exists, return NULL.
+*/
static Fts5Auxiliary *fts5FindAuxiliary(Fts5FullTable *pTab, const char *zName){
- Fts5Auxiliary *pAux;
-
- for(pAux=pTab->pGlobal->pAux; pAux; pAux=pAux->pNext){
- if( sqlite3_stricmp(zName, pAux->zFunc)==0 ) return pAux;
- }
-
- /* No function of the specified name was found. Return 0. */
- return 0;
-}
-
-
-static int fts5FindRankFunction(Fts5Cursor *pCsr){
+ Fts5Auxiliary *pAux;
+
+ for(pAux=pTab->pGlobal->pAux; pAux; pAux=pAux->pNext){
+ if( sqlite3_stricmp(zName, pAux->zFunc)==0 ) return pAux;
+ }
+
+ /* No function of the specified name was found. Return 0. */
+ return 0;
+}
+
+
+static int fts5FindRankFunction(Fts5Cursor *pCsr){
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
Fts5Config *pConfig = pTab->p.pConfig;
- int rc = SQLITE_OK;
- Fts5Auxiliary *pAux = 0;
- const char *zRank = pCsr->zRank;
- const char *zRankArgs = pCsr->zRankArgs;
-
- if( zRankArgs ){
- char *zSql = sqlite3Fts5Mprintf(&rc, "SELECT %s", zRankArgs);
- if( zSql ){
- sqlite3_stmt *pStmt = 0;
- rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
- SQLITE_PREPARE_PERSISTENT, &pStmt, 0);
- sqlite3_free(zSql);
- assert( rc==SQLITE_OK || pCsr->pRankArgStmt==0 );
- if( rc==SQLITE_OK ){
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
+ int rc = SQLITE_OK;
+ Fts5Auxiliary *pAux = 0;
+ const char *zRank = pCsr->zRank;
+ const char *zRankArgs = pCsr->zRankArgs;
+
+ if( zRankArgs ){
+ char *zSql = sqlite3Fts5Mprintf(&rc, "SELECT %s", zRankArgs);
+ if( zSql ){
+ sqlite3_stmt *pStmt = 0;
+ rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
+ SQLITE_PREPARE_PERSISTENT, &pStmt, 0);
+ sqlite3_free(zSql);
+ assert( rc==SQLITE_OK || pCsr->pRankArgStmt==0 );
+ if( rc==SQLITE_OK ){
+ if( SQLITE_ROW==sqlite3_step(pStmt) ){
sqlite3_int64 nByte;
- pCsr->nRankArg = sqlite3_column_count(pStmt);
- nByte = sizeof(sqlite3_value*)*pCsr->nRankArg;
- pCsr->apRankArg = (sqlite3_value**)sqlite3Fts5MallocZero(&rc, nByte);
- if( rc==SQLITE_OK ){
- int i;
- for(i=0; i<pCsr->nRankArg; i++){
- pCsr->apRankArg[i] = sqlite3_column_value(pStmt, i);
- }
- }
- pCsr->pRankArgStmt = pStmt;
- }else{
- rc = sqlite3_finalize(pStmt);
- assert( rc!=SQLITE_OK );
- }
- }
- }
- }
-
- if( rc==SQLITE_OK ){
- pAux = fts5FindAuxiliary(pTab, zRank);
- if( pAux==0 ){
+ pCsr->nRankArg = sqlite3_column_count(pStmt);
+ nByte = sizeof(sqlite3_value*)*pCsr->nRankArg;
+ pCsr->apRankArg = (sqlite3_value**)sqlite3Fts5MallocZero(&rc, nByte);
+ if( rc==SQLITE_OK ){
+ int i;
+ for(i=0; i<pCsr->nRankArg; i++){
+ pCsr->apRankArg[i] = sqlite3_column_value(pStmt, i);
+ }
+ }
+ pCsr->pRankArgStmt = pStmt;
+ }else{
+ rc = sqlite3_finalize(pStmt);
+ assert( rc!=SQLITE_OK );
+ }
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ pAux = fts5FindAuxiliary(pTab, zRank);
+ if( pAux==0 ){
assert( pTab->p.base.zErrMsg==0 );
pTab->p.base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank);
- rc = SQLITE_ERROR;
- }
- }
-
- pCsr->pRank = pAux;
- return rc;
-}
-
-
-static int fts5CursorParseRank(
- Fts5Config *pConfig,
+ rc = SQLITE_ERROR;
+ }
+ }
+
+ pCsr->pRank = pAux;
+ return rc;
+}
+
+
+static int fts5CursorParseRank(
+ Fts5Config *pConfig,
Fts5Cursor *pCsr,
- sqlite3_value *pRank
-){
- int rc = SQLITE_OK;
- if( pRank ){
- const char *z = (const char*)sqlite3_value_text(pRank);
- char *zRank = 0;
- char *zRankArgs = 0;
-
- if( z==0 ){
- if( sqlite3_value_type(pRank)==SQLITE_NULL ) rc = SQLITE_ERROR;
- }else{
- rc = sqlite3Fts5ConfigParseRank(z, &zRank, &zRankArgs);
- }
- if( rc==SQLITE_OK ){
- pCsr->zRank = zRank;
- pCsr->zRankArgs = zRankArgs;
- CsrFlagSet(pCsr, FTS5CSR_FREE_ZRANK);
- }else if( rc==SQLITE_ERROR ){
- pCsr->base.pVtab->zErrMsg = sqlite3_mprintf(
- "parse error in rank function: %s", z
- );
- }
- }else{
- if( pConfig->zRank ){
- pCsr->zRank = (char*)pConfig->zRank;
- pCsr->zRankArgs = (char*)pConfig->zRankArgs;
- }else{
- pCsr->zRank = (char*)FTS5_DEFAULT_RANK;
- pCsr->zRankArgs = 0;
- }
- }
- return rc;
-}
-
-static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){
- if( pVal ){
- int eType = sqlite3_value_numeric_type(pVal);
- if( eType==SQLITE_INTEGER ){
- return sqlite3_value_int64(pVal);
- }
- }
- return iDefault;
-}
-
-/*
-** This is the xFilter interface for the virtual table. See
-** the virtual table xFilter method documentation for additional
-** information.
-**
-** There are three possible query strategies:
-**
-** 1. Full-text search using a MATCH operator.
-** 2. A by-rowid lookup.
-** 3. A full-table scan.
-*/
-static int fts5FilterMethod(
- sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
- int idxNum, /* Strategy index */
+ sqlite3_value *pRank
+){
+ int rc = SQLITE_OK;
+ if( pRank ){
+ const char *z = (const char*)sqlite3_value_text(pRank);
+ char *zRank = 0;
+ char *zRankArgs = 0;
+
+ if( z==0 ){
+ if( sqlite3_value_type(pRank)==SQLITE_NULL ) rc = SQLITE_ERROR;
+ }else{
+ rc = sqlite3Fts5ConfigParseRank(z, &zRank, &zRankArgs);
+ }
+ if( rc==SQLITE_OK ){
+ pCsr->zRank = zRank;
+ pCsr->zRankArgs = zRankArgs;
+ CsrFlagSet(pCsr, FTS5CSR_FREE_ZRANK);
+ }else if( rc==SQLITE_ERROR ){
+ pCsr->base.pVtab->zErrMsg = sqlite3_mprintf(
+ "parse error in rank function: %s", z
+ );
+ }
+ }else{
+ if( pConfig->zRank ){
+ pCsr->zRank = (char*)pConfig->zRank;
+ pCsr->zRankArgs = (char*)pConfig->zRankArgs;
+ }else{
+ pCsr->zRank = (char*)FTS5_DEFAULT_RANK;
+ pCsr->zRankArgs = 0;
+ }
+ }
+ return rc;
+}
+
+static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){
+ if( pVal ){
+ int eType = sqlite3_value_numeric_type(pVal);
+ if( eType==SQLITE_INTEGER ){
+ return sqlite3_value_int64(pVal);
+ }
+ }
+ return iDefault;
+}
+
+/*
+** This is the xFilter interface for the virtual table. See
+** the virtual table xFilter method documentation for additional
+** information.
+**
+** There are three possible query strategies:
+**
+** 1. Full-text search using a MATCH operator.
+** 2. A by-rowid lookup.
+** 3. A full-table scan.
+*/
+static int fts5FilterMethod(
+ sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
+ int idxNum, /* Strategy index */
const char *idxStr, /* Unused */
- int nVal, /* Number of elements in apVal */
- sqlite3_value **apVal /* Arguments for the indexing scheme */
-){
+ int nVal, /* Number of elements in apVal */
+ sqlite3_value **apVal /* Arguments for the indexing scheme */
+){
Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
Fts5Config *pConfig = pTab->p.pConfig;
- Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
- int rc = SQLITE_OK; /* Error code */
- int bDesc; /* True if ORDER BY [rank|rowid] DESC */
- int bOrderByRank; /* True if ORDER BY rank */
- sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */
- sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
- sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
- sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
- int iCol; /* Column on LHS of MATCH operator */
- char **pzErrmsg = pConfig->pzErrmsg;
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ int rc = SQLITE_OK; /* Error code */
+ int bDesc; /* True if ORDER BY [rank|rowid] DESC */
+ int bOrderByRank; /* True if ORDER BY rank */
+ sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */
+ sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
+ sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
+ sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
+ int iCol; /* Column on LHS of MATCH operator */
+ char **pzErrmsg = pConfig->pzErrmsg;
int i;
int iIdxStr = 0;
Fts5Expr *pExpr = 0;
-
+
if( pConfig->bLock ){
pTab->p.base.zErrMsg = sqlite3_mprintf(
"recursively defined fts5 content table"
);
return SQLITE_ERROR;
}
-
- if( pCsr->ePlan ){
- fts5FreeCursorComponents(pCsr);
- memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
- }
-
- assert( pCsr->pStmt==0 );
- assert( pCsr->pExpr==0 );
- assert( pCsr->csrflags==0 );
- assert( pCsr->pRank==0 );
- assert( pCsr->zRank==0 );
- assert( pCsr->zRankArgs==0 );
+
+ if( pCsr->ePlan ){
+ fts5FreeCursorComponents(pCsr);
+ memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
+ }
+
+ assert( pCsr->pStmt==0 );
+ assert( pCsr->pExpr==0 );
+ assert( pCsr->csrflags==0 );
+ assert( pCsr->pRank==0 );
+ assert( pCsr->zRank==0 );
+ assert( pCsr->zRankArgs==0 );
assert( pTab->pSortCsr==0 || nVal==0 );
-
+
assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg );
pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
-
+
/* Decode the arguments passed through to this function. */
for(i=0; i<nVal; i++){
switch( idxStr[iIdxStr++] ){
@@ -231069,35 +231069,35 @@ static int fts5FilterMethod(
break;
}
}
- bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
- pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
-
+ bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
+ pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
+
/* Set the cursor upper and lower rowid limits. Only some strategies
- ** actually use them. This is ok, as the xBestIndex() method leaves the
- ** sqlite3_index_constraint.omit flag clear for range constraints
- ** on the rowid field. */
- if( pRowidEq ){
- pRowidLe = pRowidGe = pRowidEq;
- }
- if( bDesc ){
- pCsr->iFirstRowid = fts5GetRowidLimit(pRowidLe, LARGEST_INT64);
- pCsr->iLastRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64);
- }else{
- pCsr->iLastRowid = fts5GetRowidLimit(pRowidLe, LARGEST_INT64);
- pCsr->iFirstRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64);
- }
-
- if( pTab->pSortCsr ){
+ ** actually use them. This is ok, as the xBestIndex() method leaves the
+ ** sqlite3_index_constraint.omit flag clear for range constraints
+ ** on the rowid field. */
+ if( pRowidEq ){
+ pRowidLe = pRowidGe = pRowidEq;
+ }
+ if( bDesc ){
+ pCsr->iFirstRowid = fts5GetRowidLimit(pRowidLe, LARGEST_INT64);
+ pCsr->iLastRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64);
+ }else{
+ pCsr->iLastRowid = fts5GetRowidLimit(pRowidLe, LARGEST_INT64);
+ pCsr->iFirstRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64);
+ }
+
+ if( pTab->pSortCsr ){
/* If pSortCsr is non-NULL, then this call is being made as part of
- ** processing for a "... MATCH <expr> ORDER BY rank" query (ePlan is
- ** set to FTS5_PLAN_SORTED_MATCH). pSortCsr is the cursor that will
+ ** processing for a "... MATCH <expr> ORDER BY rank" query (ePlan is
+ ** set to FTS5_PLAN_SORTED_MATCH). pSortCsr is the cursor that will
** return results to the user for this query. The current cursor
** (pCursor) is used to execute the query issued by function
- ** fts5CursorFirstSorted() above. */
- assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 );
+ ** fts5CursorFirstSorted() above. */
+ assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 );
assert( nVal==0 && bOrderByRank==0 && bDesc==0 );
- assert( pCsr->iLastRowid==LARGEST_INT64 );
- assert( pCsr->iFirstRowid==SMALLEST_INT64 );
+ assert( pCsr->iLastRowid==LARGEST_INT64 );
+ assert( pCsr->iFirstRowid==SMALLEST_INT64 );
if( pTab->pSortCsr->bDesc ){
pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid;
pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid;
@@ -231105,354 +231105,354 @@ static int fts5FilterMethod(
pCsr->iLastRowid = pTab->pSortCsr->iLastRowid;
pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid;
}
- pCsr->ePlan = FTS5_PLAN_SOURCE;
- pCsr->pExpr = pTab->pSortCsr->pExpr;
- rc = fts5CursorFirst(pTab, pCsr, bDesc);
+ pCsr->ePlan = FTS5_PLAN_SOURCE;
+ pCsr->pExpr = pTab->pSortCsr->pExpr;
+ rc = fts5CursorFirst(pTab, pCsr, bDesc);
}else if( pCsr->pExpr ){
- rc = fts5CursorParseRank(pConfig, pCsr, pRank);
- if( rc==SQLITE_OK ){
+ rc = fts5CursorParseRank(pConfig, pCsr, pRank);
+ if( rc==SQLITE_OK ){
if( bOrderByRank ){
pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
- }else{
+ }else{
pCsr->ePlan = FTS5_PLAN_MATCH;
rc = fts5CursorFirst(pTab, pCsr, bDesc);
- }
- }
- }else if( pConfig->zContent==0 ){
- *pConfig->pzErrmsg = sqlite3_mprintf(
- "%s: table does not support scanning", pConfig->zName
- );
- rc = SQLITE_ERROR;
- }else{
- /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup
- ** by rowid (ePlan==FTS5_PLAN_ROWID). */
- pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
- rc = sqlite3Fts5StorageStmt(
+ }
+ }
+ }else if( pConfig->zContent==0 ){
+ *pConfig->pzErrmsg = sqlite3_mprintf(
+ "%s: table does not support scanning", pConfig->zName
+ );
+ rc = SQLITE_ERROR;
+ }else{
+ /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup
+ ** by rowid (ePlan==FTS5_PLAN_ROWID). */
+ pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
+ rc = sqlite3Fts5StorageStmt(
pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg
- );
- if( rc==SQLITE_OK ){
+ );
+ if( rc==SQLITE_OK ){
if( pRowidEq!=0 ){
assert( pCsr->ePlan==FTS5_PLAN_ROWID );
sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq);
- }else{
- sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
- sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
- }
- rc = fts5NextMethod(pCursor);
- }
- }
-
+ }else{
+ sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
+ sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
+ }
+ rc = fts5NextMethod(pCursor);
+ }
+ }
+
filter_out:
sqlite3Fts5ExprFree(pExpr);
- pConfig->pzErrmsg = pzErrmsg;
- return rc;
-}
-
+ pConfig->pzErrmsg = pzErrmsg;
+ return rc;
+}
+
/*
** This is the xEof method of the virtual table. SQLite calls this
-** routine to find out if it has reached the end of a result set.
-*/
-static int fts5EofMethod(sqlite3_vtab_cursor *pCursor){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
- return (CsrFlagTest(pCsr, FTS5CSR_EOF) ? 1 : 0);
-}
-
-/*
-** Return the rowid that the cursor currently points to.
-*/
-static i64 fts5CursorRowid(Fts5Cursor *pCsr){
+** routine to find out if it has reached the end of a result set.
+*/
+static int fts5EofMethod(sqlite3_vtab_cursor *pCursor){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ return (CsrFlagTest(pCsr, FTS5CSR_EOF) ? 1 : 0);
+}
+
+/*
+** Return the rowid that the cursor currently points to.
+*/
+static i64 fts5CursorRowid(Fts5Cursor *pCsr){
assert( pCsr->ePlan==FTS5_PLAN_MATCH
|| pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
|| pCsr->ePlan==FTS5_PLAN_SOURCE
- );
- if( pCsr->pSorter ){
- return pCsr->pSorter->iRowid;
- }else{
- return sqlite3Fts5ExprRowid(pCsr->pExpr);
- }
-}
-
-/*
-** This is the xRowid method. The SQLite core calls this routine to
-** retrieve the rowid for the current row of the result set. fts5
-** exposes %_content.rowid as the rowid for the virtual table. The
-** rowid should be written to *pRowid.
-*/
-static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
- int ePlan = pCsr->ePlan;
-
- assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 );
- switch( ePlan ){
- case FTS5_PLAN_SPECIAL:
- *pRowid = 0;
- break;
-
- case FTS5_PLAN_SOURCE:
- case FTS5_PLAN_MATCH:
- case FTS5_PLAN_SORTED_MATCH:
- *pRowid = fts5CursorRowid(pCsr);
- break;
-
- default:
- *pRowid = sqlite3_column_int64(pCsr->pStmt, 0);
- break;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** If the cursor requires seeking (bSeekRequired flag is set), seek it.
-** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise.
-**
-** If argument bErrormsg is true and an error occurs, an error message may
-** be left in sqlite3_vtab.zErrMsg.
-*/
-static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
- int rc = SQLITE_OK;
-
+ );
+ if( pCsr->pSorter ){
+ return pCsr->pSorter->iRowid;
+ }else{
+ return sqlite3Fts5ExprRowid(pCsr->pExpr);
+ }
+}
+
+/*
+** This is the xRowid method. The SQLite core calls this routine to
+** retrieve the rowid for the current row of the result set. fts5
+** exposes %_content.rowid as the rowid for the virtual table. The
+** rowid should be written to *pRowid.
+*/
+static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ int ePlan = pCsr->ePlan;
+
+ assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 );
+ switch( ePlan ){
+ case FTS5_PLAN_SPECIAL:
+ *pRowid = 0;
+ break;
+
+ case FTS5_PLAN_SOURCE:
+ case FTS5_PLAN_MATCH:
+ case FTS5_PLAN_SORTED_MATCH:
+ *pRowid = fts5CursorRowid(pCsr);
+ break;
+
+ default:
+ *pRowid = sqlite3_column_int64(pCsr->pStmt, 0);
+ break;
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** If the cursor requires seeking (bSeekRequired flag is set), seek it.
+** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise.
+**
+** If argument bErrormsg is true and an error occurs, an error message may
+** be left in sqlite3_vtab.zErrMsg.
+*/
+static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
+ int rc = SQLITE_OK;
+
/* If the cursor does not yet have a statement handle, obtain one now. */
- if( pCsr->pStmt==0 ){
+ if( pCsr->pStmt==0 ){
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
- int eStmt = fts5StmtType(pCsr);
- rc = sqlite3Fts5StorageStmt(
+ int eStmt = fts5StmtType(pCsr);
+ rc = sqlite3Fts5StorageStmt(
pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->p.base.zErrMsg:0)
- );
+ );
assert( rc!=SQLITE_OK || pTab->p.base.zErrMsg==0 );
- assert( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) );
- }
-
- if( rc==SQLITE_OK && CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) ){
+ assert( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) );
+ }
+
+ if( rc==SQLITE_OK && CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) ){
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
- assert( pCsr->pExpr );
- sqlite3_reset(pCsr->pStmt);
- sqlite3_bind_int64(pCsr->pStmt, 1, fts5CursorRowid(pCsr));
+ assert( pCsr->pExpr );
+ sqlite3_reset(pCsr->pStmt);
+ sqlite3_bind_int64(pCsr->pStmt, 1, fts5CursorRowid(pCsr));
pTab->pConfig->bLock++;
- rc = sqlite3_step(pCsr->pStmt);
+ rc = sqlite3_step(pCsr->pStmt);
pTab->pConfig->bLock--;
- if( rc==SQLITE_ROW ){
- rc = SQLITE_OK;
- CsrFlagClear(pCsr, FTS5CSR_REQUIRE_CONTENT);
- }else{
- rc = sqlite3_reset(pCsr->pStmt);
- if( rc==SQLITE_OK ){
- rc = FTS5_CORRUPT;
+ if( rc==SQLITE_ROW ){
+ rc = SQLITE_OK;
+ CsrFlagClear(pCsr, FTS5CSR_REQUIRE_CONTENT);
+ }else{
+ rc = sqlite3_reset(pCsr->pStmt);
+ if( rc==SQLITE_OK ){
+ rc = FTS5_CORRUPT;
}else if( pTab->pConfig->pzErrmsg ){
*pTab->pConfig->pzErrmsg = sqlite3_mprintf(
"%s", sqlite3_errmsg(pTab->pConfig->db)
);
- }
- }
- }
- return rc;
-}
-
+ }
+ }
+ }
+ return rc;
+}
+
static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){
- va_list ap; /* ... printf arguments */
- va_start(ap, zFormat);
+ va_list ap; /* ... printf arguments */
+ va_start(ap, zFormat);
assert( p->p.base.zErrMsg==0 );
p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
- va_end(ap);
-}
-
-/*
-** This function is called to handle an FTS INSERT command. In other words,
-** an INSERT statement of the form:
-**
-** INSERT INTO fts(fts) VALUES($pCmd)
-** INSERT INTO fts(fts, rank) VALUES($pCmd, $pVal)
-**
+ va_end(ap);
+}
+
+/*
+** This function is called to handle an FTS INSERT command. In other words,
+** an INSERT statement of the form:
+**
+** INSERT INTO fts(fts) VALUES($pCmd)
+** INSERT INTO fts(fts, rank) VALUES($pCmd, $pVal)
+**
** Argument pVal is the value assigned to column "fts" by the INSERT
-** statement. This function returns SQLITE_OK if successful, or an SQLite
-** error code if an error occurs.
-**
-** The commands implemented by this function are documented in the "Special
-** INSERT Directives" section of the documentation. It should be updated if
-** more commands are added to this function.
-*/
-static int fts5SpecialInsert(
+** statement. This function returns SQLITE_OK if successful, or an SQLite
+** error code if an error occurs.
+**
+** The commands implemented by this function are documented in the "Special
+** INSERT Directives" section of the documentation. It should be updated if
+** more commands are added to this function.
+*/
+static int fts5SpecialInsert(
Fts5FullTable *pTab, /* Fts5 table object */
- const char *zCmd, /* Text inserted into table-name column */
- sqlite3_value *pVal /* Value inserted into rank column */
-){
+ const char *zCmd, /* Text inserted into table-name column */
+ sqlite3_value *pVal /* Value inserted into rank column */
+){
Fts5Config *pConfig = pTab->p.pConfig;
- int rc = SQLITE_OK;
- int bError = 0;
-
- if( 0==sqlite3_stricmp("delete-all", zCmd) ){
- if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ int rc = SQLITE_OK;
+ int bError = 0;
+
+ if( 0==sqlite3_stricmp("delete-all", zCmd) ){
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
fts5SetVtabError(pTab,
- "'delete-all' may only be used with a "
- "contentless or external content fts5 table"
- );
- rc = SQLITE_ERROR;
- }else{
- rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage);
- }
- }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){
- if( pConfig->eContent==FTS5_CONTENT_NONE ){
+ "'delete-all' may only be used with a "
+ "contentless or external content fts5 table"
+ );
+ rc = SQLITE_ERROR;
+ }else{
+ rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage);
+ }
+ }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){
+ if( pConfig->eContent==FTS5_CONTENT_NONE ){
fts5SetVtabError(pTab,
- "'rebuild' may not be used with a contentless fts5 table"
- );
- rc = SQLITE_ERROR;
- }else{
- rc = sqlite3Fts5StorageRebuild(pTab->pStorage);
- }
- }else if( 0==sqlite3_stricmp("optimize", zCmd) ){
- rc = sqlite3Fts5StorageOptimize(pTab->pStorage);
- }else if( 0==sqlite3_stricmp("merge", zCmd) ){
- int nMerge = sqlite3_value_int(pVal);
- rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge);
- }else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){
+ "'rebuild' may not be used with a contentless fts5 table"
+ );
+ rc = SQLITE_ERROR;
+ }else{
+ rc = sqlite3Fts5StorageRebuild(pTab->pStorage);
+ }
+ }else if( 0==sqlite3_stricmp("optimize", zCmd) ){
+ rc = sqlite3Fts5StorageOptimize(pTab->pStorage);
+ }else if( 0==sqlite3_stricmp("merge", zCmd) ){
+ int nMerge = sqlite3_value_int(pVal);
+ rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge);
+ }else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){
int iArg = sqlite3_value_int(pVal);
rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, iArg);
-#ifdef SQLITE_DEBUG
- }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){
- pConfig->bPrefixIndex = sqlite3_value_int(pVal);
-#endif
- }else{
+#ifdef SQLITE_DEBUG
+ }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){
+ pConfig->bPrefixIndex = sqlite3_value_int(pVal);
+#endif
+ }else{
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError);
- }
- if( rc==SQLITE_OK ){
- if( bError ){
- rc = SQLITE_ERROR;
- }else{
- rc = sqlite3Fts5StorageConfigValue(pTab->pStorage, zCmd, pVal, 0);
- }
- }
- }
- return rc;
-}
-
-static int fts5SpecialDelete(
+ }
+ if( rc==SQLITE_OK ){
+ if( bError ){
+ rc = SQLITE_ERROR;
+ }else{
+ rc = sqlite3Fts5StorageConfigValue(pTab->pStorage, zCmd, pVal, 0);
+ }
+ }
+ }
+ return rc;
+}
+
+static int fts5SpecialDelete(
Fts5FullTable *pTab,
- sqlite3_value **apVal
-){
- int rc = SQLITE_OK;
- int eType1 = sqlite3_value_type(apVal[1]);
- if( eType1==SQLITE_INTEGER ){
- sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]);
- }
- return rc;
-}
-
-static void fts5StorageInsert(
+ sqlite3_value **apVal
+){
+ int rc = SQLITE_OK;
+ int eType1 = sqlite3_value_type(apVal[1]);
+ if( eType1==SQLITE_INTEGER ){
+ sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]);
+ }
+ return rc;
+}
+
+static void fts5StorageInsert(
int *pRc,
Fts5FullTable *pTab,
sqlite3_value **apVal,
- i64 *piRowid
-){
- int rc = *pRc;
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid);
- }
- *pRc = rc;
-}
-
+ i64 *piRowid
+){
+ int rc = *pRc;
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid);
+ }
+ *pRc = rc;
+}
+
/*
** This function is the implementation of the xUpdate callback used by
-** FTS3 virtual tables. It is invoked by SQLite each time a row is to be
-** inserted, updated or deleted.
-**
-** A delete specifies a single argument - the rowid of the row to remove.
-**
-** Update and insert operations pass:
-**
-** 1. The "old" rowid, or NULL.
-** 2. The "new" rowid.
-** 3. Values for each of the nCol matchable columns.
-** 4. Values for the two hidden columns (<tablename> and "rank").
-*/
-static int fts5UpdateMethod(
- sqlite3_vtab *pVtab, /* Virtual table handle */
- int nArg, /* Size of argument array */
- sqlite3_value **apVal, /* Array of arguments */
- sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
-){
+** FTS3 virtual tables. It is invoked by SQLite each time a row is to be
+** inserted, updated or deleted.
+**
+** A delete specifies a single argument - the rowid of the row to remove.
+**
+** Update and insert operations pass:
+**
+** 1. The "old" rowid, or NULL.
+** 2. The "new" rowid.
+** 3. Values for each of the nCol matchable columns.
+** 4. Values for the two hidden columns (<tablename> and "rank").
+*/
+static int fts5UpdateMethod(
+ sqlite3_vtab *pVtab, /* Virtual table handle */
+ int nArg, /* Size of argument array */
+ sqlite3_value **apVal, /* Array of arguments */
+ sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
+){
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
Fts5Config *pConfig = pTab->p.pConfig;
- int eType0; /* value_type() of apVal[0] */
- int rc = SQLITE_OK; /* Return code */
-
- /* A transaction must be open when this is called. */
- assert( pTab->ts.eState==1 );
-
- assert( pVtab->zErrMsg==0 );
- assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
+ int eType0; /* value_type() of apVal[0] */
+ int rc = SQLITE_OK; /* Return code */
+
+ /* A transaction must be open when this is called. */
+ assert( pTab->ts.eState==1 );
+
+ assert( pVtab->zErrMsg==0 );
+ assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER
|| sqlite3_value_type(apVal[0])==SQLITE_NULL
- );
+ );
assert( pTab->p.pConfig->pzErrmsg==0 );
pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
-
- /* Put any active cursors into REQUIRE_SEEK state. */
- fts5TripCursors(pTab);
-
- eType0 = sqlite3_value_type(apVal[0]);
+
+ /* Put any active cursors into REQUIRE_SEEK state. */
+ fts5TripCursors(pTab);
+
+ eType0 = sqlite3_value_type(apVal[0]);
if( eType0==SQLITE_NULL
&& sqlite3_value_type(apVal[2+pConfig->nCol])!=SQLITE_NULL
- ){
- /* A "special" INSERT op. These are handled separately. */
- const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]);
+ ){
+ /* A "special" INSERT op. These are handled separately. */
+ const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]);
if( pConfig->eContent!=FTS5_CONTENT_NORMAL
&& 0==sqlite3_stricmp("delete", z)
- ){
- rc = fts5SpecialDelete(pTab, apVal);
- }else{
- rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
- }
- }else{
- /* A regular INSERT, UPDATE or DELETE statement. The trick here is that
+ ){
+ rc = fts5SpecialDelete(pTab, apVal);
+ }else{
+ rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
+ }
+ }else{
+ /* A regular INSERT, UPDATE or DELETE statement. The trick here is that
** any conflict on the rowid value must be detected before any
- ** modifications are made to the database file. There are 4 cases:
- **
- ** 1) DELETE
- ** 2) UPDATE (rowid not modified)
- ** 3) UPDATE (rowid modified)
- ** 4) INSERT
- **
- ** Cases 3 and 4 may violate the rowid constraint.
- */
- int eConflict = SQLITE_ABORT;
- if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
- eConflict = sqlite3_vtab_on_conflict(pConfig->db);
- }
-
- assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
- assert( nArg!=1 || eType0==SQLITE_INTEGER );
-
- /* Filter out attempts to run UPDATE or DELETE on contentless tables.
- ** This is not suported. */
- if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){
+ ** modifications are made to the database file. There are 4 cases:
+ **
+ ** 1) DELETE
+ ** 2) UPDATE (rowid not modified)
+ ** 3) UPDATE (rowid modified)
+ ** 4) INSERT
+ **
+ ** Cases 3 and 4 may violate the rowid constraint.
+ */
+ int eConflict = SQLITE_ABORT;
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ eConflict = sqlite3_vtab_on_conflict(pConfig->db);
+ }
+
+ assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
+ assert( nArg!=1 || eType0==SQLITE_INTEGER );
+
+ /* Filter out attempts to run UPDATE or DELETE on contentless tables.
+ ** This is not suported. */
+ if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){
pTab->p.base.zErrMsg = sqlite3_mprintf(
"cannot %s contentless fts5 table: %s",
- (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
- );
- rc = SQLITE_ERROR;
- }
-
- /* DELETE */
- else if( nArg==1 ){
- i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
- }
-
+ (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
+ );
+ rc = SQLITE_ERROR;
+ }
+
+ /* DELETE */
+ else if( nArg==1 ){
+ i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
+ }
+
/* INSERT or UPDATE */
else{
int eType1 = sqlite3_value_numeric_type(apVal[1]);
if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){
rc = SQLITE_MISMATCH;
- }
-
+ }
+
else if( eType0!=SQLITE_INTEGER ){
/* If this is a REPLACE, first remove the current entry (if any) */
if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
@@ -231483,1010 +231483,1010 @@ static int fts5UpdateMethod(
}
}
}else{
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
- fts5StorageInsert(&rc, pTab, apVal, pRowid);
- }
- }
- }
- }
-
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
+ fts5StorageInsert(&rc, pTab, apVal, pRowid);
+ }
+ }
+ }
+ }
+
pTab->p.pConfig->pzErrmsg = 0;
- return rc;
-}
-
-/*
+ return rc;
+}
+
+/*
** Implementation of xSync() method.
-*/
-static int fts5SyncMethod(sqlite3_vtab *pVtab){
- int rc;
+*/
+static int fts5SyncMethod(sqlite3_vtab *pVtab){
+ int rc;
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
- fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
+ fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
- fts5TripCursors(pTab);
- rc = sqlite3Fts5StorageSync(pTab->pStorage);
+ fts5TripCursors(pTab);
+ rc = sqlite3Fts5StorageSync(pTab->pStorage);
pTab->p.pConfig->pzErrmsg = 0;
- return rc;
-}
-
-/*
+ return rc;
+}
+
+/*
** Implementation of xBegin() method.
-*/
-static int fts5BeginMethod(sqlite3_vtab *pVtab){
+*/
+static int fts5BeginMethod(sqlite3_vtab *pVtab){
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
fts5NewTransaction((Fts5FullTable*)pVtab);
- return SQLITE_OK;
-}
-
-/*
-** Implementation of xCommit() method. This is a no-op. The contents of
-** the pending-terms hash-table have already been flushed into the database
-** by fts5SyncMethod().
-*/
-static int fts5CommitMethod(sqlite3_vtab *pVtab){
- UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */
+ return SQLITE_OK;
+}
+
+/*
+** Implementation of xCommit() method. This is a no-op. The contents of
+** the pending-terms hash-table have already been flushed into the database
+** by fts5SyncMethod().
+*/
+static int fts5CommitMethod(sqlite3_vtab *pVtab){
+ UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_COMMIT, 0);
- return SQLITE_OK;
-}
-
-/*
-** Implementation of xRollback(). Discard the contents of the pending-terms
-** hash-table. Any changes made to the database are reverted by SQLite.
-*/
-static int fts5RollbackMethod(sqlite3_vtab *pVtab){
- int rc;
+ return SQLITE_OK;
+}
+
+/*
+** Implementation of xRollback(). Discard the contents of the pending-terms
+** hash-table. Any changes made to the database are reverted by SQLite.
+*/
+static int fts5RollbackMethod(sqlite3_vtab *pVtab){
+ int rc;
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
- fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0);
- rc = sqlite3Fts5StorageRollback(pTab->pStorage);
- return rc;
-}
-
-static int fts5CsrPoslist(Fts5Cursor*, int, const u8**, int*);
-
-static void *fts5ApiUserData(Fts5Context *pCtx){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- return pCsr->pAux->pUserData;
-}
-
-static int fts5ApiColumnCount(Fts5Context *pCtx){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- return ((Fts5Table*)(pCsr->base.pVtab))->pConfig->nCol;
-}
-
-static int fts5ApiColumnTotalSize(
+ fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0);
+ rc = sqlite3Fts5StorageRollback(pTab->pStorage);
+ return rc;
+}
+
+static int fts5CsrPoslist(Fts5Cursor*, int, const u8**, int*);
+
+static void *fts5ApiUserData(Fts5Context *pCtx){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ return pCsr->pAux->pUserData;
+}
+
+static int fts5ApiColumnCount(Fts5Context *pCtx){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ return ((Fts5Table*)(pCsr->base.pVtab))->pConfig->nCol;
+}
+
+static int fts5ApiColumnTotalSize(
Fts5Context *pCtx,
int iCol,
- sqlite3_int64 *pnToken
-){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ sqlite3_int64 *pnToken
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
- return sqlite3Fts5StorageSize(pTab->pStorage, iCol, pnToken);
-}
-
-static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ return sqlite3Fts5StorageSize(pTab->pStorage, iCol, pnToken);
+}
+
+static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
- return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
-}
-
-static int fts5ApiTokenize(
+ return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
+}
+
+static int fts5ApiTokenize(
Fts5Context *pCtx,
const char *pText, int nText,
- void *pUserData,
- int (*xToken)(void*, int, const char*, int, int, int)
-){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
- return sqlite3Fts5Tokenize(
- pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
- );
-}
-
-static int fts5ApiPhraseCount(Fts5Context *pCtx){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- return sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
-}
-
-static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase);
-}
-
-static int fts5ApiColumnText(
+ void *pUserData,
+ int (*xToken)(void*, int, const char*, int, int, int)
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ return sqlite3Fts5Tokenize(
+ pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
+ );
+}
+
+static int fts5ApiPhraseCount(Fts5Context *pCtx){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ return sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
+}
+
+static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase);
+}
+
+static int fts5ApiColumnText(
Fts5Context *pCtx,
int iCol,
const char **pz,
- int *pn
-){
- int rc = SQLITE_OK;
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ int *pn
+){
+ int rc = SQLITE_OK;
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab))
|| pCsr->ePlan==FTS5_PLAN_SPECIAL
){
- *pz = 0;
- *pn = 0;
- }else{
- rc = fts5SeekCursor(pCsr, 0);
- if( rc==SQLITE_OK ){
- *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1);
- *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1);
- }
- }
- return rc;
-}
-
-static int fts5CsrPoslist(
+ *pz = 0;
+ *pn = 0;
+ }else{
+ rc = fts5SeekCursor(pCsr, 0);
+ if( rc==SQLITE_OK ){
+ *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1);
+ *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1);
+ }
+ }
+ return rc;
+}
+
+static int fts5CsrPoslist(
Fts5Cursor *pCsr,
int iPhrase,
- const u8 **pa,
- int *pn
-){
- Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
- int rc = SQLITE_OK;
- int bLive = (pCsr->pSorter==0);
-
- if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
-
- if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
- Fts5PoslistPopulator *aPopulator;
- int i;
- aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
- if( aPopulator==0 ) rc = SQLITE_NOMEM;
- for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){
- int n; const char *z;
- rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n);
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5ExprPopulatePoslists(
- pConfig, pCsr->pExpr, aPopulator, i, z, n
- );
- }
- }
- sqlite3_free(aPopulator);
-
- if( pCsr->pSorter ){
- sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid);
- }
- }
- CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST);
- }
-
- if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){
- Fts5Sorter *pSorter = pCsr->pSorter;
- int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
- *pn = pSorter->aIdx[iPhrase] - i1;
- *pa = &pSorter->aPoslist[i1];
- }else{
- *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa);
- }
-
- return rc;
-}
-
-/*
-** Ensure that the Fts5Cursor.nInstCount and aInst[] variables are populated
-** correctly for the current view. Return SQLITE_OK if successful, or an
-** SQLite error code otherwise.
-*/
-static int fts5CacheInstArray(Fts5Cursor *pCsr){
- int rc = SQLITE_OK;
- Fts5PoslistReader *aIter; /* One iterator for each phrase */
- int nIter; /* Number of iterators/phrases */
+ const u8 **pa,
+ int *pn
+){
+ Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
+ int rc = SQLITE_OK;
+ int bLive = (pCsr->pSorter==0);
+
+ if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
+
+ if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
+ Fts5PoslistPopulator *aPopulator;
+ int i;
+ aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
+ if( aPopulator==0 ) rc = SQLITE_NOMEM;
+ for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){
+ int n; const char *z;
+ rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5ExprPopulatePoslists(
+ pConfig, pCsr->pExpr, aPopulator, i, z, n
+ );
+ }
+ }
+ sqlite3_free(aPopulator);
+
+ if( pCsr->pSorter ){
+ sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid);
+ }
+ }
+ CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST);
+ }
+
+ if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){
+ Fts5Sorter *pSorter = pCsr->pSorter;
+ int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
+ *pn = pSorter->aIdx[iPhrase] - i1;
+ *pa = &pSorter->aPoslist[i1];
+ }else{
+ *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa);
+ }
+
+ return rc;
+}
+
+/*
+** Ensure that the Fts5Cursor.nInstCount and aInst[] variables are populated
+** correctly for the current view. Return SQLITE_OK if successful, or an
+** SQLite error code otherwise.
+*/
+static int fts5CacheInstArray(Fts5Cursor *pCsr){
+ int rc = SQLITE_OK;
+ Fts5PoslistReader *aIter; /* One iterator for each phrase */
+ int nIter; /* Number of iterators/phrases */
int nCol = ((Fts5Table*)pCsr->base.pVtab)->pConfig->nCol;
- nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
- if( pCsr->aInstIter==0 ){
+ nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
+ if( pCsr->aInstIter==0 ){
sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nIter;
- pCsr->aInstIter = (Fts5PoslistReader*)sqlite3Fts5MallocZero(&rc, nByte);
- }
- aIter = pCsr->aInstIter;
-
- if( aIter ){
- int nInst = 0; /* Number instances seen so far */
- int i;
-
- /* Initialize all iterators */
- for(i=0; i<nIter && rc==SQLITE_OK; i++){
- const u8 *a;
+ pCsr->aInstIter = (Fts5PoslistReader*)sqlite3Fts5MallocZero(&rc, nByte);
+ }
+ aIter = pCsr->aInstIter;
+
+ if( aIter ){
+ int nInst = 0; /* Number instances seen so far */
+ int i;
+
+ /* Initialize all iterators */
+ for(i=0; i<nIter && rc==SQLITE_OK; i++){
+ const u8 *a;
int n;
- rc = fts5CsrPoslist(pCsr, i, &a, &n);
- if( rc==SQLITE_OK ){
- sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
- }
- }
-
- if( rc==SQLITE_OK ){
- while( 1 ){
- int *aInst;
- int iBest = -1;
- for(i=0; i<nIter; i++){
+ rc = fts5CsrPoslist(pCsr, i, &a, &n);
+ if( rc==SQLITE_OK ){
+ sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ while( 1 ){
+ int *aInst;
+ int iBest = -1;
+ for(i=0; i<nIter; i++){
if( (aIter[i].bEof==0)
&& (iBest<0 || aIter[i].iPos<aIter[iBest].iPos)
- ){
- iBest = i;
- }
- }
- if( iBest<0 ) break;
-
- nInst++;
- if( nInst>=pCsr->nInstAlloc ){
+ ){
+ iBest = i;
+ }
+ }
+ if( iBest<0 ) break;
+
+ nInst++;
+ if( nInst>=pCsr->nInstAlloc ){
int nNewSize = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
aInst = (int*)sqlite3_realloc64(
pCsr->aInst, nNewSize*sizeof(int)*3
- );
- if( aInst ){
- pCsr->aInst = aInst;
+ );
+ if( aInst ){
+ pCsr->aInst = aInst;
pCsr->nInstAlloc = nNewSize;
- }else{
+ }else{
nInst--;
- rc = SQLITE_NOMEM;
- break;
- }
- }
-
- aInst = &pCsr->aInst[3 * (nInst-1)];
- aInst[0] = iBest;
- aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
- aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
+ rc = SQLITE_NOMEM;
+ break;
+ }
+ }
+
+ aInst = &pCsr->aInst[3 * (nInst-1)];
+ aInst[0] = iBest;
+ aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
+ aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
if( aInst[1]<0 || aInst[1]>=nCol ){
rc = FTS5_CORRUPT;
break;
}
- sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
- }
- }
-
- pCsr->nInstCount = nInst;
- CsrFlagClear(pCsr, FTS5CSR_REQUIRE_INST);
- }
- return rc;
-}
-
-static int fts5ApiInstCount(Fts5Context *pCtx, int *pnInst){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- int rc = SQLITE_OK;
+ sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
+ }
+ }
+
+ pCsr->nInstCount = nInst;
+ CsrFlagClear(pCsr, FTS5CSR_REQUIRE_INST);
+ }
+ return rc;
+}
+
+static int fts5ApiInstCount(Fts5Context *pCtx, int *pnInst){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ int rc = SQLITE_OK;
if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
- || SQLITE_OK==(rc = fts5CacheInstArray(pCsr)) ){
- *pnInst = pCsr->nInstCount;
- }
- return rc;
-}
-
-static int fts5ApiInst(
+ || SQLITE_OK==(rc = fts5CacheInstArray(pCsr)) ){
+ *pnInst = pCsr->nInstCount;
+ }
+ return rc;
+}
+
+static int fts5ApiInst(
Fts5Context *pCtx,
int iIdx,
int *piPhrase,
int *piCol,
- int *piOff
-){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- int rc = SQLITE_OK;
+ int *piOff
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ int rc = SQLITE_OK;
if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
|| SQLITE_OK==(rc = fts5CacheInstArray(pCsr))
- ){
- if( iIdx<0 || iIdx>=pCsr->nInstCount ){
- rc = SQLITE_RANGE;
-#if 0
- }else if( fts5IsOffsetless((Fts5Table*)pCsr->base.pVtab) ){
- *piPhrase = pCsr->aInst[iIdx*3];
- *piCol = pCsr->aInst[iIdx*3 + 2];
- *piOff = -1;
-#endif
- }else{
- *piPhrase = pCsr->aInst[iIdx*3];
- *piCol = pCsr->aInst[iIdx*3 + 1];
- *piOff = pCsr->aInst[iIdx*3 + 2];
- }
- }
- return rc;
-}
-
-static sqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){
- return fts5CursorRowid((Fts5Cursor*)pCtx);
-}
-
-static int fts5ColumnSizeCb(
- void *pContext, /* Pointer to int */
- int tflags,
- const char *pUnused, /* Buffer containing token */
- int nUnused, /* Size of token in bytes */
- int iUnused1, /* Start offset of token */
- int iUnused2 /* End offset of token */
-){
- int *pCnt = (int*)pContext;
- UNUSED_PARAM2(pUnused, nUnused);
- UNUSED_PARAM2(iUnused1, iUnused2);
- if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
- (*pCnt)++;
- }
- return SQLITE_OK;
-}
-
-static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ ){
+ if( iIdx<0 || iIdx>=pCsr->nInstCount ){
+ rc = SQLITE_RANGE;
+#if 0
+ }else if( fts5IsOffsetless((Fts5Table*)pCsr->base.pVtab) ){
+ *piPhrase = pCsr->aInst[iIdx*3];
+ *piCol = pCsr->aInst[iIdx*3 + 2];
+ *piOff = -1;
+#endif
+ }else{
+ *piPhrase = pCsr->aInst[iIdx*3];
+ *piCol = pCsr->aInst[iIdx*3 + 1];
+ *piOff = pCsr->aInst[iIdx*3 + 2];
+ }
+ }
+ return rc;
+}
+
+static sqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){
+ return fts5CursorRowid((Fts5Cursor*)pCtx);
+}
+
+static int fts5ColumnSizeCb(
+ void *pContext, /* Pointer to int */
+ int tflags,
+ const char *pUnused, /* Buffer containing token */
+ int nUnused, /* Size of token in bytes */
+ int iUnused1, /* Start offset of token */
+ int iUnused2 /* End offset of token */
+){
+ int *pCnt = (int*)pContext;
+ UNUSED_PARAM2(pUnused, nUnused);
+ UNUSED_PARAM2(iUnused1, iUnused2);
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
+ (*pCnt)++;
+ }
+ return SQLITE_OK;
+}
+
+static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
Fts5Config *pConfig = pTab->p.pConfig;
- int rc = SQLITE_OK;
-
- if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_DOCSIZE) ){
- if( pConfig->bColumnsize ){
- i64 iRowid = fts5CursorRowid(pCsr);
- rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize);
- }else if( pConfig->zContent==0 ){
- int i;
- for(i=0; i<pConfig->nCol; i++){
- if( pConfig->abUnindexed[i]==0 ){
- pCsr->aColumnSize[i] = -1;
- }
- }
- }else{
- int i;
- for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
- if( pConfig->abUnindexed[i]==0 ){
- const char *z; int n;
- void *p = (void*)(&pCsr->aColumnSize[i]);
- pCsr->aColumnSize[i] = 0;
- rc = fts5ApiColumnText(pCtx, i, &z, &n);
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5Tokenize(
- pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb
- );
- }
- }
- }
- }
- CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
- }
- if( iCol<0 ){
- int i;
- *pnToken = 0;
- for(i=0; i<pConfig->nCol; i++){
- *pnToken += pCsr->aColumnSize[i];
- }
- }else if( iCol<pConfig->nCol ){
- *pnToken = pCsr->aColumnSize[iCol];
- }else{
- *pnToken = 0;
- rc = SQLITE_RANGE;
- }
- return rc;
-}
-
-/*
-** Implementation of the xSetAuxdata() method.
-*/
-static int fts5ApiSetAuxdata(
- Fts5Context *pCtx, /* Fts5 context */
- void *pPtr, /* Pointer to save as auxdata */
- void(*xDelete)(void*) /* Destructor for pPtr (or NULL) */
-){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- Fts5Auxdata *pData;
-
- /* Search through the cursors list of Fts5Auxdata objects for one that
- ** corresponds to the currently executing auxiliary function. */
- for(pData=pCsr->pAuxdata; pData; pData=pData->pNext){
- if( pData->pAux==pCsr->pAux ) break;
- }
-
- if( pData ){
- if( pData->xDelete ){
- pData->xDelete(pData->pPtr);
- }
- }else{
- int rc = SQLITE_OK;
- pData = (Fts5Auxdata*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Auxdata));
- if( pData==0 ){
- if( xDelete ) xDelete(pPtr);
- return rc;
- }
- pData->pAux = pCsr->pAux;
- pData->pNext = pCsr->pAuxdata;
- pCsr->pAuxdata = pData;
- }
-
- pData->xDelete = xDelete;
- pData->pPtr = pPtr;
- return SQLITE_OK;
-}
-
-static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- Fts5Auxdata *pData;
- void *pRet = 0;
-
- for(pData=pCsr->pAuxdata; pData; pData=pData->pNext){
- if( pData->pAux==pCsr->pAux ) break;
- }
-
- if( pData ){
- pRet = pData->pPtr;
- if( bClear ){
- pData->pPtr = 0;
- pData->xDelete = 0;
- }
- }
-
- return pRet;
-}
-
-static void fts5ApiPhraseNext(
+ int rc = SQLITE_OK;
+
+ if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_DOCSIZE) ){
+ if( pConfig->bColumnsize ){
+ i64 iRowid = fts5CursorRowid(pCsr);
+ rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize);
+ }else if( pConfig->zContent==0 ){
+ int i;
+ for(i=0; i<pConfig->nCol; i++){
+ if( pConfig->abUnindexed[i]==0 ){
+ pCsr->aColumnSize[i] = -1;
+ }
+ }
+ }else{
+ int i;
+ for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
+ if( pConfig->abUnindexed[i]==0 ){
+ const char *z; int n;
+ void *p = (void*)(&pCsr->aColumnSize[i]);
+ pCsr->aColumnSize[i] = 0;
+ rc = fts5ApiColumnText(pCtx, i, &z, &n);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5Tokenize(
+ pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb
+ );
+ }
+ }
+ }
+ }
+ CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
+ }
+ if( iCol<0 ){
+ int i;
+ *pnToken = 0;
+ for(i=0; i<pConfig->nCol; i++){
+ *pnToken += pCsr->aColumnSize[i];
+ }
+ }else if( iCol<pConfig->nCol ){
+ *pnToken = pCsr->aColumnSize[iCol];
+ }else{
+ *pnToken = 0;
+ rc = SQLITE_RANGE;
+ }
+ return rc;
+}
+
+/*
+** Implementation of the xSetAuxdata() method.
+*/
+static int fts5ApiSetAuxdata(
+ Fts5Context *pCtx, /* Fts5 context */
+ void *pPtr, /* Pointer to save as auxdata */
+ void(*xDelete)(void*) /* Destructor for pPtr (or NULL) */
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Auxdata *pData;
+
+ /* Search through the cursors list of Fts5Auxdata objects for one that
+ ** corresponds to the currently executing auxiliary function. */
+ for(pData=pCsr->pAuxdata; pData; pData=pData->pNext){
+ if( pData->pAux==pCsr->pAux ) break;
+ }
+
+ if( pData ){
+ if( pData->xDelete ){
+ pData->xDelete(pData->pPtr);
+ }
+ }else{
+ int rc = SQLITE_OK;
+ pData = (Fts5Auxdata*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Auxdata));
+ if( pData==0 ){
+ if( xDelete ) xDelete(pPtr);
+ return rc;
+ }
+ pData->pAux = pCsr->pAux;
+ pData->pNext = pCsr->pAuxdata;
+ pCsr->pAuxdata = pData;
+ }
+
+ pData->xDelete = xDelete;
+ pData->pPtr = pPtr;
+ return SQLITE_OK;
+}
+
+static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Auxdata *pData;
+ void *pRet = 0;
+
+ for(pData=pCsr->pAuxdata; pData; pData=pData->pNext){
+ if( pData->pAux==pCsr->pAux ) break;
+ }
+
+ if( pData ){
+ pRet = pData->pPtr;
+ if( bClear ){
+ pData->pPtr = 0;
+ pData->xDelete = 0;
+ }
+ }
+
+ return pRet;
+}
+
+static void fts5ApiPhraseNext(
Fts5Context *pUnused,
Fts5PhraseIter *pIter,
- int *piCol, int *piOff
-){
- UNUSED_PARAM(pUnused);
- if( pIter->a>=pIter->b ){
- *piCol = -1;
- *piOff = -1;
- }else{
- int iVal;
- pIter->a += fts5GetVarint32(pIter->a, iVal);
- if( iVal==1 ){
- pIter->a += fts5GetVarint32(pIter->a, iVal);
- *piCol = iVal;
- *piOff = 0;
- pIter->a += fts5GetVarint32(pIter->a, iVal);
- }
- *piOff += (iVal-2);
- }
-}
-
-static int fts5ApiPhraseFirst(
+ int *piCol, int *piOff
+){
+ UNUSED_PARAM(pUnused);
+ if( pIter->a>=pIter->b ){
+ *piCol = -1;
+ *piOff = -1;
+ }else{
+ int iVal;
+ pIter->a += fts5GetVarint32(pIter->a, iVal);
+ if( iVal==1 ){
+ pIter->a += fts5GetVarint32(pIter->a, iVal);
+ *piCol = iVal;
+ *piOff = 0;
+ pIter->a += fts5GetVarint32(pIter->a, iVal);
+ }
+ *piOff += (iVal-2);
+ }
+}
+
+static int fts5ApiPhraseFirst(
Fts5Context *pCtx,
int iPhrase,
Fts5PhraseIter *pIter,
- int *piCol, int *piOff
-){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- int n;
- int rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
- if( rc==SQLITE_OK ){
+ int *piCol, int *piOff
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ int n;
+ int rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
+ if( rc==SQLITE_OK ){
assert( pIter->a || n==0 );
pIter->b = (pIter->a ? &pIter->a[n] : 0);
- *piCol = 0;
- *piOff = 0;
- fts5ApiPhraseNext(pCtx, pIter, piCol, piOff);
- }
- return rc;
-}
-
-static void fts5ApiPhraseNextColumn(
+ *piCol = 0;
+ *piOff = 0;
+ fts5ApiPhraseNext(pCtx, pIter, piCol, piOff);
+ }
+ return rc;
+}
+
+static void fts5ApiPhraseNextColumn(
Fts5Context *pCtx,
Fts5PhraseIter *pIter,
- int *piCol
-){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
-
- if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
- if( pIter->a>=pIter->b ){
- *piCol = -1;
- }else{
- int iIncr;
- pIter->a += fts5GetVarint32(&pIter->a[0], iIncr);
- *piCol += (iIncr-2);
- }
- }else{
- while( 1 ){
- int dummy;
- if( pIter->a>=pIter->b ){
- *piCol = -1;
- return;
- }
- if( pIter->a[0]==0x01 ) break;
- pIter->a += fts5GetVarint32(pIter->a, dummy);
- }
- pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
- }
-}
-
-static int fts5ApiPhraseFirstColumn(
+ int *piCol
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
+
+ if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
+ if( pIter->a>=pIter->b ){
+ *piCol = -1;
+ }else{
+ int iIncr;
+ pIter->a += fts5GetVarint32(&pIter->a[0], iIncr);
+ *piCol += (iIncr-2);
+ }
+ }else{
+ while( 1 ){
+ int dummy;
+ if( pIter->a>=pIter->b ){
+ *piCol = -1;
+ return;
+ }
+ if( pIter->a[0]==0x01 ) break;
+ pIter->a += fts5GetVarint32(pIter->a, dummy);
+ }
+ pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
+ }
+}
+
+static int fts5ApiPhraseFirstColumn(
Fts5Context *pCtx,
int iPhrase,
Fts5PhraseIter *pIter,
- int *piCol
-){
- int rc = SQLITE_OK;
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
-
- if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
- Fts5Sorter *pSorter = pCsr->pSorter;
- int n;
- if( pSorter ){
- int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
- n = pSorter->aIdx[iPhrase] - i1;
- pIter->a = &pSorter->aPoslist[i1];
- }else{
- rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
- }
- if( rc==SQLITE_OK ){
+ int *piCol
+){
+ int rc = SQLITE_OK;
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
+
+ if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
+ Fts5Sorter *pSorter = pCsr->pSorter;
+ int n;
+ if( pSorter ){
+ int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
+ n = pSorter->aIdx[iPhrase] - i1;
+ pIter->a = &pSorter->aPoslist[i1];
+ }else{
+ rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
+ }
+ if( rc==SQLITE_OK ){
assert( pIter->a || n==0 );
pIter->b = (pIter->a ? &pIter->a[n] : 0);
- *piCol = 0;
- fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
- }
- }else{
- int n;
- rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
- if( rc==SQLITE_OK ){
+ *piCol = 0;
+ fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
+ }
+ }else{
+ int n;
+ rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
+ if( rc==SQLITE_OK ){
assert( pIter->a || n==0 );
pIter->b = (pIter->a ? &pIter->a[n] : 0);
- if( n<=0 ){
- *piCol = -1;
- }else if( pIter->a[0]==0x01 ){
- pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
- }else{
- *piCol = 0;
- }
- }
- }
-
- return rc;
-}
-
-
+ if( n<=0 ){
+ *piCol = -1;
+ }else if( pIter->a[0]==0x01 ){
+ pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
+ }else{
+ *piCol = 0;
+ }
+ }
+ }
+
+ return rc;
+}
+
+
static int fts5ApiQueryPhrase(Fts5Context*, int, void*,
- int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
-);
-
-static const Fts5ExtensionApi sFts5Api = {
- 2, /* iVersion */
- fts5ApiUserData,
- fts5ApiColumnCount,
- fts5ApiRowCount,
- fts5ApiColumnTotalSize,
- fts5ApiTokenize,
- fts5ApiPhraseCount,
- fts5ApiPhraseSize,
- fts5ApiInstCount,
- fts5ApiInst,
- fts5ApiRowid,
- fts5ApiColumnText,
- fts5ApiColumnSize,
- fts5ApiQueryPhrase,
- fts5ApiSetAuxdata,
- fts5ApiGetAuxdata,
- fts5ApiPhraseFirst,
- fts5ApiPhraseNext,
- fts5ApiPhraseFirstColumn,
- fts5ApiPhraseNextColumn,
-};
-
-/*
-** Implementation of API function xQueryPhrase().
-*/
-static int fts5ApiQueryPhrase(
+ int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
+);
+
+static const Fts5ExtensionApi sFts5Api = {
+ 2, /* iVersion */
+ fts5ApiUserData,
+ fts5ApiColumnCount,
+ fts5ApiRowCount,
+ fts5ApiColumnTotalSize,
+ fts5ApiTokenize,
+ fts5ApiPhraseCount,
+ fts5ApiPhraseSize,
+ fts5ApiInstCount,
+ fts5ApiInst,
+ fts5ApiRowid,
+ fts5ApiColumnText,
+ fts5ApiColumnSize,
+ fts5ApiQueryPhrase,
+ fts5ApiSetAuxdata,
+ fts5ApiGetAuxdata,
+ fts5ApiPhraseFirst,
+ fts5ApiPhraseNext,
+ fts5ApiPhraseFirstColumn,
+ fts5ApiPhraseNextColumn,
+};
+
+/*
+** Implementation of API function xQueryPhrase().
+*/
+static int fts5ApiQueryPhrase(
Fts5Context *pCtx,
int iPhrase,
- void *pUserData,
- int(*xCallback)(const Fts5ExtensionApi*, Fts5Context*, void*)
-){
- Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ void *pUserData,
+ int(*xCallback)(const Fts5ExtensionApi*, Fts5Context*, void*)
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
- int rc;
- Fts5Cursor *pNew = 0;
-
- rc = fts5OpenMethod(pCsr->base.pVtab, (sqlite3_vtab_cursor**)&pNew);
- if( rc==SQLITE_OK ){
- pNew->ePlan = FTS5_PLAN_MATCH;
- pNew->iFirstRowid = SMALLEST_INT64;
- pNew->iLastRowid = LARGEST_INT64;
- pNew->base.pVtab = (sqlite3_vtab*)pTab;
- rc = sqlite3Fts5ExprClonePhrase(pCsr->pExpr, iPhrase, &pNew->pExpr);
- }
-
- if( rc==SQLITE_OK ){
- for(rc = fts5CursorFirst(pTab, pNew, 0);
- rc==SQLITE_OK && CsrFlagTest(pNew, FTS5CSR_EOF)==0;
- rc = fts5NextMethod((sqlite3_vtab_cursor*)pNew)
- ){
- rc = xCallback(&sFts5Api, (Fts5Context*)pNew, pUserData);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_DONE ) rc = SQLITE_OK;
- break;
- }
- }
- }
-
- fts5CloseMethod((sqlite3_vtab_cursor*)pNew);
- return rc;
-}
-
-static void fts5ApiInvoke(
- Fts5Auxiliary *pAux,
- Fts5Cursor *pCsr,
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- assert( pCsr->pAux==0 );
- pCsr->pAux = pAux;
- pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv);
- pCsr->pAux = 0;
-}
-
-static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){
- Fts5Cursor *pCsr;
- for(pCsr=pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
- if( pCsr->iCsrId==iCsrId ) break;
- }
- return pCsr;
-}
-
-static void fts5ApiCallback(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
-
- Fts5Auxiliary *pAux;
- Fts5Cursor *pCsr;
- i64 iCsrId;
-
- assert( argc>=1 );
- pAux = (Fts5Auxiliary*)sqlite3_user_data(context);
- iCsrId = sqlite3_value_int64(argv[0]);
-
- pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
+ int rc;
+ Fts5Cursor *pNew = 0;
+
+ rc = fts5OpenMethod(pCsr->base.pVtab, (sqlite3_vtab_cursor**)&pNew);
+ if( rc==SQLITE_OK ){
+ pNew->ePlan = FTS5_PLAN_MATCH;
+ pNew->iFirstRowid = SMALLEST_INT64;
+ pNew->iLastRowid = LARGEST_INT64;
+ pNew->base.pVtab = (sqlite3_vtab*)pTab;
+ rc = sqlite3Fts5ExprClonePhrase(pCsr->pExpr, iPhrase, &pNew->pExpr);
+ }
+
+ if( rc==SQLITE_OK ){
+ for(rc = fts5CursorFirst(pTab, pNew, 0);
+ rc==SQLITE_OK && CsrFlagTest(pNew, FTS5CSR_EOF)==0;
+ rc = fts5NextMethod((sqlite3_vtab_cursor*)pNew)
+ ){
+ rc = xCallback(&sFts5Api, (Fts5Context*)pNew, pUserData);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ break;
+ }
+ }
+ }
+
+ fts5CloseMethod((sqlite3_vtab_cursor*)pNew);
+ return rc;
+}
+
+static void fts5ApiInvoke(
+ Fts5Auxiliary *pAux,
+ Fts5Cursor *pCsr,
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ assert( pCsr->pAux==0 );
+ pCsr->pAux = pAux;
+ pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv);
+ pCsr->pAux = 0;
+}
+
+static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){
+ Fts5Cursor *pCsr;
+ for(pCsr=pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
+ if( pCsr->iCsrId==iCsrId ) break;
+ }
+ return pCsr;
+}
+
+static void fts5ApiCallback(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+
+ Fts5Auxiliary *pAux;
+ Fts5Cursor *pCsr;
+ i64 iCsrId;
+
+ assert( argc>=1 );
+ pAux = (Fts5Auxiliary*)sqlite3_user_data(context);
+ iCsrId = sqlite3_value_int64(argv[0]);
+
+ pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
if( pCsr==0 || pCsr->ePlan==0 ){
- char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
- }else{
- fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
- }
-}
-
-
-/*
+ char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId);
+ sqlite3_result_error(context, zErr, -1);
+ sqlite3_free(zErr);
+ }else{
+ fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
+ }
+}
+
+
+/*
** Given cursor id iId, return a pointer to the corresponding Fts5Table
-** object. Or NULL If the cursor id does not exist.
-*/
+** object. Or NULL If the cursor id does not exist.
+*/
static Fts5Table *sqlite3Fts5TableFromCsrid(
- Fts5Global *pGlobal, /* FTS5 global context for db handle */
+ Fts5Global *pGlobal, /* FTS5 global context for db handle */
i64 iCsrId /* Id of cursor to find */
-){
- Fts5Cursor *pCsr;
- pCsr = fts5CursorFromCsrid(pGlobal, iCsrId);
+){
+ Fts5Cursor *pCsr;
+ pCsr = fts5CursorFromCsrid(pGlobal, iCsrId);
if( pCsr ){
return (Fts5Table*)pCsr->base.pVtab;
}
return 0;
-}
-
-/*
-** Return a "position-list blob" corresponding to the current position of
-** cursor pCsr via sqlite3_result_blob(). A position-list blob contains
-** the current position-list for each phrase in the query associated with
-** cursor pCsr.
-**
-** A position-list blob begins with (nPhrase-1) varints, where nPhrase is
-** the number of phrases in the query. Following the varints are the
-** concatenated position lists for each phrase, in order.
-**
-** The first varint (if it exists) contains the size of the position list
-** for phrase 0. The second (same disclaimer) contains the size of position
-** list 1. And so on. There is no size field for the final position list,
-** as it can be derived from the total size of the blob.
-*/
-static int fts5PoslistBlob(sqlite3_context *pCtx, Fts5Cursor *pCsr){
- int i;
- int rc = SQLITE_OK;
- int nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
- Fts5Buffer val;
-
- memset(&val, 0, sizeof(Fts5Buffer));
- switch( ((Fts5Table*)(pCsr->base.pVtab))->pConfig->eDetail ){
- case FTS5_DETAIL_FULL:
-
- /* Append the varints */
- for(i=0; i<(nPhrase-1); i++){
- const u8 *dummy;
- int nByte = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy);
- sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
- }
-
- /* Append the position lists */
- for(i=0; i<nPhrase; i++){
- const u8 *pPoslist;
- int nPoslist;
- nPoslist = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &pPoslist);
- sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
- }
- break;
-
- case FTS5_DETAIL_COLUMNS:
-
- /* Append the varints */
- for(i=0; rc==SQLITE_OK && i<(nPhrase-1); i++){
- const u8 *dummy;
- int nByte;
- rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &dummy, &nByte);
- sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
- }
-
- /* Append the position lists */
- for(i=0; rc==SQLITE_OK && i<nPhrase; i++){
- const u8 *pPoslist;
- int nPoslist;
- rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &pPoslist, &nPoslist);
- sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
- }
- break;
-
- default:
- break;
- }
-
- sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
- return rc;
-}
-
-/*
-** This is the xColumn method, called by SQLite to request a value from
-** the row that the supplied cursor currently points to.
-*/
-static int fts5ColumnMethod(
- sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
- sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */
- int iCol /* Index of column to read value from */
-){
+}
+
+/*
+** Return a "position-list blob" corresponding to the current position of
+** cursor pCsr via sqlite3_result_blob(). A position-list blob contains
+** the current position-list for each phrase in the query associated with
+** cursor pCsr.
+**
+** A position-list blob begins with (nPhrase-1) varints, where nPhrase is
+** the number of phrases in the query. Following the varints are the
+** concatenated position lists for each phrase, in order.
+**
+** The first varint (if it exists) contains the size of the position list
+** for phrase 0. The second (same disclaimer) contains the size of position
+** list 1. And so on. There is no size field for the final position list,
+** as it can be derived from the total size of the blob.
+*/
+static int fts5PoslistBlob(sqlite3_context *pCtx, Fts5Cursor *pCsr){
+ int i;
+ int rc = SQLITE_OK;
+ int nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
+ Fts5Buffer val;
+
+ memset(&val, 0, sizeof(Fts5Buffer));
+ switch( ((Fts5Table*)(pCsr->base.pVtab))->pConfig->eDetail ){
+ case FTS5_DETAIL_FULL:
+
+ /* Append the varints */
+ for(i=0; i<(nPhrase-1); i++){
+ const u8 *dummy;
+ int nByte = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy);
+ sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
+ }
+
+ /* Append the position lists */
+ for(i=0; i<nPhrase; i++){
+ const u8 *pPoslist;
+ int nPoslist;
+ nPoslist = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &pPoslist);
+ sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
+ }
+ break;
+
+ case FTS5_DETAIL_COLUMNS:
+
+ /* Append the varints */
+ for(i=0; rc==SQLITE_OK && i<(nPhrase-1); i++){
+ const u8 *dummy;
+ int nByte;
+ rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &dummy, &nByte);
+ sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
+ }
+
+ /* Append the position lists */
+ for(i=0; rc==SQLITE_OK && i<nPhrase; i++){
+ const u8 *pPoslist;
+ int nPoslist;
+ rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &pPoslist, &nPoslist);
+ sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
+ return rc;
+}
+
+/*
+** This is the xColumn method, called by SQLite to request a value from
+** the row that the supplied cursor currently points to.
+*/
+static int fts5ColumnMethod(
+ sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
+ sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */
+ int iCol /* Index of column to read value from */
+){
Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
Fts5Config *pConfig = pTab->p.pConfig;
- Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
- int rc = SQLITE_OK;
-
- assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 );
-
- if( pCsr->ePlan==FTS5_PLAN_SPECIAL ){
- if( iCol==pConfig->nCol ){
- sqlite3_result_int64(pCtx, pCsr->iSpecial);
- }
- }else
-
- if( iCol==pConfig->nCol ){
- /* User is requesting the value of the special column with the same name
- ** as the table. Return the cursor integer id number. This value is only
- ** useful in that it may be passed as the first argument to an FTS5
- ** auxiliary function. */
- sqlite3_result_int64(pCtx, pCsr->iCsrId);
- }else if( iCol==pConfig->nCol+1 ){
-
- /* The value of the "rank" column. */
- if( pCsr->ePlan==FTS5_PLAN_SOURCE ){
- fts5PoslistBlob(pCtx, pCsr);
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ int rc = SQLITE_OK;
+
+ assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 );
+
+ if( pCsr->ePlan==FTS5_PLAN_SPECIAL ){
+ if( iCol==pConfig->nCol ){
+ sqlite3_result_int64(pCtx, pCsr->iSpecial);
+ }
+ }else
+
+ if( iCol==pConfig->nCol ){
+ /* User is requesting the value of the special column with the same name
+ ** as the table. Return the cursor integer id number. This value is only
+ ** useful in that it may be passed as the first argument to an FTS5
+ ** auxiliary function. */
+ sqlite3_result_int64(pCtx, pCsr->iCsrId);
+ }else if( iCol==pConfig->nCol+1 ){
+
+ /* The value of the "rank" column. */
+ if( pCsr->ePlan==FTS5_PLAN_SOURCE ){
+ fts5PoslistBlob(pCtx, pCsr);
}else if(
- pCsr->ePlan==FTS5_PLAN_MATCH
- || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
- ){
- if( pCsr->pRank || SQLITE_OK==(rc = fts5FindRankFunction(pCsr)) ){
- fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg);
- }
- }
- }else if( !fts5IsContentless(pTab) ){
+ pCsr->ePlan==FTS5_PLAN_MATCH
+ || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
+ ){
+ if( pCsr->pRank || SQLITE_OK==(rc = fts5FindRankFunction(pCsr)) ){
+ fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg);
+ }
+ }
+ }else if( !fts5IsContentless(pTab) ){
pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
- rc = fts5SeekCursor(pCsr, 1);
- if( rc==SQLITE_OK ){
- sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
- }
+ rc = fts5SeekCursor(pCsr, 1);
+ if( rc==SQLITE_OK ){
+ sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
+ }
pConfig->pzErrmsg = 0;
- }
- return rc;
-}
-
-
-/*
-** This routine implements the xFindFunction method for the FTS3
-** virtual table.
-*/
-static int fts5FindFunctionMethod(
- sqlite3_vtab *pVtab, /* Virtual table handle */
- int nUnused, /* Number of SQL function arguments */
- const char *zName, /* Name of SQL function */
- void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
- void **ppArg /* OUT: User data for *pxFunc */
-){
+ }
+ return rc;
+}
+
+
+/*
+** This routine implements the xFindFunction method for the FTS3
+** virtual table.
+*/
+static int fts5FindFunctionMethod(
+ sqlite3_vtab *pVtab, /* Virtual table handle */
+ int nUnused, /* Number of SQL function arguments */
+ const char *zName, /* Name of SQL function */
+ void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
+ void **ppArg /* OUT: User data for *pxFunc */
+){
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
- Fts5Auxiliary *pAux;
-
- UNUSED_PARAM(nUnused);
- pAux = fts5FindAuxiliary(pTab, zName);
- if( pAux ){
- *pxFunc = fts5ApiCallback;
- *ppArg = (void*)pAux;
- return 1;
- }
-
- /* No function of the specified name was found. Return 0. */
- return 0;
-}
-
-/*
-** Implementation of FTS5 xRename method. Rename an fts5 table.
-*/
-static int fts5RenameMethod(
- sqlite3_vtab *pVtab, /* Virtual table handle */
- const char *zName /* New name of table */
-){
+ Fts5Auxiliary *pAux;
+
+ UNUSED_PARAM(nUnused);
+ pAux = fts5FindAuxiliary(pTab, zName);
+ if( pAux ){
+ *pxFunc = fts5ApiCallback;
+ *ppArg = (void*)pAux;
+ return 1;
+ }
+
+ /* No function of the specified name was found. Return 0. */
+ return 0;
+}
+
+/*
+** Implementation of FTS5 xRename method. Rename an fts5 table.
+*/
+static int fts5RenameMethod(
+ sqlite3_vtab *pVtab, /* Virtual table handle */
+ const char *zName /* New name of table */
+){
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
- return sqlite3Fts5StorageRename(pTab->pStorage, zName);
-}
-
+ return sqlite3Fts5StorageRename(pTab->pStorage, zName);
+}
+
static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){
fts5TripCursors((Fts5FullTable*)pTab);
return sqlite3Fts5StorageSync(((Fts5FullTable*)pTab)->pStorage);
}
-/*
-** The xSavepoint() method.
-**
-** Flush the contents of the pending-terms table to disk.
-*/
-static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
- UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
+/*
+** The xSavepoint() method.
+**
+** Flush the contents of the pending-terms table to disk.
+*/
+static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
+ UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_SAVEPOINT, iSavepoint);
return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
-}
-
-/*
-** The xRelease() method.
-**
-** This is a no-op.
-*/
-static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
- UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
+}
+
+/*
+** The xRelease() method.
+**
+** This is a no-op.
+*/
+static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
+ UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_RELEASE, iSavepoint);
return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
-}
-
-/*
-** The xRollbackTo() method.
-**
-** Discard the contents of the pending terms table.
-*/
-static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
+}
+
+/*
+** The xRollbackTo() method.
+**
+** Discard the contents of the pending terms table.
+*/
+static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
- UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
- fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
- fts5TripCursors(pTab);
- return sqlite3Fts5StorageRollback(pTab->pStorage);
-}
-
-/*
-** Register a new auxiliary function with global context pGlobal.
-*/
-static int fts5CreateAux(
- fts5_api *pApi, /* Global context (one per db handle) */
- const char *zName, /* Name of new function */
- void *pUserData, /* User data for aux. function */
- fts5_extension_function xFunc, /* Aux. function implementation */
- void(*xDestroy)(void*) /* Destructor for pUserData */
-){
- Fts5Global *pGlobal = (Fts5Global*)pApi;
- int rc = sqlite3_overload_function(pGlobal->db, zName, -1);
- if( rc==SQLITE_OK ){
- Fts5Auxiliary *pAux;
+ UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
+ fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
+ fts5TripCursors(pTab);
+ return sqlite3Fts5StorageRollback(pTab->pStorage);
+}
+
+/*
+** Register a new auxiliary function with global context pGlobal.
+*/
+static int fts5CreateAux(
+ fts5_api *pApi, /* Global context (one per db handle) */
+ const char *zName, /* Name of new function */
+ void *pUserData, /* User data for aux. function */
+ fts5_extension_function xFunc, /* Aux. function implementation */
+ void(*xDestroy)(void*) /* Destructor for pUserData */
+){
+ Fts5Global *pGlobal = (Fts5Global*)pApi;
+ int rc = sqlite3_overload_function(pGlobal->db, zName, -1);
+ if( rc==SQLITE_OK ){
+ Fts5Auxiliary *pAux;
sqlite3_int64 nName; /* Size of zName in bytes, including \0 */
sqlite3_int64 nByte; /* Bytes of space to allocate */
-
+
nName = strlen(zName) + 1;
- nByte = sizeof(Fts5Auxiliary) + nName;
+ nByte = sizeof(Fts5Auxiliary) + nName;
pAux = (Fts5Auxiliary*)sqlite3_malloc64(nByte);
- if( pAux ){
+ if( pAux ){
memset(pAux, 0, (size_t)nByte);
- pAux->zFunc = (char*)&pAux[1];
- memcpy(pAux->zFunc, zName, nName);
- pAux->pGlobal = pGlobal;
- pAux->pUserData = pUserData;
- pAux->xFunc = xFunc;
- pAux->xDestroy = xDestroy;
- pAux->pNext = pGlobal->pAux;
- pGlobal->pAux = pAux;
- }else{
- rc = SQLITE_NOMEM;
- }
- }
-
- return rc;
-}
-
-/*
+ pAux->zFunc = (char*)&pAux[1];
+ memcpy(pAux->zFunc, zName, nName);
+ pAux->pGlobal = pGlobal;
+ pAux->pUserData = pUserData;
+ pAux->xFunc = xFunc;
+ pAux->xDestroy = xDestroy;
+ pAux->pNext = pGlobal->pAux;
+ pGlobal->pAux = pAux;
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ }
+
+ return rc;
+}
+
+/*
** Register a new tokenizer. This is the implementation of the
-** fts5_api.xCreateTokenizer() method.
-*/
-static int fts5CreateTokenizer(
- fts5_api *pApi, /* Global context (one per db handle) */
- const char *zName, /* Name of new function */
- void *pUserData, /* User data for aux. function */
- fts5_tokenizer *pTokenizer, /* Tokenizer implementation */
- void(*xDestroy)(void*) /* Destructor for pUserData */
-){
- Fts5Global *pGlobal = (Fts5Global*)pApi;
- Fts5TokenizerModule *pNew;
+** fts5_api.xCreateTokenizer() method.
+*/
+static int fts5CreateTokenizer(
+ fts5_api *pApi, /* Global context (one per db handle) */
+ const char *zName, /* Name of new function */
+ void *pUserData, /* User data for aux. function */
+ fts5_tokenizer *pTokenizer, /* Tokenizer implementation */
+ void(*xDestroy)(void*) /* Destructor for pUserData */
+){
+ Fts5Global *pGlobal = (Fts5Global*)pApi;
+ Fts5TokenizerModule *pNew;
sqlite3_int64 nName; /* Size of zName and its \0 terminator */
sqlite3_int64 nByte; /* Bytes of space to allocate */
- int rc = SQLITE_OK;
-
+ int rc = SQLITE_OK;
+
nName = strlen(zName) + 1;
- nByte = sizeof(Fts5TokenizerModule) + nName;
+ nByte = sizeof(Fts5TokenizerModule) + nName;
pNew = (Fts5TokenizerModule*)sqlite3_malloc64(nByte);
- if( pNew ){
+ if( pNew ){
memset(pNew, 0, (size_t)nByte);
- pNew->zName = (char*)&pNew[1];
- memcpy(pNew->zName, zName, nName);
- pNew->pUserData = pUserData;
- pNew->x = *pTokenizer;
- pNew->xDestroy = xDestroy;
- pNew->pNext = pGlobal->pTok;
- pGlobal->pTok = pNew;
- if( pNew->pNext==0 ){
- pGlobal->pDfltTok = pNew;
- }
- }else{
- rc = SQLITE_NOMEM;
- }
-
- return rc;
-}
-
-static Fts5TokenizerModule *fts5LocateTokenizer(
+ pNew->zName = (char*)&pNew[1];
+ memcpy(pNew->zName, zName, nName);
+ pNew->pUserData = pUserData;
+ pNew->x = *pTokenizer;
+ pNew->xDestroy = xDestroy;
+ pNew->pNext = pGlobal->pTok;
+ pGlobal->pTok = pNew;
+ if( pNew->pNext==0 ){
+ pGlobal->pDfltTok = pNew;
+ }
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+
+ return rc;
+}
+
+static Fts5TokenizerModule *fts5LocateTokenizer(
Fts5Global *pGlobal,
- const char *zName
-){
- Fts5TokenizerModule *pMod = 0;
-
- if( zName==0 ){
- pMod = pGlobal->pDfltTok;
- }else{
- for(pMod=pGlobal->pTok; pMod; pMod=pMod->pNext){
- if( sqlite3_stricmp(zName, pMod->zName)==0 ) break;
- }
- }
-
- return pMod;
-}
-
-/*
+ const char *zName
+){
+ Fts5TokenizerModule *pMod = 0;
+
+ if( zName==0 ){
+ pMod = pGlobal->pDfltTok;
+ }else{
+ for(pMod=pGlobal->pTok; pMod; pMod=pMod->pNext){
+ if( sqlite3_stricmp(zName, pMod->zName)==0 ) break;
+ }
+ }
+
+ return pMod;
+}
+
+/*
** Find a tokenizer. This is the implementation of the
-** fts5_api.xFindTokenizer() method.
-*/
-static int fts5FindTokenizer(
- fts5_api *pApi, /* Global context (one per db handle) */
- const char *zName, /* Name of new function */
- void **ppUserData,
- fts5_tokenizer *pTokenizer /* Populate this object */
-){
- int rc = SQLITE_OK;
- Fts5TokenizerModule *pMod;
-
- pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
- if( pMod ){
- *pTokenizer = pMod->x;
- *ppUserData = pMod->pUserData;
- }else{
- memset(pTokenizer, 0, sizeof(fts5_tokenizer));
- rc = SQLITE_ERROR;
- }
-
- return rc;
-}
-
-static int sqlite3Fts5GetTokenizer(
+** fts5_api.xFindTokenizer() method.
+*/
+static int fts5FindTokenizer(
+ fts5_api *pApi, /* Global context (one per db handle) */
+ const char *zName, /* Name of new function */
+ void **ppUserData,
+ fts5_tokenizer *pTokenizer /* Populate this object */
+){
+ int rc = SQLITE_OK;
+ Fts5TokenizerModule *pMod;
+
+ pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
+ if( pMod ){
+ *pTokenizer = pMod->x;
+ *ppUserData = pMod->pUserData;
+ }else{
+ memset(pTokenizer, 0, sizeof(fts5_tokenizer));
+ rc = SQLITE_ERROR;
+ }
+
+ return rc;
+}
+
+static int sqlite3Fts5GetTokenizer(
Fts5Global *pGlobal,
- const char **azArg,
- int nArg,
+ const char **azArg,
+ int nArg,
Fts5Config *pConfig,
- char **pzErr
-){
- Fts5TokenizerModule *pMod;
- int rc = SQLITE_OK;
-
- pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]);
- if( pMod==0 ){
- assert( nArg>0 );
- rc = SQLITE_ERROR;
- *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
- }else{
+ char **pzErr
+){
+ Fts5TokenizerModule *pMod;
+ int rc = SQLITE_OK;
+
+ pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]);
+ if( pMod==0 ){
+ assert( nArg>0 );
+ rc = SQLITE_ERROR;
+ *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
+ }else{
rc = pMod->x.xCreate(
pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok
);
@@ -232497,63 +232497,63 @@ static int sqlite3Fts5GetTokenizer(
pConfig->ePattern = sqlite3Fts5TokenizerPattern(
pMod->x.xCreate, pConfig->pTok
);
- }
- }
-
- if( rc!=SQLITE_OK ){
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
pConfig->pTokApi = 0;
pConfig->pTok = 0;
- }
-
- return rc;
-}
-
-static void fts5ModuleDestroy(void *pCtx){
- Fts5TokenizerModule *pTok, *pNextTok;
- Fts5Auxiliary *pAux, *pNextAux;
- Fts5Global *pGlobal = (Fts5Global*)pCtx;
-
- for(pAux=pGlobal->pAux; pAux; pAux=pNextAux){
- pNextAux = pAux->pNext;
- if( pAux->xDestroy ) pAux->xDestroy(pAux->pUserData);
- sqlite3_free(pAux);
- }
-
- for(pTok=pGlobal->pTok; pTok; pTok=pNextTok){
- pNextTok = pTok->pNext;
- if( pTok->xDestroy ) pTok->xDestroy(pTok->pUserData);
- sqlite3_free(pTok);
- }
-
- sqlite3_free(pGlobal);
-}
-
-static void fts5Fts5Func(
- sqlite3_context *pCtx, /* Function call context */
- int nArg, /* Number of args */
- sqlite3_value **apArg /* Function arguments */
-){
- Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
- fts5_api **ppApi;
- UNUSED_PARAM(nArg);
- assert( nArg==1 );
- ppApi = (fts5_api**)sqlite3_value_pointer(apArg[0], "fts5_api_ptr");
- if( ppApi ) *ppApi = &pGlobal->api;
-}
-
-/*
-** Implementation of fts5_source_id() function.
-*/
-static void fts5SourceIdFunc(
- sqlite3_context *pCtx, /* Function call context */
- int nArg, /* Number of args */
- sqlite3_value **apUnused /* Function arguments */
-){
- assert( nArg==0 );
- UNUSED_PARAM2(nArg, apUnused);
+ }
+
+ return rc;
+}
+
+static void fts5ModuleDestroy(void *pCtx){
+ Fts5TokenizerModule *pTok, *pNextTok;
+ Fts5Auxiliary *pAux, *pNextAux;
+ Fts5Global *pGlobal = (Fts5Global*)pCtx;
+
+ for(pAux=pGlobal->pAux; pAux; pAux=pNextAux){
+ pNextAux = pAux->pNext;
+ if( pAux->xDestroy ) pAux->xDestroy(pAux->pUserData);
+ sqlite3_free(pAux);
+ }
+
+ for(pTok=pGlobal->pTok; pTok; pTok=pNextTok){
+ pNextTok = pTok->pNext;
+ if( pTok->xDestroy ) pTok->xDestroy(pTok->pUserData);
+ sqlite3_free(pTok);
+ }
+
+ sqlite3_free(pGlobal);
+}
+
+static void fts5Fts5Func(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apArg /* Function arguments */
+){
+ Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
+ fts5_api **ppApi;
+ UNUSED_PARAM(nArg);
+ assert( nArg==1 );
+ ppApi = (fts5_api**)sqlite3_value_pointer(apArg[0], "fts5_api_ptr");
+ if( ppApi ) *ppApi = &pGlobal->api;
+}
+
+/*
+** Implementation of fts5_source_id() function.
+*/
+static void fts5SourceIdFunc(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apUnused /* Function arguments */
+){
+ assert( nArg==0 );
+ UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2022-01-06 13:25:41 872ba256cbf61d9290b571c0e6d82a20c224ca3ad82971edc46b29818d5d17a0", -1, SQLITE_TRANSIENT);
-}
-
+}
+
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
@@ -232569,1023 +232569,1023 @@ static int fts5ShadowName(const char *zName){
return 0;
}
-static int fts5Init(sqlite3 *db){
- static const sqlite3_module fts5Mod = {
+static int fts5Init(sqlite3 *db){
+ static const sqlite3_module fts5Mod = {
/* iVersion */ 3,
- /* xCreate */ fts5CreateMethod,
- /* xConnect */ fts5ConnectMethod,
- /* xBestIndex */ fts5BestIndexMethod,
- /* xDisconnect */ fts5DisconnectMethod,
- /* xDestroy */ fts5DestroyMethod,
- /* xOpen */ fts5OpenMethod,
- /* xClose */ fts5CloseMethod,
- /* xFilter */ fts5FilterMethod,
- /* xNext */ fts5NextMethod,
- /* xEof */ fts5EofMethod,
- /* xColumn */ fts5ColumnMethod,
- /* xRowid */ fts5RowidMethod,
- /* xUpdate */ fts5UpdateMethod,
- /* xBegin */ fts5BeginMethod,
- /* xSync */ fts5SyncMethod,
- /* xCommit */ fts5CommitMethod,
- /* xRollback */ fts5RollbackMethod,
- /* xFindFunction */ fts5FindFunctionMethod,
- /* xRename */ fts5RenameMethod,
- /* xSavepoint */ fts5SavepointMethod,
- /* xRelease */ fts5ReleaseMethod,
- /* xRollbackTo */ fts5RollbackToMethod,
+ /* xCreate */ fts5CreateMethod,
+ /* xConnect */ fts5ConnectMethod,
+ /* xBestIndex */ fts5BestIndexMethod,
+ /* xDisconnect */ fts5DisconnectMethod,
+ /* xDestroy */ fts5DestroyMethod,
+ /* xOpen */ fts5OpenMethod,
+ /* xClose */ fts5CloseMethod,
+ /* xFilter */ fts5FilterMethod,
+ /* xNext */ fts5NextMethod,
+ /* xEof */ fts5EofMethod,
+ /* xColumn */ fts5ColumnMethod,
+ /* xRowid */ fts5RowidMethod,
+ /* xUpdate */ fts5UpdateMethod,
+ /* xBegin */ fts5BeginMethod,
+ /* xSync */ fts5SyncMethod,
+ /* xCommit */ fts5CommitMethod,
+ /* xRollback */ fts5RollbackMethod,
+ /* xFindFunction */ fts5FindFunctionMethod,
+ /* xRename */ fts5RenameMethod,
+ /* xSavepoint */ fts5SavepointMethod,
+ /* xRelease */ fts5ReleaseMethod,
+ /* xRollbackTo */ fts5RollbackToMethod,
/* xShadowName */ fts5ShadowName
- };
-
- int rc;
- Fts5Global *pGlobal = 0;
-
- pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global));
- if( pGlobal==0 ){
- rc = SQLITE_NOMEM;
- }else{
- void *p = (void*)pGlobal;
- memset(pGlobal, 0, sizeof(Fts5Global));
- pGlobal->db = db;
- pGlobal->api.iVersion = 2;
- pGlobal->api.xCreateFunction = fts5CreateAux;
- pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
- pGlobal->api.xFindTokenizer = fts5FindTokenizer;
- rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
- if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
- if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
- if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
- if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
- if( rc==SQLITE_OK ) rc = sqlite3Fts5VocabInit(pGlobal, db);
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(
- db, "fts5", 1, SQLITE_UTF8, p, fts5Fts5Func, 0, 0
- );
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(
- db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0
- );
- }
- }
-
- /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
- ** fts5_test_mi.c is compiled and linked into the executable. And call
- ** its entry point to enable the matchinfo() demo. */
-#ifdef SQLITE_FTS5_ENABLE_TEST_MI
- if( rc==SQLITE_OK ){
- extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*);
- rc = sqlite3Fts5TestRegisterMatchinfo(db);
- }
-#endif
-
- return rc;
-}
-
-/*
-** The following functions are used to register the module with SQLite. If
-** this module is being built as part of the SQLite core (SQLITE_CORE is
-** defined), then sqlite3_open() will call sqlite3Fts5Init() directly.
-**
+ };
+
+ int rc;
+ Fts5Global *pGlobal = 0;
+
+ pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global));
+ if( pGlobal==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ void *p = (void*)pGlobal;
+ memset(pGlobal, 0, sizeof(Fts5Global));
+ pGlobal->db = db;
+ pGlobal->api.iVersion = 2;
+ pGlobal->api.xCreateFunction = fts5CreateAux;
+ pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
+ pGlobal->api.xFindTokenizer = fts5FindTokenizer;
+ rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
+ if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
+ if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
+ if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
+ if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
+ if( rc==SQLITE_OK ) rc = sqlite3Fts5VocabInit(pGlobal, db);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(
+ db, "fts5", 1, SQLITE_UTF8, p, fts5Fts5Func, 0, 0
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(
+ db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0
+ );
+ }
+ }
+
+ /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
+ ** fts5_test_mi.c is compiled and linked into the executable. And call
+ ** its entry point to enable the matchinfo() demo. */
+#ifdef SQLITE_FTS5_ENABLE_TEST_MI
+ if( rc==SQLITE_OK ){
+ extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*);
+ rc = sqlite3Fts5TestRegisterMatchinfo(db);
+ }
+#endif
+
+ return rc;
+}
+
+/*
+** The following functions are used to register the module with SQLite. If
+** this module is being built as part of the SQLite core (SQLITE_CORE is
+** defined), then sqlite3_open() will call sqlite3Fts5Init() directly.
+**
** Or, if this module is being built as a loadable extension,
-** sqlite3Fts5Init() is omitted and the two standard entry points
-** sqlite3_fts_init() and sqlite3_fts5_init() defined instead.
-*/
-#ifndef SQLITE_CORE
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-SQLITE_API int sqlite3_fts_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- SQLITE_EXTENSION_INIT2(pApi);
- (void)pzErrMsg; /* Unused parameter */
- return fts5Init(db);
-}
-
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-SQLITE_API int sqlite3_fts5_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- SQLITE_EXTENSION_INIT2(pApi);
- (void)pzErrMsg; /* Unused parameter */
- return fts5Init(db);
-}
-#else
-SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){
- return fts5Init(db);
-}
-#endif
-
-/*
-** 2014 May 31
-**
-** 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.
-**
-******************************************************************************
-**
-*/
-
-
-
-/* #include "fts5Int.h" */
-
-struct Fts5Storage {
- Fts5Config *pConfig;
- Fts5Index *pIndex;
- int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */
- i64 nTotalRow; /* Total number of rows in FTS table */
+** sqlite3Fts5Init() is omitted and the two standard entry points
+** sqlite3_fts_init() and sqlite3_fts5_init() defined instead.
+*/
+#ifndef SQLITE_CORE
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int sqlite3_fts_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg; /* Unused parameter */
+ return fts5Init(db);
+}
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int sqlite3_fts5_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg; /* Unused parameter */
+ return fts5Init(db);
+}
+#else
+SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){
+ return fts5Init(db);
+}
+#endif
+
+/*
+** 2014 May 31
+**
+** 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.
+**
+******************************************************************************
+**
+*/
+
+
+
+/* #include "fts5Int.h" */
+
+struct Fts5Storage {
+ Fts5Config *pConfig;
+ Fts5Index *pIndex;
+ int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */
+ i64 nTotalRow; /* Total number of rows in FTS table */
i64 *aTotalSize; /* Total sizes of each column */
- sqlite3_stmt *aStmt[11];
-};
-
-
+ sqlite3_stmt *aStmt[11];
+};
+
+
#if FTS5_STMT_SCAN_ASC!=0
# error "FTS5_STMT_SCAN_ASC mismatch"
-#endif
+#endif
#if FTS5_STMT_SCAN_DESC!=1
# error "FTS5_STMT_SCAN_DESC mismatch"
-#endif
-#if FTS5_STMT_LOOKUP!=2
+#endif
+#if FTS5_STMT_LOOKUP!=2
# error "FTS5_STMT_LOOKUP mismatch"
-#endif
-
-#define FTS5_STMT_INSERT_CONTENT 3
-#define FTS5_STMT_REPLACE_CONTENT 4
-#define FTS5_STMT_DELETE_CONTENT 5
-#define FTS5_STMT_REPLACE_DOCSIZE 6
-#define FTS5_STMT_DELETE_DOCSIZE 7
-#define FTS5_STMT_LOOKUP_DOCSIZE 8
-#define FTS5_STMT_REPLACE_CONFIG 9
-#define FTS5_STMT_SCAN 10
-
-/*
-** Prepare the two insert statements - Fts5Storage.pInsertContent and
-** Fts5Storage.pInsertDocsize - if they have not already been prepared.
-** Return SQLITE_OK if successful, or an SQLite error code if an error
-** occurs.
-*/
-static int fts5StorageGetStmt(
- Fts5Storage *p, /* Storage handle */
- int eStmt, /* FTS5_STMT_XXX constant */
- sqlite3_stmt **ppStmt, /* OUT: Prepared statement handle */
- char **pzErrMsg /* OUT: Error message (if any) */
-){
- int rc = SQLITE_OK;
-
+#endif
+
+#define FTS5_STMT_INSERT_CONTENT 3
+#define FTS5_STMT_REPLACE_CONTENT 4
+#define FTS5_STMT_DELETE_CONTENT 5
+#define FTS5_STMT_REPLACE_DOCSIZE 6
+#define FTS5_STMT_DELETE_DOCSIZE 7
+#define FTS5_STMT_LOOKUP_DOCSIZE 8
+#define FTS5_STMT_REPLACE_CONFIG 9
+#define FTS5_STMT_SCAN 10
+
+/*
+** Prepare the two insert statements - Fts5Storage.pInsertContent and
+** Fts5Storage.pInsertDocsize - if they have not already been prepared.
+** Return SQLITE_OK if successful, or an SQLite error code if an error
+** occurs.
+*/
+static int fts5StorageGetStmt(
+ Fts5Storage *p, /* Storage handle */
+ int eStmt, /* FTS5_STMT_XXX constant */
+ sqlite3_stmt **ppStmt, /* OUT: Prepared statement handle */
+ char **pzErrMsg /* OUT: Error message (if any) */
+){
+ int rc = SQLITE_OK;
+
/* If there is no %_docsize table, there should be no requests for
- ** statements to operate on it. */
- assert( p->pConfig->bColumnsize || (
+ ** statements to operate on it. */
+ assert( p->pConfig->bColumnsize || (
eStmt!=FTS5_STMT_REPLACE_DOCSIZE
&& eStmt!=FTS5_STMT_DELETE_DOCSIZE
&& eStmt!=FTS5_STMT_LOOKUP_DOCSIZE
- ));
-
- assert( eStmt>=0 && eStmt<ArraySize(p->aStmt) );
- if( p->aStmt[eStmt]==0 ){
- const char *azStmt[] = {
- "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC",
- "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC",
- "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */
-
- "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */
- "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */
- "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */
- "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", /* REPLACE_DOCSIZE */
- "DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */
-
- "SELECT sz FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */
-
- "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */
- "SELECT %s FROM %s AS T", /* SCAN */
- };
- Fts5Config *pC = p->pConfig;
- char *zSql = 0;
-
- switch( eStmt ){
- case FTS5_STMT_SCAN:
+ ));
+
+ assert( eStmt>=0 && eStmt<ArraySize(p->aStmt) );
+ if( p->aStmt[eStmt]==0 ){
+ const char *azStmt[] = {
+ "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC",
+ "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC",
+ "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */
+
+ "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */
+ "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */
+ "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */
+ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", /* REPLACE_DOCSIZE */
+ "DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */
+
+ "SELECT sz FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */
+
+ "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */
+ "SELECT %s FROM %s AS T", /* SCAN */
+ };
+ Fts5Config *pC = p->pConfig;
+ char *zSql = 0;
+
+ switch( eStmt ){
+ case FTS5_STMT_SCAN:
zSql = sqlite3_mprintf(azStmt[eStmt],
- pC->zContentExprlist, pC->zContent
- );
- break;
-
- case FTS5_STMT_SCAN_ASC:
- case FTS5_STMT_SCAN_DESC:
+ pC->zContentExprlist, pC->zContent
+ );
+ break;
+
+ case FTS5_STMT_SCAN_ASC:
+ case FTS5_STMT_SCAN_DESC:
zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist,
- pC->zContent, pC->zContentRowid, pC->zContentRowid,
- pC->zContentRowid
- );
- break;
-
- case FTS5_STMT_LOOKUP:
+ pC->zContent, pC->zContentRowid, pC->zContentRowid,
+ pC->zContentRowid
+ );
+ break;
+
+ case FTS5_STMT_LOOKUP:
zSql = sqlite3_mprintf(azStmt[eStmt],
- pC->zContentExprlist, pC->zContent, pC->zContentRowid
- );
- break;
-
+ pC->zContentExprlist, pC->zContent, pC->zContentRowid
+ );
+ break;
+
case FTS5_STMT_INSERT_CONTENT:
- case FTS5_STMT_REPLACE_CONTENT: {
- int nCol = pC->nCol + 1;
- char *zBind;
- int i;
-
+ case FTS5_STMT_REPLACE_CONTENT: {
+ int nCol = pC->nCol + 1;
+ char *zBind;
+ int i;
+
zBind = sqlite3_malloc64(1 + nCol*2);
- if( zBind ){
- for(i=0; i<nCol; i++){
- zBind[i*2] = '?';
- zBind[i*2 + 1] = ',';
- }
- zBind[i*2-1] = '\0';
- zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
- sqlite3_free(zBind);
- }
- break;
- }
-
- default:
- zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName);
- break;
- }
-
- if( zSql==0 ){
- rc = SQLITE_NOMEM;
- }else{
+ if( zBind ){
+ for(i=0; i<nCol; i++){
+ zBind[i*2] = '?';
+ zBind[i*2 + 1] = ',';
+ }
+ zBind[i*2-1] = '\0';
+ zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
+ sqlite3_free(zBind);
+ }
+ break;
+ }
+
+ default:
+ zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName);
+ break;
+ }
+
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
int f = SQLITE_PREPARE_PERSISTENT;
if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
p->pConfig->bLock++;
rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
p->pConfig->bLock--;
- sqlite3_free(zSql);
- if( rc!=SQLITE_OK && pzErrMsg ){
- *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
- }
- }
- }
-
- *ppStmt = p->aStmt[eStmt];
- sqlite3_reset(*ppStmt);
- return rc;
-}
-
-
-static int fts5ExecPrintf(
- sqlite3 *db,
- char **pzErr,
- const char *zFormat,
- ...
-){
- int rc;
- va_list ap; /* ... printf arguments */
- char *zSql;
-
- va_start(ap, zFormat);
- zSql = sqlite3_vmprintf(zFormat, ap);
-
- if( zSql==0 ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_exec(db, zSql, 0, 0, pzErr);
- sqlite3_free(zSql);
- }
-
- va_end(ap);
- return rc;
-}
-
-/*
-** Drop all shadow tables. Return SQLITE_OK if successful or an SQLite error
-** code otherwise.
-*/
-static int sqlite3Fts5DropAll(Fts5Config *pConfig){
+ sqlite3_free(zSql);
+ if( rc!=SQLITE_OK && pzErrMsg ){
+ *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
+ }
+ }
+ }
+
+ *ppStmt = p->aStmt[eStmt];
+ sqlite3_reset(*ppStmt);
+ return rc;
+}
+
+
+static int fts5ExecPrintf(
+ sqlite3 *db,
+ char **pzErr,
+ const char *zFormat,
+ ...
+){
+ int rc;
+ va_list ap; /* ... printf arguments */
+ char *zSql;
+
+ va_start(ap, zFormat);
+ zSql = sqlite3_vmprintf(zFormat, ap);
+
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_exec(db, zSql, 0, 0, pzErr);
+ sqlite3_free(zSql);
+ }
+
+ va_end(ap);
+ return rc;
+}
+
+/*
+** Drop all shadow tables. Return SQLITE_OK if successful or an SQLite error
+** code otherwise.
+*/
+static int sqlite3Fts5DropAll(Fts5Config *pConfig){
int rc = fts5ExecPrintf(pConfig->db, 0,
- "DROP TABLE IF EXISTS %Q.'%q_data';"
- "DROP TABLE IF EXISTS %Q.'%q_idx';"
- "DROP TABLE IF EXISTS %Q.'%q_config';",
- pConfig->zDb, pConfig->zName,
- pConfig->zDb, pConfig->zName,
- pConfig->zDb, pConfig->zName
- );
- if( rc==SQLITE_OK && pConfig->bColumnsize ){
+ "DROP TABLE IF EXISTS %Q.'%q_data';"
+ "DROP TABLE IF EXISTS %Q.'%q_idx';"
+ "DROP TABLE IF EXISTS %Q.'%q_config';",
+ pConfig->zDb, pConfig->zName,
+ pConfig->zDb, pConfig->zName,
+ pConfig->zDb, pConfig->zName
+ );
+ if( rc==SQLITE_OK && pConfig->bColumnsize ){
rc = fts5ExecPrintf(pConfig->db, 0,
- "DROP TABLE IF EXISTS %Q.'%q_docsize';",
- pConfig->zDb, pConfig->zName
- );
- }
- if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ "DROP TABLE IF EXISTS %Q.'%q_docsize';",
+ pConfig->zDb, pConfig->zName
+ );
+ }
+ if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
rc = fts5ExecPrintf(pConfig->db, 0,
- "DROP TABLE IF EXISTS %Q.'%q_content';",
- pConfig->zDb, pConfig->zName
- );
- }
- return rc;
-}
-
-static void fts5StorageRenameOne(
- Fts5Config *pConfig, /* Current FTS5 configuration */
- int *pRc, /* IN/OUT: Error code */
- const char *zTail, /* Tail of table name e.g. "data", "config" */
- const char *zName /* New name of FTS5 table */
-){
- if( *pRc==SQLITE_OK ){
+ "DROP TABLE IF EXISTS %Q.'%q_content';",
+ pConfig->zDb, pConfig->zName
+ );
+ }
+ return rc;
+}
+
+static void fts5StorageRenameOne(
+ Fts5Config *pConfig, /* Current FTS5 configuration */
+ int *pRc, /* IN/OUT: Error code */
+ const char *zTail, /* Tail of table name e.g. "data", "config" */
+ const char *zName /* New name of FTS5 table */
+){
+ if( *pRc==SQLITE_OK ){
*pRc = fts5ExecPrintf(pConfig->db, 0,
- "ALTER TABLE %Q.'%q_%s' RENAME TO '%q_%s';",
- pConfig->zDb, pConfig->zName, zTail, zName, zTail
- );
- }
-}
-
-static int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){
- Fts5Config *pConfig = pStorage->pConfig;
- int rc = sqlite3Fts5StorageSync(pStorage);
-
- fts5StorageRenameOne(pConfig, &rc, "data", zName);
- fts5StorageRenameOne(pConfig, &rc, "idx", zName);
- fts5StorageRenameOne(pConfig, &rc, "config", zName);
- if( pConfig->bColumnsize ){
- fts5StorageRenameOne(pConfig, &rc, "docsize", zName);
- }
- if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
- fts5StorageRenameOne(pConfig, &rc, "content", zName);
- }
- return rc;
-}
-
-/*
-** Create the shadow table named zPost, with definition zDefn. Return
-** SQLITE_OK if successful, or an SQLite error code otherwise.
-*/
-static int sqlite3Fts5CreateTable(
- Fts5Config *pConfig, /* FTS5 configuration */
- const char *zPost, /* Shadow table to create (e.g. "content") */
- const char *zDefn, /* Columns etc. for shadow table */
- int bWithout, /* True for without rowid */
- char **pzErr /* OUT: Error message */
-){
- int rc;
- char *zErr = 0;
-
- rc = fts5ExecPrintf(pConfig->db, &zErr, "CREATE TABLE %Q.'%q_%q'(%s)%s",
+ "ALTER TABLE %Q.'%q_%s' RENAME TO '%q_%s';",
+ pConfig->zDb, pConfig->zName, zTail, zName, zTail
+ );
+ }
+}
+
+static int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){
+ Fts5Config *pConfig = pStorage->pConfig;
+ int rc = sqlite3Fts5StorageSync(pStorage);
+
+ fts5StorageRenameOne(pConfig, &rc, "data", zName);
+ fts5StorageRenameOne(pConfig, &rc, "idx", zName);
+ fts5StorageRenameOne(pConfig, &rc, "config", zName);
+ if( pConfig->bColumnsize ){
+ fts5StorageRenameOne(pConfig, &rc, "docsize", zName);
+ }
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ fts5StorageRenameOne(pConfig, &rc, "content", zName);
+ }
+ return rc;
+}
+
+/*
+** Create the shadow table named zPost, with definition zDefn. Return
+** SQLITE_OK if successful, or an SQLite error code otherwise.
+*/
+static int sqlite3Fts5CreateTable(
+ Fts5Config *pConfig, /* FTS5 configuration */
+ const char *zPost, /* Shadow table to create (e.g. "content") */
+ const char *zDefn, /* Columns etc. for shadow table */
+ int bWithout, /* True for without rowid */
+ char **pzErr /* OUT: Error message */
+){
+ int rc;
+ char *zErr = 0;
+
+ rc = fts5ExecPrintf(pConfig->db, &zErr, "CREATE TABLE %Q.'%q_%q'(%s)%s",
pConfig->zDb, pConfig->zName, zPost, zDefn,
-#ifndef SQLITE_FTS5_NO_WITHOUT_ROWID
- bWithout?" WITHOUT ROWID":
-#endif
- ""
- );
- if( zErr ){
- *pzErr = sqlite3_mprintf(
+#ifndef SQLITE_FTS5_NO_WITHOUT_ROWID
+ bWithout?" WITHOUT ROWID":
+#endif
+ ""
+ );
+ if( zErr ){
+ *pzErr = sqlite3_mprintf(
"fts5: error creating shadow table %q_%s: %s",
- pConfig->zName, zPost, zErr
- );
- sqlite3_free(zErr);
- }
-
- return rc;
-}
-
-/*
-** Open a new Fts5Index handle. If the bCreate argument is true, create
+ pConfig->zName, zPost, zErr
+ );
+ sqlite3_free(zErr);
+ }
+
+ return rc;
+}
+
+/*
+** Open a new Fts5Index handle. If the bCreate argument is true, create
** and initialize the underlying tables
-**
-** If successful, set *pp to point to the new object and return SQLITE_OK.
-** Otherwise, set *pp to NULL and return an SQLite error code.
-*/
-static int sqlite3Fts5StorageOpen(
+**
+** If successful, set *pp to point to the new object and return SQLITE_OK.
+** Otherwise, set *pp to NULL and return an SQLite error code.
+*/
+static int sqlite3Fts5StorageOpen(
Fts5Config *pConfig,
Fts5Index *pIndex,
int bCreate,
- Fts5Storage **pp,
- char **pzErr /* OUT: Error message */
-){
- int rc = SQLITE_OK;
- Fts5Storage *p; /* New object */
+ Fts5Storage **pp,
+ char **pzErr /* OUT: Error message */
+){
+ int rc = SQLITE_OK;
+ Fts5Storage *p; /* New object */
sqlite3_int64 nByte; /* Bytes of space to allocate */
-
- nByte = sizeof(Fts5Storage) /* Fts5Storage object */
- + pConfig->nCol * sizeof(i64); /* Fts5Storage.aTotalSize[] */
+
+ nByte = sizeof(Fts5Storage) /* Fts5Storage object */
+ + pConfig->nCol * sizeof(i64); /* Fts5Storage.aTotalSize[] */
*pp = p = (Fts5Storage*)sqlite3_malloc64(nByte);
- if( !p ) return SQLITE_NOMEM;
-
+ if( !p ) return SQLITE_NOMEM;
+
memset(p, 0, (size_t)nByte);
- p->aTotalSize = (i64*)&p[1];
- p->pConfig = pConfig;
- p->pIndex = pIndex;
-
- if( bCreate ){
- if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
- int nDefn = 32 + pConfig->nCol*10;
+ p->aTotalSize = (i64*)&p[1];
+ p->pConfig = pConfig;
+ p->pIndex = pIndex;
+
+ if( bCreate ){
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ int nDefn = 32 + pConfig->nCol*10;
char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10);
- if( zDefn==0 ){
- rc = SQLITE_NOMEM;
- }else{
- int i;
- int iOff;
- sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY");
- iOff = (int)strlen(zDefn);
- for(i=0; i<pConfig->nCol; i++){
- sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
- iOff += (int)strlen(&zDefn[iOff]);
- }
- rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr);
- }
- sqlite3_free(zDefn);
- }
-
- if( rc==SQLITE_OK && pConfig->bColumnsize ){
- rc = sqlite3Fts5CreateTable(
- pConfig, "docsize", "id INTEGER PRIMARY KEY, sz BLOB", 0, pzErr
- );
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5CreateTable(
- pConfig, "config", "k PRIMARY KEY, v", 1, pzErr
- );
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION);
- }
- }
-
- if( rc ){
- sqlite3Fts5StorageClose(p);
- *pp = 0;
- }
- return rc;
-}
-
-/*
-** Close a handle opened by an earlier call to sqlite3Fts5StorageOpen().
-*/
-static int sqlite3Fts5StorageClose(Fts5Storage *p){
- int rc = SQLITE_OK;
- if( p ){
- int i;
-
- /* Finalize all SQL statements */
- for(i=0; i<ArraySize(p->aStmt); i++){
- sqlite3_finalize(p->aStmt[i]);
- }
-
- sqlite3_free(p);
- }
- return rc;
-}
-
-typedef struct Fts5InsertCtx Fts5InsertCtx;
-struct Fts5InsertCtx {
- Fts5Storage *pStorage;
- int iCol;
- int szCol; /* Size of column value in tokens */
-};
-
-/*
-** Tokenization callback used when inserting tokens into the FTS index.
-*/
-static int fts5StorageInsertCallback(
- void *pContext, /* Pointer to Fts5InsertCtx object */
- int tflags,
- const char *pToken, /* Buffer containing token */
- int nToken, /* Size of token in bytes */
- int iUnused1, /* Start offset of token */
- int iUnused2 /* End offset of token */
-){
- Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext;
- Fts5Index *pIdx = pCtx->pStorage->pIndex;
- UNUSED_PARAM2(iUnused1, iUnused2);
- if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
- if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
- pCtx->szCol++;
- }
- return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken);
-}
-
-/*
-** If a row with rowid iDel is present in the %_content table, add the
-** delete-markers to the FTS index necessary to delete it. Do not actually
-** remove the %_content row at this time though.
-*/
-static int fts5StorageDeleteFromIndex(
+ if( zDefn==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ int i;
+ int iOff;
+ sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY");
+ iOff = (int)strlen(zDefn);
+ for(i=0; i<pConfig->nCol; i++){
+ sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
+ iOff += (int)strlen(&zDefn[iOff]);
+ }
+ rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr);
+ }
+ sqlite3_free(zDefn);
+ }
+
+ if( rc==SQLITE_OK && pConfig->bColumnsize ){
+ rc = sqlite3Fts5CreateTable(
+ pConfig, "docsize", "id INTEGER PRIMARY KEY, sz BLOB", 0, pzErr
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5CreateTable(
+ pConfig, "config", "k PRIMARY KEY, v", 1, pzErr
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION);
+ }
+ }
+
+ if( rc ){
+ sqlite3Fts5StorageClose(p);
+ *pp = 0;
+ }
+ return rc;
+}
+
+/*
+** Close a handle opened by an earlier call to sqlite3Fts5StorageOpen().
+*/
+static int sqlite3Fts5StorageClose(Fts5Storage *p){
+ int rc = SQLITE_OK;
+ if( p ){
+ int i;
+
+ /* Finalize all SQL statements */
+ for(i=0; i<ArraySize(p->aStmt); i++){
+ sqlite3_finalize(p->aStmt[i]);
+ }
+
+ sqlite3_free(p);
+ }
+ return rc;
+}
+
+typedef struct Fts5InsertCtx Fts5InsertCtx;
+struct Fts5InsertCtx {
+ Fts5Storage *pStorage;
+ int iCol;
+ int szCol; /* Size of column value in tokens */
+};
+
+/*
+** Tokenization callback used when inserting tokens into the FTS index.
+*/
+static int fts5StorageInsertCallback(
+ void *pContext, /* Pointer to Fts5InsertCtx object */
+ int tflags,
+ const char *pToken, /* Buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iUnused1, /* Start offset of token */
+ int iUnused2 /* End offset of token */
+){
+ Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext;
+ Fts5Index *pIdx = pCtx->pStorage->pIndex;
+ UNUSED_PARAM2(iUnused1, iUnused2);
+ if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
+ pCtx->szCol++;
+ }
+ return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken);
+}
+
+/*
+** If a row with rowid iDel is present in the %_content table, add the
+** delete-markers to the FTS index necessary to delete it. Do not actually
+** remove the %_content row at this time though.
+*/
+static int fts5StorageDeleteFromIndex(
Fts5Storage *p,
i64 iDel,
- sqlite3_value **apVal
-){
- Fts5Config *pConfig = p->pConfig;
- sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */
- int rc; /* Return code */
- int rc2; /* sqlite3_reset() return code */
- int iCol;
- Fts5InsertCtx ctx;
-
- if( apVal==0 ){
- rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0);
- if( rc!=SQLITE_OK ) return rc;
- sqlite3_bind_int64(pSeek, 1, iDel);
- if( sqlite3_step(pSeek)!=SQLITE_ROW ){
- return sqlite3_reset(pSeek);
- }
- }
-
- ctx.pStorage = p;
- ctx.iCol = -1;
- rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
- for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
- if( pConfig->abUnindexed[iCol-1]==0 ){
- const char *zText;
- int nText;
+ sqlite3_value **apVal
+){
+ Fts5Config *pConfig = p->pConfig;
+ sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */
+ int rc; /* Return code */
+ int rc2; /* sqlite3_reset() return code */
+ int iCol;
+ Fts5InsertCtx ctx;
+
+ if( apVal==0 ){
+ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0);
+ if( rc!=SQLITE_OK ) return rc;
+ sqlite3_bind_int64(pSeek, 1, iDel);
+ if( sqlite3_step(pSeek)!=SQLITE_ROW ){
+ return sqlite3_reset(pSeek);
+ }
+ }
+
+ ctx.pStorage = p;
+ ctx.iCol = -1;
+ rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
+ for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
+ if( pConfig->abUnindexed[iCol-1]==0 ){
+ const char *zText;
+ int nText;
assert( pSeek==0 || apVal==0 );
assert( pSeek!=0 || apVal!=0 );
- if( pSeek ){
- zText = (const char*)sqlite3_column_text(pSeek, iCol);
- nText = sqlite3_column_bytes(pSeek, iCol);
+ if( pSeek ){
+ zText = (const char*)sqlite3_column_text(pSeek, iCol);
+ nText = sqlite3_column_bytes(pSeek, iCol);
}else if( ALWAYS(apVal) ){
- zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
- nText = sqlite3_value_bytes(apVal[iCol-1]);
+ zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
+ nText = sqlite3_value_bytes(apVal[iCol-1]);
}else{
continue;
- }
- ctx.szCol = 0;
+ }
+ ctx.szCol = 0;
rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
- zText, nText, (void*)&ctx, fts5StorageInsertCallback
- );
- p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
+ zText, nText, (void*)&ctx, fts5StorageInsertCallback
+ );
+ p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
if( p->aTotalSize[iCol-1]<0 ){
rc = FTS5_CORRUPT;
}
- }
- }
+ }
+ }
if( rc==SQLITE_OK && p->nTotalRow<1 ){
rc = FTS5_CORRUPT;
}else{
p->nTotalRow--;
}
-
- rc2 = sqlite3_reset(pSeek);
- if( rc==SQLITE_OK ) rc = rc2;
- return rc;
-}
-
-
-/*
-** Insert a record into the %_docsize table. Specifically, do:
-**
-** INSERT OR REPLACE INTO %_docsize(id, sz) VALUES(iRowid, pBuf);
-**
-** If there is no %_docsize table (as happens if the columnsize=0 option
-** is specified when the FTS5 table is created), this function is a no-op.
-*/
-static int fts5StorageInsertDocsize(
- Fts5Storage *p, /* Storage module to write to */
- i64 iRowid, /* id value */
- Fts5Buffer *pBuf /* sz value */
-){
- int rc = SQLITE_OK;
- if( p->pConfig->bColumnsize ){
- sqlite3_stmt *pReplace = 0;
- rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pReplace, 1, iRowid);
- sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
- sqlite3_step(pReplace);
- rc = sqlite3_reset(pReplace);
+
+ rc2 = sqlite3_reset(pSeek);
+ if( rc==SQLITE_OK ) rc = rc2;
+ return rc;
+}
+
+
+/*
+** Insert a record into the %_docsize table. Specifically, do:
+**
+** INSERT OR REPLACE INTO %_docsize(id, sz) VALUES(iRowid, pBuf);
+**
+** If there is no %_docsize table (as happens if the columnsize=0 option
+** is specified when the FTS5 table is created), this function is a no-op.
+*/
+static int fts5StorageInsertDocsize(
+ Fts5Storage *p, /* Storage module to write to */
+ i64 iRowid, /* id value */
+ Fts5Buffer *pBuf /* sz value */
+){
+ int rc = SQLITE_OK;
+ if( p->pConfig->bColumnsize ){
+ sqlite3_stmt *pReplace = 0;
+ rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_int64(pReplace, 1, iRowid);
+ sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
+ sqlite3_step(pReplace);
+ rc = sqlite3_reset(pReplace);
sqlite3_bind_null(pReplace, 2);
- }
- }
- return rc;
-}
-
-/*
+ }
+ }
+ return rc;
+}
+
+/*
** Load the contents of the "averages" record from disk into the
-** p->nTotalRow and p->aTotalSize[] variables. If successful, and if
-** argument bCache is true, set the p->bTotalsValid flag to indicate
-** that the contents of aTotalSize[] and nTotalRow are valid until
-** further notice.
-**
-** Return SQLITE_OK if successful, or an SQLite error code if an error
-** occurs.
-*/
-static int fts5StorageLoadTotals(Fts5Storage *p, int bCache){
- int rc = SQLITE_OK;
- if( p->bTotalsValid==0 ){
- rc = sqlite3Fts5IndexGetAverages(p->pIndex, &p->nTotalRow, p->aTotalSize);
- p->bTotalsValid = bCache;
- }
- return rc;
-}
-
-/*
+** p->nTotalRow and p->aTotalSize[] variables. If successful, and if
+** argument bCache is true, set the p->bTotalsValid flag to indicate
+** that the contents of aTotalSize[] and nTotalRow are valid until
+** further notice.
+**
+** Return SQLITE_OK if successful, or an SQLite error code if an error
+** occurs.
+*/
+static int fts5StorageLoadTotals(Fts5Storage *p, int bCache){
+ int rc = SQLITE_OK;
+ if( p->bTotalsValid==0 ){
+ rc = sqlite3Fts5IndexGetAverages(p->pIndex, &p->nTotalRow, p->aTotalSize);
+ p->bTotalsValid = bCache;
+ }
+ return rc;
+}
+
+/*
** Store the current contents of the p->nTotalRow and p->aTotalSize[]
-** variables in the "averages" record on disk.
-**
-** Return SQLITE_OK if successful, or an SQLite error code if an error
-** occurs.
-*/
-static int fts5StorageSaveTotals(Fts5Storage *p){
- int nCol = p->pConfig->nCol;
- int i;
- Fts5Buffer buf;
- int rc = SQLITE_OK;
- memset(&buf, 0, sizeof(buf));
-
- sqlite3Fts5BufferAppendVarint(&rc, &buf, p->nTotalRow);
- for(i=0; i<nCol; i++){
- sqlite3Fts5BufferAppendVarint(&rc, &buf, p->aTotalSize[i]);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5IndexSetAverages(p->pIndex, buf.p, buf.n);
- }
- sqlite3_free(buf.p);
-
- return rc;
-}
-
-/*
-** Remove a row from the FTS table.
-*/
-static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){
- Fts5Config *pConfig = p->pConfig;
- int rc;
- sqlite3_stmt *pDel = 0;
-
- assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 );
- rc = fts5StorageLoadTotals(p, 1);
-
- /* Delete the index records */
- if( rc==SQLITE_OK ){
- rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
- }
-
- /* Delete the %_docsize record */
- if( rc==SQLITE_OK && pConfig->bColumnsize ){
- rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pDel, 1, iDel);
- sqlite3_step(pDel);
- rc = sqlite3_reset(pDel);
- }
- }
-
- /* Delete the %_content record */
- if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
- if( rc==SQLITE_OK ){
- rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0);
- }
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pDel, 1, iDel);
- sqlite3_step(pDel);
- rc = sqlite3_reset(pDel);
- }
- }
-
- return rc;
-}
-
-/*
-** Delete all entries in the FTS5 index.
-*/
-static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){
- Fts5Config *pConfig = p->pConfig;
- int rc;
-
+** variables in the "averages" record on disk.
+**
+** Return SQLITE_OK if successful, or an SQLite error code if an error
+** occurs.
+*/
+static int fts5StorageSaveTotals(Fts5Storage *p){
+ int nCol = p->pConfig->nCol;
+ int i;
+ Fts5Buffer buf;
+ int rc = SQLITE_OK;
+ memset(&buf, 0, sizeof(buf));
+
+ sqlite3Fts5BufferAppendVarint(&rc, &buf, p->nTotalRow);
+ for(i=0; i<nCol; i++){
+ sqlite3Fts5BufferAppendVarint(&rc, &buf, p->aTotalSize[i]);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexSetAverages(p->pIndex, buf.p, buf.n);
+ }
+ sqlite3_free(buf.p);
+
+ return rc;
+}
+
+/*
+** Remove a row from the FTS table.
+*/
+static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){
+ Fts5Config *pConfig = p->pConfig;
+ int rc;
+ sqlite3_stmt *pDel = 0;
+
+ assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 );
+ rc = fts5StorageLoadTotals(p, 1);
+
+ /* Delete the index records */
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
+ }
+
+ /* Delete the %_docsize record */
+ if( rc==SQLITE_OK && pConfig->bColumnsize ){
+ rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_int64(pDel, 1, iDel);
+ sqlite3_step(pDel);
+ rc = sqlite3_reset(pDel);
+ }
+ }
+
+ /* Delete the %_content record */
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0);
+ }
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_int64(pDel, 1, iDel);
+ sqlite3_step(pDel);
+ rc = sqlite3_reset(pDel);
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Delete all entries in the FTS5 index.
+*/
+static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){
+ Fts5Config *pConfig = p->pConfig;
+ int rc;
+
p->bTotalsValid = 0;
- /* Delete the contents of the %_data and %_docsize tables. */
- rc = fts5ExecPrintf(pConfig->db, 0,
+ /* Delete the contents of the %_data and %_docsize tables. */
+ rc = fts5ExecPrintf(pConfig->db, 0,
"DELETE FROM %Q.'%q_data';"
- "DELETE FROM %Q.'%q_idx';",
- pConfig->zDb, pConfig->zName,
- pConfig->zDb, pConfig->zName
- );
- if( rc==SQLITE_OK && pConfig->bColumnsize ){
- rc = fts5ExecPrintf(pConfig->db, 0,
- "DELETE FROM %Q.'%q_docsize';",
- pConfig->zDb, pConfig->zName
- );
- }
-
- /* Reinitialize the %_data table. This call creates the initial structure
- ** and averages records. */
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5IndexReinit(p->pIndex);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION);
- }
- return rc;
-}
-
-static int sqlite3Fts5StorageRebuild(Fts5Storage *p){
- Fts5Buffer buf = {0,0,0};
- Fts5Config *pConfig = p->pConfig;
- sqlite3_stmt *pScan = 0;
- Fts5InsertCtx ctx;
+ "DELETE FROM %Q.'%q_idx';",
+ pConfig->zDb, pConfig->zName,
+ pConfig->zDb, pConfig->zName
+ );
+ if( rc==SQLITE_OK && pConfig->bColumnsize ){
+ rc = fts5ExecPrintf(pConfig->db, 0,
+ "DELETE FROM %Q.'%q_docsize';",
+ pConfig->zDb, pConfig->zName
+ );
+ }
+
+ /* Reinitialize the %_data table. This call creates the initial structure
+ ** and averages records. */
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexReinit(p->pIndex);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION);
+ }
+ return rc;
+}
+
+static int sqlite3Fts5StorageRebuild(Fts5Storage *p){
+ Fts5Buffer buf = {0,0,0};
+ Fts5Config *pConfig = p->pConfig;
+ sqlite3_stmt *pScan = 0;
+ Fts5InsertCtx ctx;
int rc, rc2;
-
- memset(&ctx, 0, sizeof(Fts5InsertCtx));
- ctx.pStorage = p;
- rc = sqlite3Fts5StorageDeleteAll(p);
- if( rc==SQLITE_OK ){
- rc = fts5StorageLoadTotals(p, 1);
- }
-
- if( rc==SQLITE_OK ){
- rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
- }
-
- while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){
- i64 iRowid = sqlite3_column_int64(pScan, 0);
-
- sqlite3Fts5BufferZero(&buf);
- rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
- for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
- ctx.szCol = 0;
- if( pConfig->abUnindexed[ctx.iCol]==0 ){
+
+ memset(&ctx, 0, sizeof(Fts5InsertCtx));
+ ctx.pStorage = p;
+ rc = sqlite3Fts5StorageDeleteAll(p);
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageLoadTotals(p, 1);
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
+ }
+
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){
+ i64 iRowid = sqlite3_column_int64(pScan, 0);
+
+ sqlite3Fts5BufferZero(&buf);
+ rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
+ for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
+ ctx.szCol = 0;
+ if( pConfig->abUnindexed[ctx.iCol]==0 ){
const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1);
int nText = sqlite3_column_bytes(pScan, ctx.iCol+1);
rc = sqlite3Fts5Tokenize(pConfig,
- FTS5_TOKENIZE_DOCUMENT,
+ FTS5_TOKENIZE_DOCUMENT,
zText, nText,
- (void*)&ctx,
- fts5StorageInsertCallback
- );
- }
- sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
- p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
- }
- p->nTotalRow++;
-
- if( rc==SQLITE_OK ){
- rc = fts5StorageInsertDocsize(p, iRowid, &buf);
- }
- }
- sqlite3_free(buf.p);
+ (void*)&ctx,
+ fts5StorageInsertCallback
+ );
+ }
+ sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
+ p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
+ }
+ p->nTotalRow++;
+
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageInsertDocsize(p, iRowid, &buf);
+ }
+ }
+ sqlite3_free(buf.p);
rc2 = sqlite3_reset(pScan);
if( rc==SQLITE_OK ) rc = rc2;
-
- /* Write the averages record */
- if( rc==SQLITE_OK ){
- rc = fts5StorageSaveTotals(p);
- }
- return rc;
-}
-
-static int sqlite3Fts5StorageOptimize(Fts5Storage *p){
- return sqlite3Fts5IndexOptimize(p->pIndex);
-}
-
-static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){
- return sqlite3Fts5IndexMerge(p->pIndex, nMerge);
-}
-
-static int sqlite3Fts5StorageReset(Fts5Storage *p){
- return sqlite3Fts5IndexReset(p->pIndex);
-}
-
-/*
-** Allocate a new rowid. This is used for "external content" tables when
-** a NULL value is inserted into the rowid column. The new rowid is allocated
-** by inserting a dummy row into the %_docsize table. The dummy will be
-** overwritten later.
-**
-** If the %_docsize table does not exist, SQLITE_MISMATCH is returned. In
-** this case the user is required to provide a rowid explicitly.
-*/
-static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){
- int rc = SQLITE_MISMATCH;
- if( p->pConfig->bColumnsize ){
- sqlite3_stmt *pReplace = 0;
- rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_null(pReplace, 1);
- sqlite3_bind_null(pReplace, 2);
- sqlite3_step(pReplace);
- rc = sqlite3_reset(pReplace);
- }
- if( rc==SQLITE_OK ){
- *piRowid = sqlite3_last_insert_rowid(p->pConfig->db);
- }
- }
- return rc;
-}
-
-/*
-** Insert a new row into the FTS content table.
-*/
-static int sqlite3Fts5StorageContentInsert(
+
+ /* Write the averages record */
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageSaveTotals(p);
+ }
+ return rc;
+}
+
+static int sqlite3Fts5StorageOptimize(Fts5Storage *p){
+ return sqlite3Fts5IndexOptimize(p->pIndex);
+}
+
+static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){
+ return sqlite3Fts5IndexMerge(p->pIndex, nMerge);
+}
+
+static int sqlite3Fts5StorageReset(Fts5Storage *p){
+ return sqlite3Fts5IndexReset(p->pIndex);
+}
+
+/*
+** Allocate a new rowid. This is used for "external content" tables when
+** a NULL value is inserted into the rowid column. The new rowid is allocated
+** by inserting a dummy row into the %_docsize table. The dummy will be
+** overwritten later.
+**
+** If the %_docsize table does not exist, SQLITE_MISMATCH is returned. In
+** this case the user is required to provide a rowid explicitly.
+*/
+static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){
+ int rc = SQLITE_MISMATCH;
+ if( p->pConfig->bColumnsize ){
+ sqlite3_stmt *pReplace = 0;
+ rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_null(pReplace, 1);
+ sqlite3_bind_null(pReplace, 2);
+ sqlite3_step(pReplace);
+ rc = sqlite3_reset(pReplace);
+ }
+ if( rc==SQLITE_OK ){
+ *piRowid = sqlite3_last_insert_rowid(p->pConfig->db);
+ }
+ }
+ return rc;
+}
+
+/*
+** Insert a new row into the FTS content table.
+*/
+static int sqlite3Fts5StorageContentInsert(
Fts5Storage *p,
sqlite3_value **apVal,
- i64 *piRowid
-){
- Fts5Config *pConfig = p->pConfig;
- int rc = SQLITE_OK;
-
- /* Insert the new row into the %_content table. */
- if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
- if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){
- *piRowid = sqlite3_value_int64(apVal[1]);
- }else{
- rc = fts5StorageNewRowid(p, piRowid);
- }
- }else{
- sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
- int i; /* Counter variable */
- rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
- for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
- rc = sqlite3_bind_value(pInsert, i, apVal[i]);
- }
- if( rc==SQLITE_OK ){
- sqlite3_step(pInsert);
- rc = sqlite3_reset(pInsert);
- }
- *piRowid = sqlite3_last_insert_rowid(pConfig->db);
- }
-
- return rc;
-}
-
-/*
-** Insert new entries into the FTS index and %_docsize table.
-*/
-static int sqlite3Fts5StorageIndexInsert(
+ i64 *piRowid
+){
+ Fts5Config *pConfig = p->pConfig;
+ int rc = SQLITE_OK;
+
+ /* Insert the new row into the %_content table. */
+ if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
+ if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){
+ *piRowid = sqlite3_value_int64(apVal[1]);
+ }else{
+ rc = fts5StorageNewRowid(p, piRowid);
+ }
+ }else{
+ sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
+ int i; /* Counter variable */
+ rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
+ for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
+ rc = sqlite3_bind_value(pInsert, i, apVal[i]);
+ }
+ if( rc==SQLITE_OK ){
+ sqlite3_step(pInsert);
+ rc = sqlite3_reset(pInsert);
+ }
+ *piRowid = sqlite3_last_insert_rowid(pConfig->db);
+ }
+
+ return rc;
+}
+
+/*
+** Insert new entries into the FTS index and %_docsize table.
+*/
+static int sqlite3Fts5StorageIndexInsert(
Fts5Storage *p,
sqlite3_value **apVal,
- i64 iRowid
-){
- Fts5Config *pConfig = p->pConfig;
- int rc = SQLITE_OK; /* Return code */
- Fts5InsertCtx ctx; /* Tokenization callback context object */
- Fts5Buffer buf; /* Buffer used to build up %_docsize blob */
-
- memset(&buf, 0, sizeof(Fts5Buffer));
- ctx.pStorage = p;
- rc = fts5StorageLoadTotals(p, 1);
-
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
- }
- for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
- ctx.szCol = 0;
- if( pConfig->abUnindexed[ctx.iCol]==0 ){
+ i64 iRowid
+){
+ Fts5Config *pConfig = p->pConfig;
+ int rc = SQLITE_OK; /* Return code */
+ Fts5InsertCtx ctx; /* Tokenization callback context object */
+ Fts5Buffer buf; /* Buffer used to build up %_docsize blob */
+
+ memset(&buf, 0, sizeof(Fts5Buffer));
+ ctx.pStorage = p;
+ rc = fts5StorageLoadTotals(p, 1);
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
+ }
+ for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
+ ctx.szCol = 0;
+ if( pConfig->abUnindexed[ctx.iCol]==0 ){
const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]);
int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]);
rc = sqlite3Fts5Tokenize(pConfig,
- FTS5_TOKENIZE_DOCUMENT,
+ FTS5_TOKENIZE_DOCUMENT,
zText, nText,
- (void*)&ctx,
- fts5StorageInsertCallback
- );
- }
- sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
- p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
- }
- p->nTotalRow++;
-
- /* Write the %_docsize record */
- if( rc==SQLITE_OK ){
- rc = fts5StorageInsertDocsize(p, iRowid, &buf);
- }
- sqlite3_free(buf.p);
-
- return rc;
-}
-
-static int fts5StorageCount(Fts5Storage *p, const char *zSuffix, i64 *pnRow){
- Fts5Config *pConfig = p->pConfig;
- char *zSql;
- int rc;
-
+ (void*)&ctx,
+ fts5StorageInsertCallback
+ );
+ }
+ sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
+ p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
+ }
+ p->nTotalRow++;
+
+ /* Write the %_docsize record */
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageInsertDocsize(p, iRowid, &buf);
+ }
+ sqlite3_free(buf.p);
+
+ return rc;
+}
+
+static int fts5StorageCount(Fts5Storage *p, const char *zSuffix, i64 *pnRow){
+ Fts5Config *pConfig = p->pConfig;
+ char *zSql;
+ int rc;
+
zSql = sqlite3_mprintf("SELECT count(*) FROM %Q.'%q_%s'",
- pConfig->zDb, pConfig->zName, zSuffix
- );
- if( zSql==0 ){
- rc = SQLITE_NOMEM;
- }else{
- sqlite3_stmt *pCnt = 0;
- rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pCnt, 0);
- if( rc==SQLITE_OK ){
- if( SQLITE_ROW==sqlite3_step(pCnt) ){
- *pnRow = sqlite3_column_int64(pCnt, 0);
- }
- rc = sqlite3_finalize(pCnt);
- }
- }
-
- sqlite3_free(zSql);
- return rc;
-}
-
-/*
-** Context object used by sqlite3Fts5StorageIntegrity().
-*/
-typedef struct Fts5IntegrityCtx Fts5IntegrityCtx;
-struct Fts5IntegrityCtx {
- i64 iRowid;
- int iCol;
- int szCol;
- u64 cksum;
- Fts5Termset *pTermset;
- Fts5Config *pConfig;
-};
-
-
-/*
-** Tokenization callback used by integrity check.
-*/
-static int fts5StorageIntegrityCallback(
- void *pContext, /* Pointer to Fts5IntegrityCtx object */
- int tflags,
- const char *pToken, /* Buffer containing token */
- int nToken, /* Size of token in bytes */
- int iUnused1, /* Start offset of token */
- int iUnused2 /* End offset of token */
-){
- Fts5IntegrityCtx *pCtx = (Fts5IntegrityCtx*)pContext;
- Fts5Termset *pTermset = pCtx->pTermset;
- int bPresent;
- int ii;
- int rc = SQLITE_OK;
- int iPos;
- int iCol;
-
- UNUSED_PARAM2(iUnused1, iUnused2);
- if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
-
- if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
- pCtx->szCol++;
- }
-
- switch( pCtx->pConfig->eDetail ){
- case FTS5_DETAIL_FULL:
- iPos = pCtx->szCol-1;
- iCol = pCtx->iCol;
- break;
-
- case FTS5_DETAIL_COLUMNS:
- iPos = pCtx->iCol;
- iCol = 0;
- break;
-
- default:
- assert( pCtx->pConfig->eDetail==FTS5_DETAIL_NONE );
- iPos = 0;
- iCol = 0;
- break;
- }
-
- rc = sqlite3Fts5TermsetAdd(pTermset, 0, pToken, nToken, &bPresent);
- if( rc==SQLITE_OK && bPresent==0 ){
- pCtx->cksum ^= sqlite3Fts5IndexEntryCksum(
- pCtx->iRowid, iCol, iPos, 0, pToken, nToken
- );
- }
-
- for(ii=0; rc==SQLITE_OK && ii<pCtx->pConfig->nPrefix; ii++){
- const int nChar = pCtx->pConfig->aPrefix[ii];
- int nByte = sqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar);
- if( nByte ){
- rc = sqlite3Fts5TermsetAdd(pTermset, ii+1, pToken, nByte, &bPresent);
- if( bPresent==0 ){
- pCtx->cksum ^= sqlite3Fts5IndexEntryCksum(
- pCtx->iRowid, iCol, iPos, ii+1, pToken, nByte
- );
- }
- }
- }
-
- return rc;
-}
-
-/*
-** Check that the contents of the FTS index match that of the %_content
-** table. Return SQLITE_OK if they do, or SQLITE_CORRUPT if not. Return
-** some other SQLite error code if an error occurs while attempting to
-** determine this.
-*/
+ pConfig->zDb, pConfig->zName, zSuffix
+ );
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_stmt *pCnt = 0;
+ rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pCnt, 0);
+ if( rc==SQLITE_OK ){
+ if( SQLITE_ROW==sqlite3_step(pCnt) ){
+ *pnRow = sqlite3_column_int64(pCnt, 0);
+ }
+ rc = sqlite3_finalize(pCnt);
+ }
+ }
+
+ sqlite3_free(zSql);
+ return rc;
+}
+
+/*
+** Context object used by sqlite3Fts5StorageIntegrity().
+*/
+typedef struct Fts5IntegrityCtx Fts5IntegrityCtx;
+struct Fts5IntegrityCtx {
+ i64 iRowid;
+ int iCol;
+ int szCol;
+ u64 cksum;
+ Fts5Termset *pTermset;
+ Fts5Config *pConfig;
+};
+
+
+/*
+** Tokenization callback used by integrity check.
+*/
+static int fts5StorageIntegrityCallback(
+ void *pContext, /* Pointer to Fts5IntegrityCtx object */
+ int tflags,
+ const char *pToken, /* Buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iUnused1, /* Start offset of token */
+ int iUnused2 /* End offset of token */
+){
+ Fts5IntegrityCtx *pCtx = (Fts5IntegrityCtx*)pContext;
+ Fts5Termset *pTermset = pCtx->pTermset;
+ int bPresent;
+ int ii;
+ int rc = SQLITE_OK;
+ int iPos;
+ int iCol;
+
+ UNUSED_PARAM2(iUnused1, iUnused2);
+ if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
+
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
+ pCtx->szCol++;
+ }
+
+ switch( pCtx->pConfig->eDetail ){
+ case FTS5_DETAIL_FULL:
+ iPos = pCtx->szCol-1;
+ iCol = pCtx->iCol;
+ break;
+
+ case FTS5_DETAIL_COLUMNS:
+ iPos = pCtx->iCol;
+ iCol = 0;
+ break;
+
+ default:
+ assert( pCtx->pConfig->eDetail==FTS5_DETAIL_NONE );
+ iPos = 0;
+ iCol = 0;
+ break;
+ }
+
+ rc = sqlite3Fts5TermsetAdd(pTermset, 0, pToken, nToken, &bPresent);
+ if( rc==SQLITE_OK && bPresent==0 ){
+ pCtx->cksum ^= sqlite3Fts5IndexEntryCksum(
+ pCtx->iRowid, iCol, iPos, 0, pToken, nToken
+ );
+ }
+
+ for(ii=0; rc==SQLITE_OK && ii<pCtx->pConfig->nPrefix; ii++){
+ const int nChar = pCtx->pConfig->aPrefix[ii];
+ int nByte = sqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar);
+ if( nByte ){
+ rc = sqlite3Fts5TermsetAdd(pTermset, ii+1, pToken, nByte, &bPresent);
+ if( bPresent==0 ){
+ pCtx->cksum ^= sqlite3Fts5IndexEntryCksum(
+ pCtx->iRowid, iCol, iPos, ii+1, pToken, nByte
+ );
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Check that the contents of the FTS index match that of the %_content
+** table. Return SQLITE_OK if they do, or SQLITE_CORRUPT if not. Return
+** some other SQLite error code if an error occurs while attempting to
+** determine this.
+*/
static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){
- Fts5Config *pConfig = p->pConfig;
+ Fts5Config *pConfig = p->pConfig;
int rc = SQLITE_OK; /* Return code */
- int *aColSize; /* Array of size pConfig->nCol */
- i64 *aTotalSize; /* Array of size pConfig->nCol */
- Fts5IntegrityCtx ctx;
- sqlite3_stmt *pScan;
+ int *aColSize; /* Array of size pConfig->nCol */
+ i64 *aTotalSize; /* Array of size pConfig->nCol */
+ Fts5IntegrityCtx ctx;
+ sqlite3_stmt *pScan;
int bUseCksum;
-
- memset(&ctx, 0, sizeof(Fts5IntegrityCtx));
- ctx.pConfig = p->pConfig;
+
+ memset(&ctx, 0, sizeof(Fts5IntegrityCtx));
+ ctx.pConfig = p->pConfig;
aTotalSize = (i64*)sqlite3_malloc64(pConfig->nCol*(sizeof(int)+sizeof(i64)));
- if( !aTotalSize ) return SQLITE_NOMEM;
- aColSize = (int*)&aTotalSize[pConfig->nCol];
- memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol);
-
+ if( !aTotalSize ) return SQLITE_NOMEM;
+ aColSize = (int*)&aTotalSize[pConfig->nCol];
+ memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol);
+
bUseCksum = (pConfig->eContent==FTS5_CONTENT_NORMAL
|| (pConfig->eContent==FTS5_CONTENT_EXTERNAL && iArg)
);
@@ -233598,13 +233598,13 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){
while( SQLITE_ROW==sqlite3_step(pScan) ){
int i;
ctx.iRowid = sqlite3_column_int64(pScan, 0);
- ctx.szCol = 0;
+ ctx.szCol = 0;
if( pConfig->bColumnsize ){
rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
}
if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
- rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
- }
+ rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
+ }
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
if( pConfig->abUnindexed[i] ) continue;
ctx.iCol = i;
@@ -233630,16 +233630,16 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){
sqlite3Fts5TermsetFree(ctx.pTermset);
ctx.pTermset = 0;
}
- }
+ }
sqlite3Fts5TermsetFree(ctx.pTermset);
ctx.pTermset = 0;
if( rc!=SQLITE_OK ) break;
- }
+ }
rc2 = sqlite3_reset(pScan);
if( rc==SQLITE_OK ) rc = rc2;
}
-
+
/* Test that the "totals" (sometimes called "averages") record looks Ok */
if( rc==SQLITE_OK ){
int i;
@@ -233647,543 +233647,543 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT;
}
- }
-
+ }
+
/* Check that the %_docsize and %_content tables contain the expected
** number of rows. */
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
i64 nRow = 0;
rc = fts5StorageCount(p, "content", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
- }
+ }
if( rc==SQLITE_OK && pConfig->bColumnsize ){
i64 nRow = 0;
rc = fts5StorageCount(p, "docsize", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
}
- }
-
- /* Pass the expected checksum down to the FTS index module. It will
- ** verify, amongst other things, that it matches the checksum generated by
- ** inspecting the index itself. */
- if( rc==SQLITE_OK ){
+ }
+
+ /* Pass the expected checksum down to the FTS index module. It will
+ ** verify, amongst other things, that it matches the checksum generated by
+ ** inspecting the index itself. */
+ if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum, bUseCksum);
- }
-
- sqlite3_free(aTotalSize);
- return rc;
-}
-
-/*
-** Obtain an SQLite statement handle that may be used to read data from the
-** %_content table.
-*/
-static int sqlite3Fts5StorageStmt(
+ }
+
+ sqlite3_free(aTotalSize);
+ return rc;
+}
+
+/*
+** Obtain an SQLite statement handle that may be used to read data from the
+** %_content table.
+*/
+static int sqlite3Fts5StorageStmt(
Fts5Storage *p,
int eStmt,
sqlite3_stmt **pp,
- char **pzErrMsg
-){
- int rc;
+ char **pzErrMsg
+){
+ int rc;
assert( eStmt==FTS5_STMT_SCAN_ASC
- || eStmt==FTS5_STMT_SCAN_DESC
- || eStmt==FTS5_STMT_LOOKUP
- );
- rc = fts5StorageGetStmt(p, eStmt, pp, pzErrMsg);
- if( rc==SQLITE_OK ){
- assert( p->aStmt[eStmt]==*pp );
- p->aStmt[eStmt] = 0;
- }
- return rc;
-}
-
-/*
-** Release an SQLite statement handle obtained via an earlier call to
-** sqlite3Fts5StorageStmt(). The eStmt parameter passed to this function
-** must match that passed to the sqlite3Fts5StorageStmt() call.
-*/
-static void sqlite3Fts5StorageStmtRelease(
+ || eStmt==FTS5_STMT_SCAN_DESC
+ || eStmt==FTS5_STMT_LOOKUP
+ );
+ rc = fts5StorageGetStmt(p, eStmt, pp, pzErrMsg);
+ if( rc==SQLITE_OK ){
+ assert( p->aStmt[eStmt]==*pp );
+ p->aStmt[eStmt] = 0;
+ }
+ return rc;
+}
+
+/*
+** Release an SQLite statement handle obtained via an earlier call to
+** sqlite3Fts5StorageStmt(). The eStmt parameter passed to this function
+** must match that passed to the sqlite3Fts5StorageStmt() call.
+*/
+static void sqlite3Fts5StorageStmtRelease(
Fts5Storage *p,
int eStmt,
- sqlite3_stmt *pStmt
-){
- assert( eStmt==FTS5_STMT_SCAN_ASC
- || eStmt==FTS5_STMT_SCAN_DESC
- || eStmt==FTS5_STMT_LOOKUP
- );
- if( p->aStmt[eStmt]==0 ){
- sqlite3_reset(pStmt);
- p->aStmt[eStmt] = pStmt;
- }else{
- sqlite3_finalize(pStmt);
- }
-}
-
-static int fts5StorageDecodeSizeArray(
- int *aCol, int nCol, /* Array to populate */
- const u8 *aBlob, int nBlob /* Record to read varints from */
-){
- int i;
- int iOff = 0;
- for(i=0; i<nCol; i++){
- if( iOff>=nBlob ) return 1;
- iOff += fts5GetVarint32(&aBlob[iOff], aCol[i]);
- }
- return (iOff!=nBlob);
-}
-
-/*
-** Argument aCol points to an array of integers containing one entry for
-** each table column. This function reads the %_docsize record for the
-** specified rowid and populates aCol[] with the results.
-**
-** An SQLite error code is returned if an error occurs, or SQLITE_OK
-** otherwise.
-*/
-static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){
- int nCol = p->pConfig->nCol; /* Number of user columns in table */
- sqlite3_stmt *pLookup = 0; /* Statement to query %_docsize */
- int rc; /* Return Code */
-
- assert( p->pConfig->bColumnsize );
- rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
+ sqlite3_stmt *pStmt
+){
+ assert( eStmt==FTS5_STMT_SCAN_ASC
+ || eStmt==FTS5_STMT_SCAN_DESC
+ || eStmt==FTS5_STMT_LOOKUP
+ );
+ if( p->aStmt[eStmt]==0 ){
+ sqlite3_reset(pStmt);
+ p->aStmt[eStmt] = pStmt;
+ }else{
+ sqlite3_finalize(pStmt);
+ }
+}
+
+static int fts5StorageDecodeSizeArray(
+ int *aCol, int nCol, /* Array to populate */
+ const u8 *aBlob, int nBlob /* Record to read varints from */
+){
+ int i;
+ int iOff = 0;
+ for(i=0; i<nCol; i++){
+ if( iOff>=nBlob ) return 1;
+ iOff += fts5GetVarint32(&aBlob[iOff], aCol[i]);
+ }
+ return (iOff!=nBlob);
+}
+
+/*
+** Argument aCol points to an array of integers containing one entry for
+** each table column. This function reads the %_docsize record for the
+** specified rowid and populates aCol[] with the results.
+**
+** An SQLite error code is returned if an error occurs, or SQLITE_OK
+** otherwise.
+*/
+static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){
+ int nCol = p->pConfig->nCol; /* Number of user columns in table */
+ sqlite3_stmt *pLookup = 0; /* Statement to query %_docsize */
+ int rc; /* Return Code */
+
+ assert( p->pConfig->bColumnsize );
+ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
if( pLookup ){
- int bCorrupt = 1;
+ int bCorrupt = 1;
assert( rc==SQLITE_OK );
- sqlite3_bind_int64(pLookup, 1, iRowid);
- if( SQLITE_ROW==sqlite3_step(pLookup) ){
- const u8 *aBlob = sqlite3_column_blob(pLookup, 0);
- int nBlob = sqlite3_column_bytes(pLookup, 0);
- if( 0==fts5StorageDecodeSizeArray(aCol, nCol, aBlob, nBlob) ){
- bCorrupt = 0;
- }
- }
- rc = sqlite3_reset(pLookup);
- if( bCorrupt && rc==SQLITE_OK ){
- rc = FTS5_CORRUPT;
- }
+ sqlite3_bind_int64(pLookup, 1, iRowid);
+ if( SQLITE_ROW==sqlite3_step(pLookup) ){
+ const u8 *aBlob = sqlite3_column_blob(pLookup, 0);
+ int nBlob = sqlite3_column_bytes(pLookup, 0);
+ if( 0==fts5StorageDecodeSizeArray(aCol, nCol, aBlob, nBlob) ){
+ bCorrupt = 0;
+ }
+ }
+ rc = sqlite3_reset(pLookup);
+ if( bCorrupt && rc==SQLITE_OK ){
+ rc = FTS5_CORRUPT;
+ }
}else{
assert( rc!=SQLITE_OK );
- }
-
- return rc;
-}
-
-static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){
- int rc = fts5StorageLoadTotals(p, 0);
- if( rc==SQLITE_OK ){
- *pnToken = 0;
- if( iCol<0 ){
- int i;
- for(i=0; i<p->pConfig->nCol; i++){
- *pnToken += p->aTotalSize[i];
- }
- }else if( iCol<p->pConfig->nCol ){
- *pnToken = p->aTotalSize[iCol];
- }else{
- rc = SQLITE_RANGE;
- }
- }
- return rc;
-}
-
-static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
- int rc = fts5StorageLoadTotals(p, 0);
- if( rc==SQLITE_OK ){
+ }
+
+ return rc;
+}
+
+static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){
+ int rc = fts5StorageLoadTotals(p, 0);
+ if( rc==SQLITE_OK ){
+ *pnToken = 0;
+ if( iCol<0 ){
+ int i;
+ for(i=0; i<p->pConfig->nCol; i++){
+ *pnToken += p->aTotalSize[i];
+ }
+ }else if( iCol<p->pConfig->nCol ){
+ *pnToken = p->aTotalSize[iCol];
+ }else{
+ rc = SQLITE_RANGE;
+ }
+ }
+ return rc;
+}
+
+static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
+ int rc = fts5StorageLoadTotals(p, 0);
+ if( rc==SQLITE_OK ){
/* nTotalRow being zero does not necessarily indicate a corrupt
** database - it might be that the FTS5 table really does contain zero
** rows. However this function is only called from the xRowCount() API,
** and there is no way for that API to be invoked if the table contains
** no rows. Hence the FTS5_CORRUPT return. */
- *pnRow = p->nTotalRow;
+ *pnRow = p->nTotalRow;
if( p->nTotalRow<=0 ) rc = FTS5_CORRUPT;
- }
- return rc;
-}
-
-/*
-** Flush any data currently held in-memory to disk.
-*/
-static int sqlite3Fts5StorageSync(Fts5Storage *p){
- int rc = SQLITE_OK;
- i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
- if( p->bTotalsValid ){
- rc = fts5StorageSaveTotals(p);
- p->bTotalsValid = 0;
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5IndexSync(p->pIndex);
- }
- sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid);
- return rc;
-}
-
-static int sqlite3Fts5StorageRollback(Fts5Storage *p){
- p->bTotalsValid = 0;
- return sqlite3Fts5IndexRollback(p->pIndex);
-}
-
-static int sqlite3Fts5StorageConfigValue(
+ }
+ return rc;
+}
+
+/*
+** Flush any data currently held in-memory to disk.
+*/
+static int sqlite3Fts5StorageSync(Fts5Storage *p){
+ int rc = SQLITE_OK;
+ i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
+ if( p->bTotalsValid ){
+ rc = fts5StorageSaveTotals(p);
+ p->bTotalsValid = 0;
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexSync(p->pIndex);
+ }
+ sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid);
+ return rc;
+}
+
+static int sqlite3Fts5StorageRollback(Fts5Storage *p){
+ p->bTotalsValid = 0;
+ return sqlite3Fts5IndexRollback(p->pIndex);
+}
+
+static int sqlite3Fts5StorageConfigValue(
Fts5Storage *p,
- const char *z,
- sqlite3_value *pVal,
- int iVal
-){
- sqlite3_stmt *pReplace = 0;
- int rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_CONFIG, &pReplace, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_text(pReplace, 1, z, -1, SQLITE_STATIC);
- if( pVal ){
- sqlite3_bind_value(pReplace, 2, pVal);
- }else{
- sqlite3_bind_int(pReplace, 2, iVal);
- }
- sqlite3_step(pReplace);
- rc = sqlite3_reset(pReplace);
+ const char *z,
+ sqlite3_value *pVal,
+ int iVal
+){
+ sqlite3_stmt *pReplace = 0;
+ int rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_CONFIG, &pReplace, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_text(pReplace, 1, z, -1, SQLITE_STATIC);
+ if( pVal ){
+ sqlite3_bind_value(pReplace, 2, pVal);
+ }else{
+ sqlite3_bind_int(pReplace, 2, iVal);
+ }
+ sqlite3_step(pReplace);
+ rc = sqlite3_reset(pReplace);
sqlite3_bind_null(pReplace, 1);
- }
- if( rc==SQLITE_OK && pVal ){
- int iNew = p->pConfig->iCookie + 1;
- rc = sqlite3Fts5IndexSetCookie(p->pIndex, iNew);
- if( rc==SQLITE_OK ){
- p->pConfig->iCookie = iNew;
- }
- }
- return rc;
-}
-
-/*
-** 2014 May 31
-**
-** 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.
-**
-******************************************************************************
-*/
-
-
-/* #include "fts5Int.h" */
-
-/**************************************************************************
-** Start of ascii tokenizer implementation.
-*/
-
-/*
-** For tokenizers with no "unicode" modifier, the set of token characters
+ }
+ if( rc==SQLITE_OK && pVal ){
+ int iNew = p->pConfig->iCookie + 1;
+ rc = sqlite3Fts5IndexSetCookie(p->pIndex, iNew);
+ if( rc==SQLITE_OK ){
+ p->pConfig->iCookie = iNew;
+ }
+ }
+ return rc;
+}
+
+/*
+** 2014 May 31
+**
+** 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.
+**
+******************************************************************************
+*/
+
+
+/* #include "fts5Int.h" */
+
+/**************************************************************************
+** Start of ascii tokenizer implementation.
+*/
+
+/*
+** For tokenizers with no "unicode" modifier, the set of token characters
** is the same as the set of ASCII range alphanumeric characters.
-*/
-static unsigned char aAsciiTokenChar[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00..0x0F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10..0x1F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20..0x2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30..0x3F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40..0x4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50..0x5F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60..0x6F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70..0x7F */
-};
-
-typedef struct AsciiTokenizer AsciiTokenizer;
-struct AsciiTokenizer {
- unsigned char aTokenChar[128];
-};
-
-static void fts5AsciiAddExceptions(
+*/
+static unsigned char aAsciiTokenChar[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00..0x0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10..0x1F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20..0x2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30..0x3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40..0x4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50..0x5F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60..0x6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70..0x7F */
+};
+
+typedef struct AsciiTokenizer AsciiTokenizer;
+struct AsciiTokenizer {
+ unsigned char aTokenChar[128];
+};
+
+static void fts5AsciiAddExceptions(
AsciiTokenizer *p,
const char *zArg,
- int bTokenChars
-){
- int i;
- for(i=0; zArg[i]; i++){
- if( (zArg[i] & 0x80)==0 ){
- p->aTokenChar[(int)zArg[i]] = (unsigned char)bTokenChars;
- }
- }
-}
-
-/*
-** Delete a "ascii" tokenizer.
-*/
-static void fts5AsciiDelete(Fts5Tokenizer *p){
- sqlite3_free(p);
-}
-
-/*
-** Create an "ascii" tokenizer.
-*/
-static int fts5AsciiCreate(
+ int bTokenChars
+){
+ int i;
+ for(i=0; zArg[i]; i++){
+ if( (zArg[i] & 0x80)==0 ){
+ p->aTokenChar[(int)zArg[i]] = (unsigned char)bTokenChars;
+ }
+ }
+}
+
+/*
+** Delete a "ascii" tokenizer.
+*/
+static void fts5AsciiDelete(Fts5Tokenizer *p){
+ sqlite3_free(p);
+}
+
+/*
+** Create an "ascii" tokenizer.
+*/
+static int fts5AsciiCreate(
void *pUnused,
- const char **azArg, int nArg,
- Fts5Tokenizer **ppOut
-){
- int rc = SQLITE_OK;
- AsciiTokenizer *p = 0;
- UNUSED_PARAM(pUnused);
- if( nArg%2 ){
- rc = SQLITE_ERROR;
- }else{
- p = sqlite3_malloc(sizeof(AsciiTokenizer));
- if( p==0 ){
- rc = SQLITE_NOMEM;
- }else{
- int i;
- memset(p, 0, sizeof(AsciiTokenizer));
- memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
- for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
- const char *zArg = azArg[i+1];
- if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
- fts5AsciiAddExceptions(p, zArg, 1);
- }else
- if( 0==sqlite3_stricmp(azArg[i], "separators") ){
- fts5AsciiAddExceptions(p, zArg, 0);
- }else{
- rc = SQLITE_ERROR;
- }
- }
- if( rc!=SQLITE_OK ){
- fts5AsciiDelete((Fts5Tokenizer*)p);
- p = 0;
- }
- }
- }
-
- *ppOut = (Fts5Tokenizer*)p;
- return rc;
-}
-
-
-static void asciiFold(char *aOut, const char *aIn, int nByte){
- int i;
- for(i=0; i<nByte; i++){
- char c = aIn[i];
- if( c>='A' && c<='Z' ) c += 32;
- aOut[i] = c;
- }
-}
-
-/*
-** Tokenize some text using the ascii tokenizer.
-*/
-static int fts5AsciiTokenize(
- Fts5Tokenizer *pTokenizer,
- void *pCtx,
- int iUnused,
- const char *pText, int nText,
- int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
-){
- AsciiTokenizer *p = (AsciiTokenizer*)pTokenizer;
- int rc = SQLITE_OK;
- int ie;
- int is = 0;
-
- char aFold[64];
- int nFold = sizeof(aFold);
- char *pFold = aFold;
- unsigned char *a = p->aTokenChar;
-
- UNUSED_PARAM(iUnused);
-
- while( is<nText && rc==SQLITE_OK ){
- int nByte;
-
- /* Skip any leading divider characters. */
- while( is<nText && ((pText[is]&0x80)==0 && a[(int)pText[is]]==0) ){
- is++;
- }
- if( is==nText ) break;
-
- /* Count the token characters */
- ie = is+1;
- while( ie<nText && ((pText[ie]&0x80) || a[(int)pText[ie]] ) ){
- ie++;
- }
-
- /* Fold to lower case */
- nByte = ie-is;
- if( nByte>nFold ){
- if( pFold!=aFold ) sqlite3_free(pFold);
+ const char **azArg, int nArg,
+ Fts5Tokenizer **ppOut
+){
+ int rc = SQLITE_OK;
+ AsciiTokenizer *p = 0;
+ UNUSED_PARAM(pUnused);
+ if( nArg%2 ){
+ rc = SQLITE_ERROR;
+ }else{
+ p = sqlite3_malloc(sizeof(AsciiTokenizer));
+ if( p==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ int i;
+ memset(p, 0, sizeof(AsciiTokenizer));
+ memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
+ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
+ const char *zArg = azArg[i+1];
+ if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
+ fts5AsciiAddExceptions(p, zArg, 1);
+ }else
+ if( 0==sqlite3_stricmp(azArg[i], "separators") ){
+ fts5AsciiAddExceptions(p, zArg, 0);
+ }else{
+ rc = SQLITE_ERROR;
+ }
+ }
+ if( rc!=SQLITE_OK ){
+ fts5AsciiDelete((Fts5Tokenizer*)p);
+ p = 0;
+ }
+ }
+ }
+
+ *ppOut = (Fts5Tokenizer*)p;
+ return rc;
+}
+
+
+static void asciiFold(char *aOut, const char *aIn, int nByte){
+ int i;
+ for(i=0; i<nByte; i++){
+ char c = aIn[i];
+ if( c>='A' && c<='Z' ) c += 32;
+ aOut[i] = c;
+ }
+}
+
+/*
+** Tokenize some text using the ascii tokenizer.
+*/
+static int fts5AsciiTokenize(
+ Fts5Tokenizer *pTokenizer,
+ void *pCtx,
+ int iUnused,
+ const char *pText, int nText,
+ int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
+){
+ AsciiTokenizer *p = (AsciiTokenizer*)pTokenizer;
+ int rc = SQLITE_OK;
+ int ie;
+ int is = 0;
+
+ char aFold[64];
+ int nFold = sizeof(aFold);
+ char *pFold = aFold;
+ unsigned char *a = p->aTokenChar;
+
+ UNUSED_PARAM(iUnused);
+
+ while( is<nText && rc==SQLITE_OK ){
+ int nByte;
+
+ /* Skip any leading divider characters. */
+ while( is<nText && ((pText[is]&0x80)==0 && a[(int)pText[is]]==0) ){
+ is++;
+ }
+ if( is==nText ) break;
+
+ /* Count the token characters */
+ ie = is+1;
+ while( ie<nText && ((pText[ie]&0x80) || a[(int)pText[ie]] ) ){
+ ie++;
+ }
+
+ /* Fold to lower case */
+ nByte = ie-is;
+ if( nByte>nFold ){
+ if( pFold!=aFold ) sqlite3_free(pFold);
pFold = sqlite3_malloc64((sqlite3_int64)nByte*2);
- if( pFold==0 ){
- rc = SQLITE_NOMEM;
- break;
- }
- nFold = nByte*2;
- }
- asciiFold(pFold, &pText[is], nByte);
-
- /* Invoke the token callback */
- rc = xToken(pCtx, 0, pFold, nByte, is, ie);
- is = ie+1;
- }
-
- if( pFold!=aFold ) sqlite3_free(pFold);
- if( rc==SQLITE_DONE ) rc = SQLITE_OK;
- return rc;
-}
-
-/**************************************************************************
-** Start of unicode61 tokenizer implementation.
-*/
-
-
-/*
-** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied
-** from the sqlite3 source file utf.c. If this file is compiled as part
-** of the amalgamation, they are not required.
-*/
-#ifndef SQLITE_AMALGAMATION
-
-static const unsigned char sqlite3Utf8Trans1[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
-};
-
-#define READ_UTF8(zIn, zTerm, c) \
- c = *(zIn++); \
- if( c>=0xc0 ){ \
- c = sqlite3Utf8Trans1[c-0xc0]; \
- while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
- c = (c<<6) + (0x3f & *(zIn++)); \
- } \
- if( c<0x80 \
- || (c&0xFFFFF800)==0xD800 \
- || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
- }
-
-
-#define WRITE_UTF8(zOut, c) { \
- if( c<0x00080 ){ \
- *zOut++ = (unsigned char)(c&0xFF); \
- } \
- else if( c<0x00800 ){ \
- *zOut++ = 0xC0 + (unsigned char)((c>>6)&0x1F); \
- *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
- } \
- else if( c<0x10000 ){ \
- *zOut++ = 0xE0 + (unsigned char)((c>>12)&0x0F); \
- *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F); \
- *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
- }else{ \
- *zOut++ = 0xF0 + (unsigned char)((c>>18) & 0x07); \
- *zOut++ = 0x80 + (unsigned char)((c>>12) & 0x3F); \
- *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F); \
- *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
- } \
-}
-
-#endif /* ifndef SQLITE_AMALGAMATION */
-
-typedef struct Unicode61Tokenizer Unicode61Tokenizer;
-struct Unicode61Tokenizer {
- unsigned char aTokenChar[128]; /* ASCII range token characters */
- char *aFold; /* Buffer to fold text into */
- int nFold; /* Size of aFold[] in bytes */
+ if( pFold==0 ){
+ rc = SQLITE_NOMEM;
+ break;
+ }
+ nFold = nByte*2;
+ }
+ asciiFold(pFold, &pText[is], nByte);
+
+ /* Invoke the token callback */
+ rc = xToken(pCtx, 0, pFold, nByte, is, ie);
+ is = ie+1;
+ }
+
+ if( pFold!=aFold ) sqlite3_free(pFold);
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ return rc;
+}
+
+/**************************************************************************
+** Start of unicode61 tokenizer implementation.
+*/
+
+
+/*
+** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied
+** from the sqlite3 source file utf.c. If this file is compiled as part
+** of the amalgamation, they are not required.
+*/
+#ifndef SQLITE_AMALGAMATION
+
+static const unsigned char sqlite3Utf8Trans1[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
+};
+
+#define READ_UTF8(zIn, zTerm, c) \
+ c = *(zIn++); \
+ if( c>=0xc0 ){ \
+ c = sqlite3Utf8Trans1[c-0xc0]; \
+ while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
+ c = (c<<6) + (0x3f & *(zIn++)); \
+ } \
+ if( c<0x80 \
+ || (c&0xFFFFF800)==0xD800 \
+ || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
+ }
+
+
+#define WRITE_UTF8(zOut, c) { \
+ if( c<0x00080 ){ \
+ *zOut++ = (unsigned char)(c&0xFF); \
+ } \
+ else if( c<0x00800 ){ \
+ *zOut++ = 0xC0 + (unsigned char)((c>>6)&0x1F); \
+ *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
+ } \
+ else if( c<0x10000 ){ \
+ *zOut++ = 0xE0 + (unsigned char)((c>>12)&0x0F); \
+ *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F); \
+ *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
+ }else{ \
+ *zOut++ = 0xF0 + (unsigned char)((c>>18) & 0x07); \
+ *zOut++ = 0x80 + (unsigned char)((c>>12) & 0x3F); \
+ *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F); \
+ *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
+ } \
+}
+
+#endif /* ifndef SQLITE_AMALGAMATION */
+
+typedef struct Unicode61Tokenizer Unicode61Tokenizer;
+struct Unicode61Tokenizer {
+ unsigned char aTokenChar[128]; /* ASCII range token characters */
+ char *aFold; /* Buffer to fold text into */
+ int nFold; /* Size of aFold[] in bytes */
int eRemoveDiacritic; /* True if remove_diacritics=1 is set */
- int nException;
- int *aiException;
+ int nException;
+ int *aiException;
unsigned char aCategory[32]; /* True for token char categories */
-};
-
+};
+
/* Values for eRemoveDiacritic (must match internals of fts5_unicode2.c) */
#define FTS5_REMOVE_DIACRITICS_NONE 0
#define FTS5_REMOVE_DIACRITICS_SIMPLE 1
#define FTS5_REMOVE_DIACRITICS_COMPLEX 2
-static int fts5UnicodeAddExceptions(
- Unicode61Tokenizer *p, /* Tokenizer object */
- const char *z, /* Characters to treat as exceptions */
- int bTokenChars /* 1 for 'tokenchars', 0 for 'separators' */
-){
- int rc = SQLITE_OK;
- int n = (int)strlen(z);
- int *aNew;
-
- if( n>0 ){
+static int fts5UnicodeAddExceptions(
+ Unicode61Tokenizer *p, /* Tokenizer object */
+ const char *z, /* Characters to treat as exceptions */
+ int bTokenChars /* 1 for 'tokenchars', 0 for 'separators' */
+){
+ int rc = SQLITE_OK;
+ int n = (int)strlen(z);
+ int *aNew;
+
+ if( n>0 ){
aNew = (int*)sqlite3_realloc64(p->aiException,
(n+p->nException)*sizeof(int));
- if( aNew ){
- int nNew = p->nException;
- const unsigned char *zCsr = (const unsigned char*)z;
- const unsigned char *zTerm = (const unsigned char*)&z[n];
- while( zCsr<zTerm ){
+ if( aNew ){
+ int nNew = p->nException;
+ const unsigned char *zCsr = (const unsigned char*)z;
+ const unsigned char *zTerm = (const unsigned char*)&z[n];
+ while( zCsr<zTerm ){
u32 iCode;
- int bToken;
- READ_UTF8(zCsr, zTerm, iCode);
- if( iCode<128 ){
- p->aTokenChar[iCode] = (unsigned char)bTokenChars;
- }else{
+ int bToken;
+ READ_UTF8(zCsr, zTerm, iCode);
+ if( iCode<128 ){
+ p->aTokenChar[iCode] = (unsigned char)bTokenChars;
+ }else{
bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)];
assert( (bToken==0 || bToken==1) );
- assert( (bTokenChars==0 || bTokenChars==1) );
- if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
- int i;
- for(i=0; i<nNew; i++){
+ assert( (bTokenChars==0 || bTokenChars==1) );
+ if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
+ int i;
+ for(i=0; i<nNew; i++){
if( (u32)aNew[i]>iCode ) break;
- }
- memmove(&aNew[i+1], &aNew[i], (nNew-i)*sizeof(int));
- aNew[i] = iCode;
- nNew++;
- }
- }
- }
- p->aiException = aNew;
- p->nException = nNew;
- }else{
- rc = SQLITE_NOMEM;
- }
- }
-
- return rc;
-}
-
-/*
-** Return true if the p->aiException[] array contains the value iCode.
-*/
-static int fts5UnicodeIsException(Unicode61Tokenizer *p, int iCode){
- if( p->nException>0 ){
- int *a = p->aiException;
- int iLo = 0;
- int iHi = p->nException-1;
-
- while( iHi>=iLo ){
- int iTest = (iHi + iLo) / 2;
- if( iCode==a[iTest] ){
- return 1;
- }else if( iCode>a[iTest] ){
- iLo = iTest+1;
- }else{
- iHi = iTest-1;
- }
- }
- }
-
- return 0;
-}
-
-/*
-** Delete a "unicode61" tokenizer.
-*/
-static void fts5UnicodeDelete(Fts5Tokenizer *pTok){
- if( pTok ){
- Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTok;
- sqlite3_free(p->aiException);
- sqlite3_free(p->aFold);
- sqlite3_free(p);
- }
- return;
-}
-
+ }
+ memmove(&aNew[i+1], &aNew[i], (nNew-i)*sizeof(int));
+ aNew[i] = iCode;
+ nNew++;
+ }
+ }
+ }
+ p->aiException = aNew;
+ p->nException = nNew;
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Return true if the p->aiException[] array contains the value iCode.
+*/
+static int fts5UnicodeIsException(Unicode61Tokenizer *p, int iCode){
+ if( p->nException>0 ){
+ int *a = p->aiException;
+ int iLo = 0;
+ int iHi = p->nException-1;
+
+ while( iHi>=iLo ){
+ int iTest = (iHi + iLo) / 2;
+ if( iCode==a[iTest] ){
+ return 1;
+ }else if( iCode>a[iTest] ){
+ iLo = iTest+1;
+ }else{
+ iHi = iTest-1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+** Delete a "unicode61" tokenizer.
+*/
+static void fts5UnicodeDelete(Fts5Tokenizer *pTok){
+ if( pTok ){
+ Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTok;
+ sqlite3_free(p->aiException);
+ sqlite3_free(p->aFold);
+ sqlite3_free(p);
+ }
+ return;
+}
+
static int unicodeSetCategories(Unicode61Tokenizer *p, const char *zCat){
const char *z = zCat;
@@ -234199,37 +234199,37 @@ static int unicodeSetCategories(Unicode61Tokenizer *p, const char *zCat){
return SQLITE_OK;
}
-/*
-** Create a "unicode61" tokenizer.
-*/
-static int fts5UnicodeCreate(
+/*
+** Create a "unicode61" tokenizer.
+*/
+static int fts5UnicodeCreate(
void *pUnused,
- const char **azArg, int nArg,
- Fts5Tokenizer **ppOut
-){
- int rc = SQLITE_OK; /* Return code */
+ const char **azArg, int nArg,
+ Fts5Tokenizer **ppOut
+){
+ int rc = SQLITE_OK; /* Return code */
Unicode61Tokenizer *p = 0; /* New tokenizer object */
-
- UNUSED_PARAM(pUnused);
-
- if( nArg%2 ){
- rc = SQLITE_ERROR;
- }else{
- p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer));
- if( p ){
+
+ UNUSED_PARAM(pUnused);
+
+ if( nArg%2 ){
+ rc = SQLITE_ERROR;
+ }else{
+ p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer));
+ if( p ){
const char *zCat = "L* N* Co";
- int i;
- memset(p, 0, sizeof(Unicode61Tokenizer));
+ int i;
+ memset(p, 0, sizeof(Unicode61Tokenizer));
p->eRemoveDiacritic = FTS5_REMOVE_DIACRITICS_SIMPLE;
- p->nFold = 64;
+ p->nFold = 64;
p->aFold = sqlite3_malloc64(p->nFold * sizeof(char));
- if( p->aFold==0 ){
- rc = SQLITE_NOMEM;
- }
+ if( p->aFold==0 ){
+ rc = SQLITE_NOMEM;
+ }
/* Search for a "categories" argument */
- for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
+ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
if( 0==sqlite3_stricmp(azArg[i], "categories") ){
zCat = azArg[i+1];
}
@@ -234240,878 +234240,878 @@ static int fts5UnicodeCreate(
}
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
- const char *zArg = azArg[i+1];
- if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
+ const char *zArg = azArg[i+1];
+ if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
- rc = SQLITE_ERROR;
+ rc = SQLITE_ERROR;
}else{
p->eRemoveDiacritic = (zArg[0] - '0');
assert( p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_NONE
|| p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_SIMPLE
|| p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_COMPLEX
);
- }
- }else
- if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
- rc = fts5UnicodeAddExceptions(p, zArg, 1);
- }else
- if( 0==sqlite3_stricmp(azArg[i], "separators") ){
- rc = fts5UnicodeAddExceptions(p, zArg, 0);
+ }
+ }else
+ if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
+ rc = fts5UnicodeAddExceptions(p, zArg, 1);
+ }else
+ if( 0==sqlite3_stricmp(azArg[i], "separators") ){
+ rc = fts5UnicodeAddExceptions(p, zArg, 0);
}else
if( 0==sqlite3_stricmp(azArg[i], "categories") ){
/* no-op */
- }else{
- rc = SQLITE_ERROR;
- }
- }
-
- }else{
- rc = SQLITE_NOMEM;
- }
- if( rc!=SQLITE_OK ){
- fts5UnicodeDelete((Fts5Tokenizer*)p);
- p = 0;
- }
- *ppOut = (Fts5Tokenizer*)p;
- }
- return rc;
-}
-
-/*
-** Return true if, for the purposes of tokenizing with the tokenizer
+ }else{
+ rc = SQLITE_ERROR;
+ }
+ }
+
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ if( rc!=SQLITE_OK ){
+ fts5UnicodeDelete((Fts5Tokenizer*)p);
+ p = 0;
+ }
+ *ppOut = (Fts5Tokenizer*)p;
+ }
+ return rc;
+}
+
+/*
+** Return true if, for the purposes of tokenizing with the tokenizer
** passed as the first argument, codepoint iCode is considered a token
-** character (not a separator).
-*/
-static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
+** character (not a separator).
+*/
+static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
return (
p->aCategory[sqlite3Fts5UnicodeCategory((u32)iCode)]
^ fts5UnicodeIsException(p, iCode)
);
-}
-
-static int fts5UnicodeTokenize(
- Fts5Tokenizer *pTokenizer,
- void *pCtx,
- int iUnused,
- const char *pText, int nText,
- int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
-){
- Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTokenizer;
- int rc = SQLITE_OK;
- unsigned char *a = p->aTokenChar;
-
- unsigned char *zTerm = (unsigned char*)&pText[nText];
- unsigned char *zCsr = (unsigned char *)pText;
-
- /* Output buffer */
- char *aFold = p->aFold;
- int nFold = p->nFold;
- const char *pEnd = &aFold[nFold-6];
-
- UNUSED_PARAM(iUnused);
-
- /* Each iteration of this loop gobbles up a contiguous run of separators,
- ** then the next token. */
- while( rc==SQLITE_OK ){
+}
+
+static int fts5UnicodeTokenize(
+ Fts5Tokenizer *pTokenizer,
+ void *pCtx,
+ int iUnused,
+ const char *pText, int nText,
+ int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
+){
+ Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTokenizer;
+ int rc = SQLITE_OK;
+ unsigned char *a = p->aTokenChar;
+
+ unsigned char *zTerm = (unsigned char*)&pText[nText];
+ unsigned char *zCsr = (unsigned char *)pText;
+
+ /* Output buffer */
+ char *aFold = p->aFold;
+ int nFold = p->nFold;
+ const char *pEnd = &aFold[nFold-6];
+
+ UNUSED_PARAM(iUnused);
+
+ /* Each iteration of this loop gobbles up a contiguous run of separators,
+ ** then the next token. */
+ while( rc==SQLITE_OK ){
u32 iCode; /* non-ASCII codepoint read from input */
- char *zOut = aFold;
- int is;
- int ie;
-
- /* Skip any separator characters. */
- while( 1 ){
- if( zCsr>=zTerm ) goto tokenize_done;
- if( *zCsr & 0x80 ) {
- /* A character outside of the ascii range. Skip past it if it is
- ** a separator character. Or break out of the loop if it is not. */
- is = zCsr - (unsigned char*)pText;
- READ_UTF8(zCsr, zTerm, iCode);
- if( fts5UnicodeIsAlnum(p, iCode) ){
- goto non_ascii_tokenchar;
- }
- }else{
- if( a[*zCsr] ){
- is = zCsr - (unsigned char*)pText;
- goto ascii_tokenchar;
- }
- zCsr++;
- }
- }
-
- /* Run through the tokenchars. Fold them into the output buffer along
- ** the way. */
- while( zCsr<zTerm ){
-
- /* Grow the output buffer so that there is sufficient space to fit the
- ** largest possible utf-8 character. */
- if( zOut>pEnd ){
+ char *zOut = aFold;
+ int is;
+ int ie;
+
+ /* Skip any separator characters. */
+ while( 1 ){
+ if( zCsr>=zTerm ) goto tokenize_done;
+ if( *zCsr & 0x80 ) {
+ /* A character outside of the ascii range. Skip past it if it is
+ ** a separator character. Or break out of the loop if it is not. */
+ is = zCsr - (unsigned char*)pText;
+ READ_UTF8(zCsr, zTerm, iCode);
+ if( fts5UnicodeIsAlnum(p, iCode) ){
+ goto non_ascii_tokenchar;
+ }
+ }else{
+ if( a[*zCsr] ){
+ is = zCsr - (unsigned char*)pText;
+ goto ascii_tokenchar;
+ }
+ zCsr++;
+ }
+ }
+
+ /* Run through the tokenchars. Fold them into the output buffer along
+ ** the way. */
+ while( zCsr<zTerm ){
+
+ /* Grow the output buffer so that there is sufficient space to fit the
+ ** largest possible utf-8 character. */
+ if( zOut>pEnd ){
aFold = sqlite3_malloc64((sqlite3_int64)nFold*2);
- if( aFold==0 ){
- rc = SQLITE_NOMEM;
- goto tokenize_done;
- }
- zOut = &aFold[zOut - p->aFold];
- memcpy(aFold, p->aFold, nFold);
- sqlite3_free(p->aFold);
- p->aFold = aFold;
- p->nFold = nFold = nFold*2;
- pEnd = &aFold[nFold-6];
- }
-
- if( *zCsr & 0x80 ){
- /* An non-ascii-range character. Fold it into the output buffer if
- ** it is a token character, or break out of the loop if it is not. */
- READ_UTF8(zCsr, zTerm, iCode);
- if( fts5UnicodeIsAlnum(p,iCode)||sqlite3Fts5UnicodeIsdiacritic(iCode) ){
- non_ascii_tokenchar:
+ if( aFold==0 ){
+ rc = SQLITE_NOMEM;
+ goto tokenize_done;
+ }
+ zOut = &aFold[zOut - p->aFold];
+ memcpy(aFold, p->aFold, nFold);
+ sqlite3_free(p->aFold);
+ p->aFold = aFold;
+ p->nFold = nFold = nFold*2;
+ pEnd = &aFold[nFold-6];
+ }
+
+ if( *zCsr & 0x80 ){
+ /* An non-ascii-range character. Fold it into the output buffer if
+ ** it is a token character, or break out of the loop if it is not. */
+ READ_UTF8(zCsr, zTerm, iCode);
+ if( fts5UnicodeIsAlnum(p,iCode)||sqlite3Fts5UnicodeIsdiacritic(iCode) ){
+ non_ascii_tokenchar:
iCode = sqlite3Fts5UnicodeFold(iCode, p->eRemoveDiacritic);
- if( iCode ) WRITE_UTF8(zOut, iCode);
- }else{
- break;
- }
- }else if( a[*zCsr]==0 ){
- /* An ascii-range separator character. End of token. */
- break;
- }else{
- ascii_tokenchar:
- if( *zCsr>='A' && *zCsr<='Z' ){
- *zOut++ = *zCsr + 32;
- }else{
- *zOut++ = *zCsr;
- }
- zCsr++;
- }
- ie = zCsr - (unsigned char*)pText;
- }
-
- /* Invoke the token callback */
+ if( iCode ) WRITE_UTF8(zOut, iCode);
+ }else{
+ break;
+ }
+ }else if( a[*zCsr]==0 ){
+ /* An ascii-range separator character. End of token. */
+ break;
+ }else{
+ ascii_tokenchar:
+ if( *zCsr>='A' && *zCsr<='Z' ){
+ *zOut++ = *zCsr + 32;
+ }else{
+ *zOut++ = *zCsr;
+ }
+ zCsr++;
+ }
+ ie = zCsr - (unsigned char*)pText;
+ }
+
+ /* Invoke the token callback */
rc = xToken(pCtx, 0, aFold, zOut-aFold, is, ie);
- }
-
- tokenize_done:
- if( rc==SQLITE_DONE ) rc = SQLITE_OK;
- return rc;
-}
-
-/**************************************************************************
-** Start of porter stemmer implementation.
-*/
-
-/* Any tokens larger than this (in bytes) are passed through without
-** stemming. */
-#define FTS5_PORTER_MAX_TOKEN 64
-
-typedef struct PorterTokenizer PorterTokenizer;
-struct PorterTokenizer {
- fts5_tokenizer tokenizer; /* Parent tokenizer module */
- Fts5Tokenizer *pTokenizer; /* Parent tokenizer instance */
- char aBuf[FTS5_PORTER_MAX_TOKEN + 64];
-};
-
-/*
-** Delete a "porter" tokenizer.
-*/
-static void fts5PorterDelete(Fts5Tokenizer *pTok){
- if( pTok ){
- PorterTokenizer *p = (PorterTokenizer*)pTok;
- if( p->pTokenizer ){
- p->tokenizer.xDelete(p->pTokenizer);
- }
- sqlite3_free(p);
- }
-}
-
-/*
-** Create a "porter" tokenizer.
-*/
-static int fts5PorterCreate(
+ }
+
+ tokenize_done:
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ return rc;
+}
+
+/**************************************************************************
+** Start of porter stemmer implementation.
+*/
+
+/* Any tokens larger than this (in bytes) are passed through without
+** stemming. */
+#define FTS5_PORTER_MAX_TOKEN 64
+
+typedef struct PorterTokenizer PorterTokenizer;
+struct PorterTokenizer {
+ fts5_tokenizer tokenizer; /* Parent tokenizer module */
+ Fts5Tokenizer *pTokenizer; /* Parent tokenizer instance */
+ char aBuf[FTS5_PORTER_MAX_TOKEN + 64];
+};
+
+/*
+** Delete a "porter" tokenizer.
+*/
+static void fts5PorterDelete(Fts5Tokenizer *pTok){
+ if( pTok ){
+ PorterTokenizer *p = (PorterTokenizer*)pTok;
+ if( p->pTokenizer ){
+ p->tokenizer.xDelete(p->pTokenizer);
+ }
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Create a "porter" tokenizer.
+*/
+static int fts5PorterCreate(
void *pCtx,
- const char **azArg, int nArg,
- Fts5Tokenizer **ppOut
-){
- fts5_api *pApi = (fts5_api*)pCtx;
- int rc = SQLITE_OK;
- PorterTokenizer *pRet;
- void *pUserdata = 0;
- const char *zBase = "unicode61";
-
- if( nArg>0 ){
- zBase = azArg[0];
- }
-
- pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer));
- if( pRet ){
- memset(pRet, 0, sizeof(PorterTokenizer));
- rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer);
- }else{
- rc = SQLITE_NOMEM;
- }
- if( rc==SQLITE_OK ){
- int nArg2 = (nArg>0 ? nArg-1 : 0);
- const char **azArg2 = (nArg2 ? &azArg[1] : 0);
- rc = pRet->tokenizer.xCreate(pUserdata, azArg2, nArg2, &pRet->pTokenizer);
- }
-
- if( rc!=SQLITE_OK ){
- fts5PorterDelete((Fts5Tokenizer*)pRet);
- pRet = 0;
- }
- *ppOut = (Fts5Tokenizer*)pRet;
- return rc;
-}
-
-typedef struct PorterContext PorterContext;
-struct PorterContext {
- void *pCtx;
- int (*xToken)(void*, int, const char*, int, int, int);
- char *aBuf;
-};
-
-typedef struct PorterRule PorterRule;
-struct PorterRule {
- const char *zSuffix;
- int nSuffix;
- int (*xCond)(char *zStem, int nStem);
- const char *zOutput;
- int nOutput;
-};
-
-#if 0
-static int fts5PorterApply(char *aBuf, int *pnBuf, PorterRule *aRule){
- int ret = -1;
- int nBuf = *pnBuf;
- PorterRule *p;
-
- for(p=aRule; p->zSuffix; p++){
- assert( strlen(p->zSuffix)==p->nSuffix );
- assert( strlen(p->zOutput)==p->nOutput );
- if( nBuf<p->nSuffix ) continue;
- if( 0==memcmp(&aBuf[nBuf - p->nSuffix], p->zSuffix, p->nSuffix) ) break;
- }
-
- if( p->zSuffix ){
- int nStem = nBuf - p->nSuffix;
- if( p->xCond==0 || p->xCond(aBuf, nStem) ){
- memcpy(&aBuf[nStem], p->zOutput, p->nOutput);
- *pnBuf = nStem + p->nOutput;
- ret = p - aRule;
- }
- }
-
- return ret;
-}
-#endif
-
-static int fts5PorterIsVowel(char c, int bYIsVowel){
- return (
- c=='a' || c=='e' || c=='i' || c=='o' || c=='u' || (bYIsVowel && c=='y')
- );
-}
-
-static int fts5PorterGobbleVC(char *zStem, int nStem, int bPrevCons){
- int i;
- int bCons = bPrevCons;
-
- /* Scan for a vowel */
- for(i=0; i<nStem; i++){
- if( 0==(bCons = !fts5PorterIsVowel(zStem[i], bCons)) ) break;
- }
-
- /* Scan for a consonent */
- for(i++; i<nStem; i++){
- if( (bCons = !fts5PorterIsVowel(zStem[i], bCons)) ) return i+1;
- }
- return 0;
-}
-
-/* porter rule condition: (m > 0) */
-static int fts5Porter_MGt0(char *zStem, int nStem){
- return !!fts5PorterGobbleVC(zStem, nStem, 0);
-}
-
-/* porter rule condition: (m > 1) */
-static int fts5Porter_MGt1(char *zStem, int nStem){
- int n;
- n = fts5PorterGobbleVC(zStem, nStem, 0);
- if( n && fts5PorterGobbleVC(&zStem[n], nStem-n, 1) ){
- return 1;
- }
- return 0;
-}
-
-/* porter rule condition: (m = 1) */
-static int fts5Porter_MEq1(char *zStem, int nStem){
- int n;
- n = fts5PorterGobbleVC(zStem, nStem, 0);
- if( n && 0==fts5PorterGobbleVC(&zStem[n], nStem-n, 1) ){
- return 1;
- }
- return 0;
-}
-
-/* porter rule condition: (*o) */
-static int fts5Porter_Ostar(char *zStem, int nStem){
- if( zStem[nStem-1]=='w' || zStem[nStem-1]=='x' || zStem[nStem-1]=='y' ){
- return 0;
- }else{
- int i;
- int mask = 0;
- int bCons = 0;
- for(i=0; i<nStem; i++){
- bCons = !fts5PorterIsVowel(zStem[i], bCons);
- assert( bCons==0 || bCons==1 );
- mask = (mask << 1) + bCons;
- }
- return ((mask & 0x0007)==0x0005);
- }
-}
-
-/* porter rule condition: (m > 1 and (*S or *T)) */
-static int fts5Porter_MGt1_and_S_or_T(char *zStem, int nStem){
- assert( nStem>0 );
+ const char **azArg, int nArg,
+ Fts5Tokenizer **ppOut
+){
+ fts5_api *pApi = (fts5_api*)pCtx;
+ int rc = SQLITE_OK;
+ PorterTokenizer *pRet;
+ void *pUserdata = 0;
+ const char *zBase = "unicode61";
+
+ if( nArg>0 ){
+ zBase = azArg[0];
+ }
+
+ pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer));
+ if( pRet ){
+ memset(pRet, 0, sizeof(PorterTokenizer));
+ rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer);
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ if( rc==SQLITE_OK ){
+ int nArg2 = (nArg>0 ? nArg-1 : 0);
+ const char **azArg2 = (nArg2 ? &azArg[1] : 0);
+ rc = pRet->tokenizer.xCreate(pUserdata, azArg2, nArg2, &pRet->pTokenizer);
+ }
+
+ if( rc!=SQLITE_OK ){
+ fts5PorterDelete((Fts5Tokenizer*)pRet);
+ pRet = 0;
+ }
+ *ppOut = (Fts5Tokenizer*)pRet;
+ return rc;
+}
+
+typedef struct PorterContext PorterContext;
+struct PorterContext {
+ void *pCtx;
+ int (*xToken)(void*, int, const char*, int, int, int);
+ char *aBuf;
+};
+
+typedef struct PorterRule PorterRule;
+struct PorterRule {
+ const char *zSuffix;
+ int nSuffix;
+ int (*xCond)(char *zStem, int nStem);
+ const char *zOutput;
+ int nOutput;
+};
+
+#if 0
+static int fts5PorterApply(char *aBuf, int *pnBuf, PorterRule *aRule){
+ int ret = -1;
+ int nBuf = *pnBuf;
+ PorterRule *p;
+
+ for(p=aRule; p->zSuffix; p++){
+ assert( strlen(p->zSuffix)==p->nSuffix );
+ assert( strlen(p->zOutput)==p->nOutput );
+ if( nBuf<p->nSuffix ) continue;
+ if( 0==memcmp(&aBuf[nBuf - p->nSuffix], p->zSuffix, p->nSuffix) ) break;
+ }
+
+ if( p->zSuffix ){
+ int nStem = nBuf - p->nSuffix;
+ if( p->xCond==0 || p->xCond(aBuf, nStem) ){
+ memcpy(&aBuf[nStem], p->zOutput, p->nOutput);
+ *pnBuf = nStem + p->nOutput;
+ ret = p - aRule;
+ }
+ }
+
+ return ret;
+}
+#endif
+
+static int fts5PorterIsVowel(char c, int bYIsVowel){
+ return (
+ c=='a' || c=='e' || c=='i' || c=='o' || c=='u' || (bYIsVowel && c=='y')
+ );
+}
+
+static int fts5PorterGobbleVC(char *zStem, int nStem, int bPrevCons){
+ int i;
+ int bCons = bPrevCons;
+
+ /* Scan for a vowel */
+ for(i=0; i<nStem; i++){
+ if( 0==(bCons = !fts5PorterIsVowel(zStem[i], bCons)) ) break;
+ }
+
+ /* Scan for a consonent */
+ for(i++; i<nStem; i++){
+ if( (bCons = !fts5PorterIsVowel(zStem[i], bCons)) ) return i+1;
+ }
+ return 0;
+}
+
+/* porter rule condition: (m > 0) */
+static int fts5Porter_MGt0(char *zStem, int nStem){
+ return !!fts5PorterGobbleVC(zStem, nStem, 0);
+}
+
+/* porter rule condition: (m > 1) */
+static int fts5Porter_MGt1(char *zStem, int nStem){
+ int n;
+ n = fts5PorterGobbleVC(zStem, nStem, 0);
+ if( n && fts5PorterGobbleVC(&zStem[n], nStem-n, 1) ){
+ return 1;
+ }
+ return 0;
+}
+
+/* porter rule condition: (m = 1) */
+static int fts5Porter_MEq1(char *zStem, int nStem){
+ int n;
+ n = fts5PorterGobbleVC(zStem, nStem, 0);
+ if( n && 0==fts5PorterGobbleVC(&zStem[n], nStem-n, 1) ){
+ return 1;
+ }
+ return 0;
+}
+
+/* porter rule condition: (*o) */
+static int fts5Porter_Ostar(char *zStem, int nStem){
+ if( zStem[nStem-1]=='w' || zStem[nStem-1]=='x' || zStem[nStem-1]=='y' ){
+ return 0;
+ }else{
+ int i;
+ int mask = 0;
+ int bCons = 0;
+ for(i=0; i<nStem; i++){
+ bCons = !fts5PorterIsVowel(zStem[i], bCons);
+ assert( bCons==0 || bCons==1 );
+ mask = (mask << 1) + bCons;
+ }
+ return ((mask & 0x0007)==0x0005);
+ }
+}
+
+/* porter rule condition: (m > 1 and (*S or *T)) */
+static int fts5Porter_MGt1_and_S_or_T(char *zStem, int nStem){
+ assert( nStem>0 );
return (zStem[nStem-1]=='s' || zStem[nStem-1]=='t')
- && fts5Porter_MGt1(zStem, nStem);
-}
-
-/* porter rule condition: (*v*) */
-static int fts5Porter_Vowel(char *zStem, int nStem){
- int i;
- for(i=0; i<nStem; i++){
- if( fts5PorterIsVowel(zStem[i], i>0) ){
- return 1;
- }
- }
- return 0;
-}
-
-
-/**************************************************************************
-***************************************************************************
-** GENERATED CODE STARTS HERE (mkportersteps.tcl)
-*/
-
-static int fts5PorterStep4(char *aBuf, int *pnBuf){
- int ret = 0;
- int nBuf = *pnBuf;
- switch( aBuf[nBuf-2] ){
+ && fts5Porter_MGt1(zStem, nStem);
+}
+
+/* porter rule condition: (*v*) */
+static int fts5Porter_Vowel(char *zStem, int nStem){
+ int i;
+ for(i=0; i<nStem; i++){
+ if( fts5PorterIsVowel(zStem[i], i>0) ){
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+***************************************************************************
+** GENERATED CODE STARTS HERE (mkportersteps.tcl)
+*/
+
+static int fts5PorterStep4(char *aBuf, int *pnBuf){
+ int ret = 0;
+ int nBuf = *pnBuf;
+ switch( aBuf[nBuf-2] ){
case 'a':
- if( nBuf>2 && 0==memcmp("al", &aBuf[nBuf-2], 2) ){
- if( fts5Porter_MGt1(aBuf, nBuf-2) ){
- *pnBuf = nBuf - 2;
- }
- }
- break;
+ if( nBuf>2 && 0==memcmp("al", &aBuf[nBuf-2], 2) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-2) ){
+ *pnBuf = nBuf - 2;
+ }
+ }
+ break;
case 'c':
- if( nBuf>4 && 0==memcmp("ance", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt1(aBuf, nBuf-4) ){
- *pnBuf = nBuf - 4;
- }
- }else if( nBuf>4 && 0==memcmp("ence", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt1(aBuf, nBuf-4) ){
- *pnBuf = nBuf - 4;
- }
- }
- break;
+ if( nBuf>4 && 0==memcmp("ance", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }else if( nBuf>4 && 0==memcmp("ence", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }
+ break;
case 'e':
- if( nBuf>2 && 0==memcmp("er", &aBuf[nBuf-2], 2) ){
- if( fts5Porter_MGt1(aBuf, nBuf-2) ){
- *pnBuf = nBuf - 2;
- }
- }
- break;
+ if( nBuf>2 && 0==memcmp("er", &aBuf[nBuf-2], 2) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-2) ){
+ *pnBuf = nBuf - 2;
+ }
+ }
+ break;
case 'i':
- if( nBuf>2 && 0==memcmp("ic", &aBuf[nBuf-2], 2) ){
- if( fts5Porter_MGt1(aBuf, nBuf-2) ){
- *pnBuf = nBuf - 2;
- }
- }
- break;
+ if( nBuf>2 && 0==memcmp("ic", &aBuf[nBuf-2], 2) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-2) ){
+ *pnBuf = nBuf - 2;
+ }
+ }
+ break;
case 'l':
- if( nBuf>4 && 0==memcmp("able", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt1(aBuf, nBuf-4) ){
- *pnBuf = nBuf - 4;
- }
- }else if( nBuf>4 && 0==memcmp("ible", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt1(aBuf, nBuf-4) ){
- *pnBuf = nBuf - 4;
- }
- }
- break;
+ if( nBuf>4 && 0==memcmp("able", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }else if( nBuf>4 && 0==memcmp("ible", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }
+ break;
case 'n':
- if( nBuf>3 && 0==memcmp("ant", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt1(aBuf, nBuf-3) ){
- *pnBuf = nBuf - 3;
- }
- }else if( nBuf>5 && 0==memcmp("ement", &aBuf[nBuf-5], 5) ){
- if( fts5Porter_MGt1(aBuf, nBuf-5) ){
- *pnBuf = nBuf - 5;
- }
- }else if( nBuf>4 && 0==memcmp("ment", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt1(aBuf, nBuf-4) ){
- *pnBuf = nBuf - 4;
- }
- }else if( nBuf>3 && 0==memcmp("ent", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt1(aBuf, nBuf-3) ){
- *pnBuf = nBuf - 3;
- }
- }
- break;
+ if( nBuf>3 && 0==memcmp("ant", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }else if( nBuf>5 && 0==memcmp("ement", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-5) ){
+ *pnBuf = nBuf - 5;
+ }
+ }else if( nBuf>4 && 0==memcmp("ment", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }else if( nBuf>3 && 0==memcmp("ent", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
case 'o':
- if( nBuf>3 && 0==memcmp("ion", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt1_and_S_or_T(aBuf, nBuf-3) ){
- *pnBuf = nBuf - 3;
- }
- }else if( nBuf>2 && 0==memcmp("ou", &aBuf[nBuf-2], 2) ){
- if( fts5Porter_MGt1(aBuf, nBuf-2) ){
- *pnBuf = nBuf - 2;
- }
- }
- break;
+ if( nBuf>3 && 0==memcmp("ion", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1_and_S_or_T(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }else if( nBuf>2 && 0==memcmp("ou", &aBuf[nBuf-2], 2) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-2) ){
+ *pnBuf = nBuf - 2;
+ }
+ }
+ break;
case 's':
- if( nBuf>3 && 0==memcmp("ism", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt1(aBuf, nBuf-3) ){
- *pnBuf = nBuf - 3;
- }
- }
- break;
+ if( nBuf>3 && 0==memcmp("ism", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
case 't':
- if( nBuf>3 && 0==memcmp("ate", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt1(aBuf, nBuf-3) ){
- *pnBuf = nBuf - 3;
- }
- }else if( nBuf>3 && 0==memcmp("iti", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt1(aBuf, nBuf-3) ){
- *pnBuf = nBuf - 3;
- }
- }
- break;
+ if( nBuf>3 && 0==memcmp("ate", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }else if( nBuf>3 && 0==memcmp("iti", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
case 'u':
- if( nBuf>3 && 0==memcmp("ous", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt1(aBuf, nBuf-3) ){
- *pnBuf = nBuf - 3;
- }
- }
- break;
+ if( nBuf>3 && 0==memcmp("ous", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
case 'v':
- if( nBuf>3 && 0==memcmp("ive", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt1(aBuf, nBuf-3) ){
- *pnBuf = nBuf - 3;
- }
- }
- break;
+ if( nBuf>3 && 0==memcmp("ive", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
case 'z':
- if( nBuf>3 && 0==memcmp("ize", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt1(aBuf, nBuf-3) ){
- *pnBuf = nBuf - 3;
- }
- }
- break;
-
- }
- return ret;
-}
-
-
-static int fts5PorterStep1B2(char *aBuf, int *pnBuf){
- int ret = 0;
- int nBuf = *pnBuf;
- switch( aBuf[nBuf-2] ){
+ if( nBuf>3 && 0==memcmp("ize", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
+
+ }
+ return ret;
+}
+
+
+static int fts5PorterStep1B2(char *aBuf, int *pnBuf){
+ int ret = 0;
+ int nBuf = *pnBuf;
+ switch( aBuf[nBuf-2] ){
case 'a':
- if( nBuf>2 && 0==memcmp("at", &aBuf[nBuf-2], 2) ){
- memcpy(&aBuf[nBuf-2], "ate", 3);
- *pnBuf = nBuf - 2 + 3;
- ret = 1;
- }
- break;
+ if( nBuf>2 && 0==memcmp("at", &aBuf[nBuf-2], 2) ){
+ memcpy(&aBuf[nBuf-2], "ate", 3);
+ *pnBuf = nBuf - 2 + 3;
+ ret = 1;
+ }
+ break;
case 'b':
- if( nBuf>2 && 0==memcmp("bl", &aBuf[nBuf-2], 2) ){
- memcpy(&aBuf[nBuf-2], "ble", 3);
- *pnBuf = nBuf - 2 + 3;
- ret = 1;
- }
- break;
+ if( nBuf>2 && 0==memcmp("bl", &aBuf[nBuf-2], 2) ){
+ memcpy(&aBuf[nBuf-2], "ble", 3);
+ *pnBuf = nBuf - 2 + 3;
+ ret = 1;
+ }
+ break;
case 'i':
- if( nBuf>2 && 0==memcmp("iz", &aBuf[nBuf-2], 2) ){
- memcpy(&aBuf[nBuf-2], "ize", 3);
- *pnBuf = nBuf - 2 + 3;
- ret = 1;
- }
- break;
-
- }
- return ret;
-}
-
-
-static int fts5PorterStep2(char *aBuf, int *pnBuf){
- int ret = 0;
- int nBuf = *pnBuf;
- switch( aBuf[nBuf-2] ){
+ if( nBuf>2 && 0==memcmp("iz", &aBuf[nBuf-2], 2) ){
+ memcpy(&aBuf[nBuf-2], "ize", 3);
+ *pnBuf = nBuf - 2 + 3;
+ ret = 1;
+ }
+ break;
+
+ }
+ return ret;
+}
+
+
+static int fts5PorterStep2(char *aBuf, int *pnBuf){
+ int ret = 0;
+ int nBuf = *pnBuf;
+ switch( aBuf[nBuf-2] ){
case 'a':
- if( nBuf>7 && 0==memcmp("ational", &aBuf[nBuf-7], 7) ){
- if( fts5Porter_MGt0(aBuf, nBuf-7) ){
- memcpy(&aBuf[nBuf-7], "ate", 3);
- *pnBuf = nBuf - 7 + 3;
- }
- }else if( nBuf>6 && 0==memcmp("tional", &aBuf[nBuf-6], 6) ){
- if( fts5Porter_MGt0(aBuf, nBuf-6) ){
- memcpy(&aBuf[nBuf-6], "tion", 4);
- *pnBuf = nBuf - 6 + 4;
- }
- }
- break;
+ if( nBuf>7 && 0==memcmp("ational", &aBuf[nBuf-7], 7) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-7) ){
+ memcpy(&aBuf[nBuf-7], "ate", 3);
+ *pnBuf = nBuf - 7 + 3;
+ }
+ }else if( nBuf>6 && 0==memcmp("tional", &aBuf[nBuf-6], 6) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-6) ){
+ memcpy(&aBuf[nBuf-6], "tion", 4);
+ *pnBuf = nBuf - 6 + 4;
+ }
+ }
+ break;
case 'c':
- if( nBuf>4 && 0==memcmp("enci", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt0(aBuf, nBuf-4) ){
- memcpy(&aBuf[nBuf-4], "ence", 4);
- *pnBuf = nBuf - 4 + 4;
- }
- }else if( nBuf>4 && 0==memcmp("anci", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt0(aBuf, nBuf-4) ){
- memcpy(&aBuf[nBuf-4], "ance", 4);
- *pnBuf = nBuf - 4 + 4;
- }
- }
- break;
+ if( nBuf>4 && 0==memcmp("enci", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "ence", 4);
+ *pnBuf = nBuf - 4 + 4;
+ }
+ }else if( nBuf>4 && 0==memcmp("anci", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "ance", 4);
+ *pnBuf = nBuf - 4 + 4;
+ }
+ }
+ break;
case 'e':
- if( nBuf>4 && 0==memcmp("izer", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt0(aBuf, nBuf-4) ){
- memcpy(&aBuf[nBuf-4], "ize", 3);
- *pnBuf = nBuf - 4 + 3;
- }
- }
- break;
+ if( nBuf>4 && 0==memcmp("izer", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "ize", 3);
+ *pnBuf = nBuf - 4 + 3;
+ }
+ }
+ break;
case 'g':
- if( nBuf>4 && 0==memcmp("logi", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt0(aBuf, nBuf-4) ){
- memcpy(&aBuf[nBuf-4], "log", 3);
- *pnBuf = nBuf - 4 + 3;
- }
- }
- break;
+ if( nBuf>4 && 0==memcmp("logi", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "log", 3);
+ *pnBuf = nBuf - 4 + 3;
+ }
+ }
+ break;
case 'l':
- if( nBuf>3 && 0==memcmp("bli", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt0(aBuf, nBuf-3) ){
- memcpy(&aBuf[nBuf-3], "ble", 3);
- *pnBuf = nBuf - 3 + 3;
- }
- }else if( nBuf>4 && 0==memcmp("alli", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt0(aBuf, nBuf-4) ){
- memcpy(&aBuf[nBuf-4], "al", 2);
- *pnBuf = nBuf - 4 + 2;
- }
- }else if( nBuf>5 && 0==memcmp("entli", &aBuf[nBuf-5], 5) ){
- if( fts5Porter_MGt0(aBuf, nBuf-5) ){
- memcpy(&aBuf[nBuf-5], "ent", 3);
- *pnBuf = nBuf - 5 + 3;
- }
- }else if( nBuf>3 && 0==memcmp("eli", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt0(aBuf, nBuf-3) ){
- memcpy(&aBuf[nBuf-3], "e", 1);
- *pnBuf = nBuf - 3 + 1;
- }
- }else if( nBuf>5 && 0==memcmp("ousli", &aBuf[nBuf-5], 5) ){
- if( fts5Porter_MGt0(aBuf, nBuf-5) ){
- memcpy(&aBuf[nBuf-5], "ous", 3);
- *pnBuf = nBuf - 5 + 3;
- }
- }
- break;
+ if( nBuf>3 && 0==memcmp("bli", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-3) ){
+ memcpy(&aBuf[nBuf-3], "ble", 3);
+ *pnBuf = nBuf - 3 + 3;
+ }
+ }else if( nBuf>4 && 0==memcmp("alli", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "al", 2);
+ *pnBuf = nBuf - 4 + 2;
+ }
+ }else if( nBuf>5 && 0==memcmp("entli", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ent", 3);
+ *pnBuf = nBuf - 5 + 3;
+ }
+ }else if( nBuf>3 && 0==memcmp("eli", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-3) ){
+ memcpy(&aBuf[nBuf-3], "e", 1);
+ *pnBuf = nBuf - 3 + 1;
+ }
+ }else if( nBuf>5 && 0==memcmp("ousli", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ous", 3);
+ *pnBuf = nBuf - 5 + 3;
+ }
+ }
+ break;
case 'o':
- if( nBuf>7 && 0==memcmp("ization", &aBuf[nBuf-7], 7) ){
- if( fts5Porter_MGt0(aBuf, nBuf-7) ){
- memcpy(&aBuf[nBuf-7], "ize", 3);
- *pnBuf = nBuf - 7 + 3;
- }
- }else if( nBuf>5 && 0==memcmp("ation", &aBuf[nBuf-5], 5) ){
- if( fts5Porter_MGt0(aBuf, nBuf-5) ){
- memcpy(&aBuf[nBuf-5], "ate", 3);
- *pnBuf = nBuf - 5 + 3;
- }
- }else if( nBuf>4 && 0==memcmp("ator", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt0(aBuf, nBuf-4) ){
- memcpy(&aBuf[nBuf-4], "ate", 3);
- *pnBuf = nBuf - 4 + 3;
- }
- }
- break;
+ if( nBuf>7 && 0==memcmp("ization", &aBuf[nBuf-7], 7) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-7) ){
+ memcpy(&aBuf[nBuf-7], "ize", 3);
+ *pnBuf = nBuf - 7 + 3;
+ }
+ }else if( nBuf>5 && 0==memcmp("ation", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ate", 3);
+ *pnBuf = nBuf - 5 + 3;
+ }
+ }else if( nBuf>4 && 0==memcmp("ator", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "ate", 3);
+ *pnBuf = nBuf - 4 + 3;
+ }
+ }
+ break;
case 's':
- if( nBuf>5 && 0==memcmp("alism", &aBuf[nBuf-5], 5) ){
- if( fts5Porter_MGt0(aBuf, nBuf-5) ){
- memcpy(&aBuf[nBuf-5], "al", 2);
- *pnBuf = nBuf - 5 + 2;
- }
- }else if( nBuf>7 && 0==memcmp("iveness", &aBuf[nBuf-7], 7) ){
- if( fts5Porter_MGt0(aBuf, nBuf-7) ){
- memcpy(&aBuf[nBuf-7], "ive", 3);
- *pnBuf = nBuf - 7 + 3;
- }
- }else if( nBuf>7 && 0==memcmp("fulness", &aBuf[nBuf-7], 7) ){
- if( fts5Porter_MGt0(aBuf, nBuf-7) ){
- memcpy(&aBuf[nBuf-7], "ful", 3);
- *pnBuf = nBuf - 7 + 3;
- }
- }else if( nBuf>7 && 0==memcmp("ousness", &aBuf[nBuf-7], 7) ){
- if( fts5Porter_MGt0(aBuf, nBuf-7) ){
- memcpy(&aBuf[nBuf-7], "ous", 3);
- *pnBuf = nBuf - 7 + 3;
- }
- }
- break;
+ if( nBuf>5 && 0==memcmp("alism", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "al", 2);
+ *pnBuf = nBuf - 5 + 2;
+ }
+ }else if( nBuf>7 && 0==memcmp("iveness", &aBuf[nBuf-7], 7) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-7) ){
+ memcpy(&aBuf[nBuf-7], "ive", 3);
+ *pnBuf = nBuf - 7 + 3;
+ }
+ }else if( nBuf>7 && 0==memcmp("fulness", &aBuf[nBuf-7], 7) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-7) ){
+ memcpy(&aBuf[nBuf-7], "ful", 3);
+ *pnBuf = nBuf - 7 + 3;
+ }
+ }else if( nBuf>7 && 0==memcmp("ousness", &aBuf[nBuf-7], 7) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-7) ){
+ memcpy(&aBuf[nBuf-7], "ous", 3);
+ *pnBuf = nBuf - 7 + 3;
+ }
+ }
+ break;
case 't':
- if( nBuf>5 && 0==memcmp("aliti", &aBuf[nBuf-5], 5) ){
- if( fts5Porter_MGt0(aBuf, nBuf-5) ){
- memcpy(&aBuf[nBuf-5], "al", 2);
- *pnBuf = nBuf - 5 + 2;
- }
- }else if( nBuf>5 && 0==memcmp("iviti", &aBuf[nBuf-5], 5) ){
- if( fts5Porter_MGt0(aBuf, nBuf-5) ){
- memcpy(&aBuf[nBuf-5], "ive", 3);
- *pnBuf = nBuf - 5 + 3;
- }
- }else if( nBuf>6 && 0==memcmp("biliti", &aBuf[nBuf-6], 6) ){
- if( fts5Porter_MGt0(aBuf, nBuf-6) ){
- memcpy(&aBuf[nBuf-6], "ble", 3);
- *pnBuf = nBuf - 6 + 3;
- }
- }
- break;
-
- }
- return ret;
-}
-
-
-static int fts5PorterStep3(char *aBuf, int *pnBuf){
- int ret = 0;
- int nBuf = *pnBuf;
- switch( aBuf[nBuf-2] ){
+ if( nBuf>5 && 0==memcmp("aliti", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "al", 2);
+ *pnBuf = nBuf - 5 + 2;
+ }
+ }else if( nBuf>5 && 0==memcmp("iviti", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ive", 3);
+ *pnBuf = nBuf - 5 + 3;
+ }
+ }else if( nBuf>6 && 0==memcmp("biliti", &aBuf[nBuf-6], 6) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-6) ){
+ memcpy(&aBuf[nBuf-6], "ble", 3);
+ *pnBuf = nBuf - 6 + 3;
+ }
+ }
+ break;
+
+ }
+ return ret;
+}
+
+
+static int fts5PorterStep3(char *aBuf, int *pnBuf){
+ int ret = 0;
+ int nBuf = *pnBuf;
+ switch( aBuf[nBuf-2] ){
case 'a':
- if( nBuf>4 && 0==memcmp("ical", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt0(aBuf, nBuf-4) ){
- memcpy(&aBuf[nBuf-4], "ic", 2);
- *pnBuf = nBuf - 4 + 2;
- }
- }
- break;
+ if( nBuf>4 && 0==memcmp("ical", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "ic", 2);
+ *pnBuf = nBuf - 4 + 2;
+ }
+ }
+ break;
case 's':
- if( nBuf>4 && 0==memcmp("ness", &aBuf[nBuf-4], 4) ){
- if( fts5Porter_MGt0(aBuf, nBuf-4) ){
- *pnBuf = nBuf - 4;
- }
- }
- break;
+ if( nBuf>4 && 0==memcmp("ness", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }
+ break;
case 't':
- if( nBuf>5 && 0==memcmp("icate", &aBuf[nBuf-5], 5) ){
- if( fts5Porter_MGt0(aBuf, nBuf-5) ){
- memcpy(&aBuf[nBuf-5], "ic", 2);
- *pnBuf = nBuf - 5 + 2;
- }
- }else if( nBuf>5 && 0==memcmp("iciti", &aBuf[nBuf-5], 5) ){
- if( fts5Porter_MGt0(aBuf, nBuf-5) ){
- memcpy(&aBuf[nBuf-5], "ic", 2);
- *pnBuf = nBuf - 5 + 2;
- }
- }
- break;
+ if( nBuf>5 && 0==memcmp("icate", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ic", 2);
+ *pnBuf = nBuf - 5 + 2;
+ }
+ }else if( nBuf>5 && 0==memcmp("iciti", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ic", 2);
+ *pnBuf = nBuf - 5 + 2;
+ }
+ }
+ break;
case 'u':
- if( nBuf>3 && 0==memcmp("ful", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt0(aBuf, nBuf-3) ){
- *pnBuf = nBuf - 3;
- }
- }
- break;
+ if( nBuf>3 && 0==memcmp("ful", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
case 'v':
- if( nBuf>5 && 0==memcmp("ative", &aBuf[nBuf-5], 5) ){
- if( fts5Porter_MGt0(aBuf, nBuf-5) ){
- *pnBuf = nBuf - 5;
- }
- }
- break;
+ if( nBuf>5 && 0==memcmp("ative", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ *pnBuf = nBuf - 5;
+ }
+ }
+ break;
case 'z':
- if( nBuf>5 && 0==memcmp("alize", &aBuf[nBuf-5], 5) ){
- if( fts5Porter_MGt0(aBuf, nBuf-5) ){
- memcpy(&aBuf[nBuf-5], "al", 2);
- *pnBuf = nBuf - 5 + 2;
- }
- }
- break;
-
- }
- return ret;
-}
-
-
-static int fts5PorterStep1B(char *aBuf, int *pnBuf){
- int ret = 0;
- int nBuf = *pnBuf;
- switch( aBuf[nBuf-2] ){
+ if( nBuf>5 && 0==memcmp("alize", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "al", 2);
+ *pnBuf = nBuf - 5 + 2;
+ }
+ }
+ break;
+
+ }
+ return ret;
+}
+
+
+static int fts5PorterStep1B(char *aBuf, int *pnBuf){
+ int ret = 0;
+ int nBuf = *pnBuf;
+ switch( aBuf[nBuf-2] ){
case 'e':
- if( nBuf>3 && 0==memcmp("eed", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_MGt0(aBuf, nBuf-3) ){
- memcpy(&aBuf[nBuf-3], "ee", 2);
- *pnBuf = nBuf - 3 + 2;
- }
- }else if( nBuf>2 && 0==memcmp("ed", &aBuf[nBuf-2], 2) ){
- if( fts5Porter_Vowel(aBuf, nBuf-2) ){
- *pnBuf = nBuf - 2;
- ret = 1;
- }
- }
- break;
+ if( nBuf>3 && 0==memcmp("eed", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-3) ){
+ memcpy(&aBuf[nBuf-3], "ee", 2);
+ *pnBuf = nBuf - 3 + 2;
+ }
+ }else if( nBuf>2 && 0==memcmp("ed", &aBuf[nBuf-2], 2) ){
+ if( fts5Porter_Vowel(aBuf, nBuf-2) ){
+ *pnBuf = nBuf - 2;
+ ret = 1;
+ }
+ }
+ break;
case 'n':
- if( nBuf>3 && 0==memcmp("ing", &aBuf[nBuf-3], 3) ){
- if( fts5Porter_Vowel(aBuf, nBuf-3) ){
- *pnBuf = nBuf - 3;
- ret = 1;
- }
- }
- break;
-
- }
- return ret;
-}
-
-/*
-** GENERATED CODE ENDS HERE (mkportersteps.tcl)
-***************************************************************************
-**************************************************************************/
-
-static void fts5PorterStep1A(char *aBuf, int *pnBuf){
- int nBuf = *pnBuf;
- if( aBuf[nBuf-1]=='s' ){
- if( aBuf[nBuf-2]=='e' ){
+ if( nBuf>3 && 0==memcmp("ing", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_Vowel(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ ret = 1;
+ }
+ }
+ break;
+
+ }
+ return ret;
+}
+
+/*
+** GENERATED CODE ENDS HERE (mkportersteps.tcl)
+***************************************************************************
+**************************************************************************/
+
+static void fts5PorterStep1A(char *aBuf, int *pnBuf){
+ int nBuf = *pnBuf;
+ if( aBuf[nBuf-1]=='s' ){
+ if( aBuf[nBuf-2]=='e' ){
if( (nBuf>4 && aBuf[nBuf-4]=='s' && aBuf[nBuf-3]=='s')
- || (nBuf>3 && aBuf[nBuf-3]=='i' )
- ){
- *pnBuf = nBuf-2;
- }else{
- *pnBuf = nBuf-1;
- }
- }
- else if( aBuf[nBuf-2]!='s' ){
- *pnBuf = nBuf-1;
- }
- }
-}
-
-static int fts5PorterCb(
+ || (nBuf>3 && aBuf[nBuf-3]=='i' )
+ ){
+ *pnBuf = nBuf-2;
+ }else{
+ *pnBuf = nBuf-1;
+ }
+ }
+ else if( aBuf[nBuf-2]!='s' ){
+ *pnBuf = nBuf-1;
+ }
+ }
+}
+
+static int fts5PorterCb(
void *pCtx,
- int tflags,
+ int tflags,
const char *pToken,
int nToken,
int iStart,
- int iEnd
-){
- PorterContext *p = (PorterContext*)pCtx;
-
- char *aBuf;
- int nBuf;
-
- if( nToken>FTS5_PORTER_MAX_TOKEN || nToken<3 ) goto pass_through;
- aBuf = p->aBuf;
- nBuf = nToken;
- memcpy(aBuf, pToken, nBuf);
-
- /* Step 1. */
- fts5PorterStep1A(aBuf, &nBuf);
- if( fts5PorterStep1B(aBuf, &nBuf) ){
- if( fts5PorterStep1B2(aBuf, &nBuf)==0 ){
- char c = aBuf[nBuf-1];
+ int iEnd
+){
+ PorterContext *p = (PorterContext*)pCtx;
+
+ char *aBuf;
+ int nBuf;
+
+ if( nToken>FTS5_PORTER_MAX_TOKEN || nToken<3 ) goto pass_through;
+ aBuf = p->aBuf;
+ nBuf = nToken;
+ memcpy(aBuf, pToken, nBuf);
+
+ /* Step 1. */
+ fts5PorterStep1A(aBuf, &nBuf);
+ if( fts5PorterStep1B(aBuf, &nBuf) ){
+ if( fts5PorterStep1B2(aBuf, &nBuf)==0 ){
+ char c = aBuf[nBuf-1];
if( fts5PorterIsVowel(c, 0)==0
&& c!='l' && c!='s' && c!='z' && c==aBuf[nBuf-2]
- ){
- nBuf--;
- }else if( fts5Porter_MEq1(aBuf, nBuf) && fts5Porter_Ostar(aBuf, nBuf) ){
- aBuf[nBuf++] = 'e';
- }
- }
- }
-
- /* Step 1C. */
- if( aBuf[nBuf-1]=='y' && fts5Porter_Vowel(aBuf, nBuf-1) ){
- aBuf[nBuf-1] = 'i';
- }
-
- /* Steps 2 through 4. */
- fts5PorterStep2(aBuf, &nBuf);
- fts5PorterStep3(aBuf, &nBuf);
- fts5PorterStep4(aBuf, &nBuf);
-
- /* Step 5a. */
- assert( nBuf>0 );
- if( aBuf[nBuf-1]=='e' ){
+ ){
+ nBuf--;
+ }else if( fts5Porter_MEq1(aBuf, nBuf) && fts5Porter_Ostar(aBuf, nBuf) ){
+ aBuf[nBuf++] = 'e';
+ }
+ }
+ }
+
+ /* Step 1C. */
+ if( aBuf[nBuf-1]=='y' && fts5Porter_Vowel(aBuf, nBuf-1) ){
+ aBuf[nBuf-1] = 'i';
+ }
+
+ /* Steps 2 through 4. */
+ fts5PorterStep2(aBuf, &nBuf);
+ fts5PorterStep3(aBuf, &nBuf);
+ fts5PorterStep4(aBuf, &nBuf);
+
+ /* Step 5a. */
+ assert( nBuf>0 );
+ if( aBuf[nBuf-1]=='e' ){
if( fts5Porter_MGt1(aBuf, nBuf-1)
- || (fts5Porter_MEq1(aBuf, nBuf-1) && !fts5Porter_Ostar(aBuf, nBuf-1))
- ){
- nBuf--;
- }
- }
-
- /* Step 5b. */
+ || (fts5Porter_MEq1(aBuf, nBuf-1) && !fts5Porter_Ostar(aBuf, nBuf-1))
+ ){
+ nBuf--;
+ }
+ }
+
+ /* Step 5b. */
if( nBuf>1 && aBuf[nBuf-1]=='l'
&& aBuf[nBuf-2]=='l' && fts5Porter_MGt1(aBuf, nBuf-1)
- ){
- nBuf--;
- }
-
- return p->xToken(p->pCtx, tflags, aBuf, nBuf, iStart, iEnd);
-
- pass_through:
- return p->xToken(p->pCtx, tflags, pToken, nToken, iStart, iEnd);
-}
-
-/*
-** Tokenize using the porter tokenizer.
-*/
-static int fts5PorterTokenize(
- Fts5Tokenizer *pTokenizer,
- void *pCtx,
- int flags,
- const char *pText, int nText,
- int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
-){
- PorterTokenizer *p = (PorterTokenizer*)pTokenizer;
- PorterContext sCtx;
- sCtx.xToken = xToken;
- sCtx.pCtx = pCtx;
- sCtx.aBuf = p->aBuf;
- return p->tokenizer.xTokenize(
- p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb
- );
-}
-
+ ){
+ nBuf--;
+ }
+
+ return p->xToken(p->pCtx, tflags, aBuf, nBuf, iStart, iEnd);
+
+ pass_through:
+ return p->xToken(p->pCtx, tflags, pToken, nToken, iStart, iEnd);
+}
+
+/*
+** Tokenize using the porter tokenizer.
+*/
+static int fts5PorterTokenize(
+ Fts5Tokenizer *pTokenizer,
+ void *pCtx,
+ int flags,
+ const char *pText, int nText,
+ int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
+){
+ PorterTokenizer *p = (PorterTokenizer*)pTokenizer;
+ PorterContext sCtx;
+ sCtx.xToken = xToken;
+ sCtx.pCtx = pCtx;
+ sCtx.aBuf = p->aBuf;
+ return p->tokenizer.xTokenize(
+ p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb
+ );
+}
+
/**************************************************************************
** Start of trigram implementation.
*/
@@ -235120,7 +235120,7 @@ struct TrigramTokenizer {
int bFold; /* True to fold to lower-case */
};
-/*
+/*
** Free a trigram tokenizer.
*/
static void fts5TriDelete(Fts5Tokenizer *p){
@@ -235240,66 +235240,66 @@ static int sqlite3Fts5TokenizerPattern(
}
/*
-** Register all built-in tokenizers with FTS5.
-*/
-static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
- struct BuiltinTokenizer {
- const char *zName;
- fts5_tokenizer x;
- } aBuiltin[] = {
- { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
- { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
- { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
+** Register all built-in tokenizers with FTS5.
+*/
+static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
+ struct BuiltinTokenizer {
+ const char *zName;
+ fts5_tokenizer x;
+ } aBuiltin[] = {
+ { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
+ { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
+ { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
{ "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}},
- };
-
- int rc = SQLITE_OK; /* Return code */
- int i; /* To iterate through builtin functions */
-
- for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
- rc = pApi->xCreateTokenizer(pApi,
- aBuiltin[i].zName,
- (void*)pApi,
- &aBuiltin[i].x,
- 0
- );
- }
-
- return rc;
-}
-
-/*
+ };
+
+ int rc = SQLITE_OK; /* Return code */
+ int i; /* To iterate through builtin functions */
+
+ for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
+ rc = pApi->xCreateTokenizer(pApi,
+ aBuiltin[i].zName,
+ (void*)pApi,
+ &aBuiltin[i].x,
+ 0
+ );
+ }
+
+ return rc;
+}
+
+/*
** 2012-05-25
-**
-** 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.
-**
-******************************************************************************
-*/
-
-/*
-** DO NOT EDIT THIS MACHINE GENERATED FILE.
-*/
-
-
-/* #include <assert.h> */
-
-
-
-/*
-** If the argument is a codepoint corresponding to a lowercase letter
-** in the ASCII range with a diacritic added, return the codepoint
-** of the ASCII letter only. For example, if passed 235 - "LATIN
-** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER
-** E"). The resuls of passing a codepoint that corresponds to an
-** uppercase letter are undefined.
-*/
+**
+** 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.
+**
+******************************************************************************
+*/
+
+/*
+** DO NOT EDIT THIS MACHINE GENERATED FILE.
+*/
+
+
+/* #include <assert.h> */
+
+
+
+/*
+** If the argument is a codepoint corresponding to a lowercase letter
+** in the ASCII range with a diacritic added, return the codepoint
+** of the ASCII letter only. For example, if passed 235 - "LATIN
+** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER
+** E"). The resuls of passing a codepoint that corresponds to an
+** uppercase letter are undefined.
+*/
static int fts5_remove_diacritic(int c, int bComplex){
- unsigned short aDia[] = {
+ unsigned short aDia[] = {
0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
@@ -235316,7 +235316,7 @@ static int fts5_remove_diacritic(int c, int bComplex){
62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766,
62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118,
63182, 63242, 63274, 63310, 63368, 63390,
- };
+ };
#define HIBIT ((unsigned char)0x80)
unsigned char aChar[] = {
'\0', 'a', 'c', 'e', 'i', 'n',
@@ -235340,130 +235340,130 @@ static int fts5_remove_diacritic(int c, int bComplex){
'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT,
'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT,
'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y',
- };
-
- unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
- int iRes = 0;
- int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
- int iLo = 0;
- while( iHi>=iLo ){
- int iTest = (iHi + iLo) / 2;
- if( key >= aDia[iTest] ){
- iRes = iTest;
- iLo = iTest+1;
- }else{
- iHi = iTest-1;
- }
- }
- assert( key>=aDia[iRes] );
+ };
+
+ unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
+ int iRes = 0;
+ int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
+ int iLo = 0;
+ while( iHi>=iLo ){
+ int iTest = (iHi + iLo) / 2;
+ if( key >= aDia[iTest] ){
+ iRes = iTest;
+ iLo = iTest+1;
+ }else{
+ iHi = iTest-1;
+ }
+ }
+ assert( key>=aDia[iRes] );
if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);
-}
-
-
-/*
-** Return true if the argument interpreted as a unicode codepoint
-** is a diacritical modifier character.
-*/
-static int sqlite3Fts5UnicodeIsdiacritic(int c){
- unsigned int mask0 = 0x08029FDF;
- unsigned int mask1 = 0x000361F8;
- if( c<768 || c>817 ) return 0;
- return (c < 768+32) ?
+}
+
+
+/*
+** Return true if the argument interpreted as a unicode codepoint
+** is a diacritical modifier character.
+*/
+static int sqlite3Fts5UnicodeIsdiacritic(int c){
+ unsigned int mask0 = 0x08029FDF;
+ unsigned int mask1 = 0x000361F8;
+ if( c<768 || c>817 ) return 0;
+ return (c < 768+32) ?
(mask0 & ((unsigned int)1 << (c-768))) :
(mask1 & ((unsigned int)1 << (c-768-32)));
-}
-
-
-/*
-** Interpret the argument as a unicode codepoint. If the codepoint
-** is an upper case character that has a lower case equivalent,
-** return the codepoint corresponding to the lower case version.
-** Otherwise, return a copy of the argument.
-**
-** The results are undefined if the value passed to this function
-** is less than zero.
-*/
+}
+
+
+/*
+** Interpret the argument as a unicode codepoint. If the codepoint
+** is an upper case character that has a lower case equivalent,
+** return the codepoint corresponding to the lower case version.
+** Otherwise, return a copy of the argument.
+**
+** The results are undefined if the value passed to this function
+** is less than zero.
+*/
static int sqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){
- /* Each entry in the following array defines a rule for folding a range
- ** of codepoints to lower case. The rule applies to a range of nRange
- ** codepoints starting at codepoint iCode.
- **
- ** If the least significant bit in flags is clear, then the rule applies
- ** to all nRange codepoints (i.e. all nRange codepoints are upper case and
- ** need to be folded). Or, if it is set, then the rule only applies to
- ** every second codepoint in the range, starting with codepoint C.
- **
- ** The 7 most significant bits in flags are an index into the aiOff[]
- ** array. If a specific codepoint C does require folding, then its lower
- ** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF).
- **
- ** The contents of this array are generated by parsing the CaseFolding.txt
- ** file distributed as part of the "Unicode Character Database". See
- ** http://www.unicode.org for details.
- */
- static const struct TableEntry {
- unsigned short iCode;
- unsigned char flags;
- unsigned char nRange;
- } aEntry[] = {
- {65, 14, 26}, {181, 64, 1}, {192, 14, 23},
- {216, 14, 7}, {256, 1, 48}, {306, 1, 6},
- {313, 1, 16}, {330, 1, 46}, {376, 116, 1},
- {377, 1, 6}, {383, 104, 1}, {385, 50, 1},
- {386, 1, 4}, {390, 44, 1}, {391, 0, 1},
- {393, 42, 2}, {395, 0, 1}, {398, 32, 1},
- {399, 38, 1}, {400, 40, 1}, {401, 0, 1},
- {403, 42, 1}, {404, 46, 1}, {406, 52, 1},
- {407, 48, 1}, {408, 0, 1}, {412, 52, 1},
- {413, 54, 1}, {415, 56, 1}, {416, 1, 6},
- {422, 60, 1}, {423, 0, 1}, {425, 60, 1},
- {428, 0, 1}, {430, 60, 1}, {431, 0, 1},
- {433, 58, 2}, {435, 1, 4}, {439, 62, 1},
- {440, 0, 1}, {444, 0, 1}, {452, 2, 1},
- {453, 0, 1}, {455, 2, 1}, {456, 0, 1},
- {458, 2, 1}, {459, 1, 18}, {478, 1, 18},
- {497, 2, 1}, {498, 1, 4}, {502, 122, 1},
- {503, 134, 1}, {504, 1, 40}, {544, 110, 1},
- {546, 1, 18}, {570, 70, 1}, {571, 0, 1},
- {573, 108, 1}, {574, 68, 1}, {577, 0, 1},
- {579, 106, 1}, {580, 28, 1}, {581, 30, 1},
- {582, 1, 10}, {837, 36, 1}, {880, 1, 4},
- {886, 0, 1}, {902, 18, 1}, {904, 16, 3},
- {908, 26, 1}, {910, 24, 2}, {913, 14, 17},
- {931, 14, 9}, {962, 0, 1}, {975, 4, 1},
- {976, 140, 1}, {977, 142, 1}, {981, 146, 1},
- {982, 144, 1}, {984, 1, 24}, {1008, 136, 1},
- {1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1},
- {1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1},
- {1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32},
- {1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1},
- {1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38},
- {4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1},
- {7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1},
- {7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6},
- {7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6},
- {8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8},
- {8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2},
- {8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1},
- {8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2},
- {8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2},
- {8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2},
- {8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1},
- {8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16},
- {8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47},
- {11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1},
- {11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1},
- {11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1},
- {11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2},
- {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1},
- {42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14},
- {42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1},
- {42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1},
- {42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1},
+ /* Each entry in the following array defines a rule for folding a range
+ ** of codepoints to lower case. The rule applies to a range of nRange
+ ** codepoints starting at codepoint iCode.
+ **
+ ** If the least significant bit in flags is clear, then the rule applies
+ ** to all nRange codepoints (i.e. all nRange codepoints are upper case and
+ ** need to be folded). Or, if it is set, then the rule only applies to
+ ** every second codepoint in the range, starting with codepoint C.
+ **
+ ** The 7 most significant bits in flags are an index into the aiOff[]
+ ** array. If a specific codepoint C does require folding, then its lower
+ ** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF).
+ **
+ ** The contents of this array are generated by parsing the CaseFolding.txt
+ ** file distributed as part of the "Unicode Character Database". See
+ ** http://www.unicode.org for details.
+ */
+ static const struct TableEntry {
+ unsigned short iCode;
+ unsigned char flags;
+ unsigned char nRange;
+ } aEntry[] = {
+ {65, 14, 26}, {181, 64, 1}, {192, 14, 23},
+ {216, 14, 7}, {256, 1, 48}, {306, 1, 6},
+ {313, 1, 16}, {330, 1, 46}, {376, 116, 1},
+ {377, 1, 6}, {383, 104, 1}, {385, 50, 1},
+ {386, 1, 4}, {390, 44, 1}, {391, 0, 1},
+ {393, 42, 2}, {395, 0, 1}, {398, 32, 1},
+ {399, 38, 1}, {400, 40, 1}, {401, 0, 1},
+ {403, 42, 1}, {404, 46, 1}, {406, 52, 1},
+ {407, 48, 1}, {408, 0, 1}, {412, 52, 1},
+ {413, 54, 1}, {415, 56, 1}, {416, 1, 6},
+ {422, 60, 1}, {423, 0, 1}, {425, 60, 1},
+ {428, 0, 1}, {430, 60, 1}, {431, 0, 1},
+ {433, 58, 2}, {435, 1, 4}, {439, 62, 1},
+ {440, 0, 1}, {444, 0, 1}, {452, 2, 1},
+ {453, 0, 1}, {455, 2, 1}, {456, 0, 1},
+ {458, 2, 1}, {459, 1, 18}, {478, 1, 18},
+ {497, 2, 1}, {498, 1, 4}, {502, 122, 1},
+ {503, 134, 1}, {504, 1, 40}, {544, 110, 1},
+ {546, 1, 18}, {570, 70, 1}, {571, 0, 1},
+ {573, 108, 1}, {574, 68, 1}, {577, 0, 1},
+ {579, 106, 1}, {580, 28, 1}, {581, 30, 1},
+ {582, 1, 10}, {837, 36, 1}, {880, 1, 4},
+ {886, 0, 1}, {902, 18, 1}, {904, 16, 3},
+ {908, 26, 1}, {910, 24, 2}, {913, 14, 17},
+ {931, 14, 9}, {962, 0, 1}, {975, 4, 1},
+ {976, 140, 1}, {977, 142, 1}, {981, 146, 1},
+ {982, 144, 1}, {984, 1, 24}, {1008, 136, 1},
+ {1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1},
+ {1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1},
+ {1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32},
+ {1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1},
+ {1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38},
+ {4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1},
+ {7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1},
+ {7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6},
+ {7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6},
+ {8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8},
+ {8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2},
+ {8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1},
+ {8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2},
+ {8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2},
+ {8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2},
+ {8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1},
+ {8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16},
+ {8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47},
+ {11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1},
+ {11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1},
+ {11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1},
+ {11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2},
+ {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1},
+ {42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14},
+ {42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1},
+ {42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1},
+ {42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1},
{65313, 14, 26},
- };
- static const unsigned short aiOff[] = {
+ };
+ static const unsigned short aiOff[] = {
1, 2, 8, 15, 16, 26, 28, 32,
37, 38, 40, 48, 63, 64, 69, 71,
79, 80, 116, 202, 203, 205, 206, 207,
@@ -235474,51 +235474,51 @@ static int sqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){
65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462,
65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511,
65514, 65521, 65527, 65528, 65529,
- };
-
- int ret = c;
-
- assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
-
- if( c<128 ){
- if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
- }else if( c<65536 ){
- const struct TableEntry *p;
- int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
- int iLo = 0;
- int iRes = -1;
-
- assert( c>aEntry[0].iCode );
- while( iHi>=iLo ){
- int iTest = (iHi + iLo) / 2;
- int cmp = (c - aEntry[iTest].iCode);
- if( cmp>=0 ){
- iRes = iTest;
- iLo = iTest+1;
- }else{
- iHi = iTest-1;
- }
- }
-
- assert( iRes>=0 && c>=aEntry[iRes].iCode );
- p = &aEntry[iRes];
- if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
- ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
- assert( ret>0 );
- }
-
+ };
+
+ int ret = c;
+
+ assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
+
+ if( c<128 ){
+ if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
+ }else if( c<65536 ){
+ const struct TableEntry *p;
+ int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
+ int iLo = 0;
+ int iRes = -1;
+
+ assert( c>aEntry[0].iCode );
+ while( iHi>=iLo ){
+ int iTest = (iHi + iLo) / 2;
+ int cmp = (c - aEntry[iTest].iCode);
+ if( cmp>=0 ){
+ iRes = iTest;
+ iLo = iTest+1;
+ }else{
+ iHi = iTest-1;
+ }
+ }
+
+ assert( iRes>=0 && c>=aEntry[iRes].iCode );
+ p = &aEntry[iRes];
+ if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
+ ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
+ assert( ret>0 );
+ }
+
if( eRemoveDiacritic ){
ret = fts5_remove_diacritic(ret, eRemoveDiacritic==2);
}
- }
+ }
+
+ else if( c>=66560 && c<66600 ){
+ ret = c + 40;
+ }
+
+ return ret;
+}
- else if( c>=66560 && c<66600 ){
- ret = c + 40;
- }
-
- return ret;
-}
-
static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){
aArray[0] = 1;
@@ -236047,711 +236047,711 @@ static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
}
-/*
-** 2015 May 30
-**
-** 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.
-**
-******************************************************************************
-**
-** Routines for varint serialization and deserialization.
-*/
-
-
-/* #include "fts5Int.h" */
-
-/*
-** This is a copy of the sqlite3GetVarint32() routine from the SQLite core.
-** Except, this version does handle the single byte case that the core
-** version depends on being handled before its function is called.
-*/
-static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){
- u32 a,b;
-
- /* The 1-byte case. Overwhelmingly the most common. */
- a = *p;
- /* a: p0 (unmasked) */
- if (!(a&0x80))
- {
- /* Values between 0 and 127 */
- *v = a;
- return 1;
- }
-
- /* The 2-byte case */
- p++;
- b = *p;
- /* b: p1 (unmasked) */
- if (!(b&0x80))
- {
- /* Values between 128 and 16383 */
- a &= 0x7f;
- a = a<<7;
- *v = a | b;
- return 2;
- }
-
- /* The 3-byte case */
- p++;
- a = a<<14;
- a |= *p;
- /* a: p0<<14 | p2 (unmasked) */
- if (!(a&0x80))
- {
- /* Values between 16384 and 2097151 */
- a &= (0x7f<<14)|(0x7f);
- b &= 0x7f;
- b = b<<7;
- *v = a | b;
- return 3;
- }
-
- /* A 32-bit varint is used to store size information in btrees.
- ** Objects are rarely larger than 2MiB limit of a 3-byte varint.
- ** A 3-byte varint is sufficient, for example, to record the size
- ** of a 1048569-byte BLOB or string.
- **
- ** We only unroll the first 1-, 2-, and 3- byte cases. The very
- ** rare larger cases can be handled by the slower 64-bit varint
- ** routine.
- */
- {
- u64 v64;
- u8 n;
- p -= 2;
- n = sqlite3Fts5GetVarint(p, &v64);
+/*
+** 2015 May 30
+**
+** 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.
+**
+******************************************************************************
+**
+** Routines for varint serialization and deserialization.
+*/
+
+
+/* #include "fts5Int.h" */
+
+/*
+** This is a copy of the sqlite3GetVarint32() routine from the SQLite core.
+** Except, this version does handle the single byte case that the core
+** version depends on being handled before its function is called.
+*/
+static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){
+ u32 a,b;
+
+ /* The 1-byte case. Overwhelmingly the most common. */
+ a = *p;
+ /* a: p0 (unmasked) */
+ if (!(a&0x80))
+ {
+ /* Values between 0 and 127 */
+ *v = a;
+ return 1;
+ }
+
+ /* The 2-byte case */
+ p++;
+ b = *p;
+ /* b: p1 (unmasked) */
+ if (!(b&0x80))
+ {
+ /* Values between 128 and 16383 */
+ a &= 0x7f;
+ a = a<<7;
+ *v = a | b;
+ return 2;
+ }
+
+ /* The 3-byte case */
+ p++;
+ a = a<<14;
+ a |= *p;
+ /* a: p0<<14 | p2 (unmasked) */
+ if (!(a&0x80))
+ {
+ /* Values between 16384 and 2097151 */
+ a &= (0x7f<<14)|(0x7f);
+ b &= 0x7f;
+ b = b<<7;
+ *v = a | b;
+ return 3;
+ }
+
+ /* A 32-bit varint is used to store size information in btrees.
+ ** Objects are rarely larger than 2MiB limit of a 3-byte varint.
+ ** A 3-byte varint is sufficient, for example, to record the size
+ ** of a 1048569-byte BLOB or string.
+ **
+ ** We only unroll the first 1-, 2-, and 3- byte cases. The very
+ ** rare larger cases can be handled by the slower 64-bit varint
+ ** routine.
+ */
+ {
+ u64 v64;
+ u8 n;
+ p -= 2;
+ n = sqlite3Fts5GetVarint(p, &v64);
*v = ((u32)v64) & 0x7FFFFFFF;
- assert( n>3 && n<=9 );
- return n;
- }
-}
-
-
-/*
-** Bitmasks used by sqlite3GetVarint(). These precomputed constants
-** are defined here rather than simply putting the constant expressions
-** inline in order to work around bugs in the RVT compiler.
-**
-** SLOT_2_0 A mask for (0x7f<<14) | 0x7f
-**
-** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0
-*/
-#define SLOT_2_0 0x001fc07f
-#define SLOT_4_2_0 0xf01fc07f
-
-/*
-** 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.
-*/
-static u8 sqlite3Fts5GetVarint(const unsigned char *p, u64 *v){
- u32 a,b,s;
-
- a = *p;
- /* a: p0 (unmasked) */
- if (!(a&0x80))
- {
- *v = a;
- return 1;
- }
-
- p++;
- b = *p;
- /* b: p1 (unmasked) */
- if (!(b&0x80))
- {
- a &= 0x7f;
- a = a<<7;
- a |= b;
- *v = a;
- return 2;
- }
-
- /* Verify that constants are precomputed correctly */
- assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
- assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
-
- p++;
- a = a<<14;
- a |= *p;
- /* a: p0<<14 | p2 (unmasked) */
- if (!(a&0x80))
- {
- a &= SLOT_2_0;
- b &= 0x7f;
- b = b<<7;
- a |= b;
- *v = a;
- return 3;
- }
-
- /* CSE1 from below */
- a &= SLOT_2_0;
- p++;
- b = b<<14;
- b |= *p;
- /* b: p1<<14 | p3 (unmasked) */
- if (!(b&0x80))
- {
- b &= SLOT_2_0;
- /* moved CSE1 up */
- /* a &= (0x7f<<14)|(0x7f); */
- a = a<<7;
- a |= b;
- *v = a;
- return 4;
- }
-
- /* a: p0<<14 | p2 (masked) */
- /* b: p1<<14 | p3 (unmasked) */
- /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
- /* moved CSE1 up */
- /* a &= (0x7f<<14)|(0x7f); */
- b &= SLOT_2_0;
- s = a;
- /* s: p0<<14 | p2 (masked) */
-
- p++;
- a = a<<14;
- a |= *p;
- /* a: p0<<28 | p2<<14 | p4 (unmasked) */
- if (!(a&0x80))
- {
- /* we can skip these cause they were (effectively) done above in calc'ing s */
- /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
- /* b &= (0x7f<<14)|(0x7f); */
- b = b<<7;
- a |= b;
- s = s>>18;
- *v = ((u64)s)<<32 | a;
- return 5;
- }
-
- /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
- s = s<<7;
- s |= b;
- /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
-
- p++;
- b = b<<14;
- b |= *p;
- /* b: p1<<28 | p3<<14 | p5 (unmasked) */
- if (!(b&0x80))
- {
- /* we can skip this cause it was (effectively) done above in calc'ing s */
- /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
- a &= SLOT_2_0;
- a = a<<7;
- a |= b;
- s = s>>18;
- *v = ((u64)s)<<32 | a;
- return 6;
- }
-
- p++;
- a = a<<14;
- a |= *p;
- /* a: p2<<28 | p4<<14 | p6 (unmasked) */
- if (!(a&0x80))
- {
- a &= SLOT_4_2_0;
- b &= SLOT_2_0;
- b = b<<7;
- a |= b;
- s = s>>11;
- *v = ((u64)s)<<32 | a;
- return 7;
- }
-
- /* CSE2 from below */
- a &= SLOT_2_0;
- p++;
- b = b<<14;
- b |= *p;
- /* b: p3<<28 | p5<<14 | p7 (unmasked) */
- if (!(b&0x80))
- {
- b &= SLOT_4_2_0;
- /* moved CSE2 up */
- /* a &= (0x7f<<14)|(0x7f); */
- a = a<<7;
- a |= b;
- s = s>>4;
- *v = ((u64)s)<<32 | a;
- return 8;
- }
-
- p++;
- a = a<<15;
- a |= *p;
- /* a: p4<<29 | p6<<15 | p8 (unmasked) */
-
- /* moved CSE2 up */
- /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */
- b &= SLOT_2_0;
- b = b<<8;
- a |= b;
-
- s = s<<4;
- b = p[-4];
- b &= 0x7f;
- b = b>>3;
- s |= b;
-
- *v = ((u64)s)<<32 | a;
-
- return 9;
-}
-
-/*
-** The variable-length integer encoding is as follows:
-**
-** KEY:
-** A = 0xxxxxxx 7 bits of data and one flag bit
-** B = 1xxxxxxx 7 bits of data and one flag bit
-** C = xxxxxxxx 8 bits of data
-**
-** 7 bits - A
-** 14 bits - BA
-** 21 bits - BBA
-** 28 bits - BBBA
-** 35 bits - BBBBA
-** 42 bits - BBBBBA
-** 49 bits - BBBBBBA
-** 56 bits - BBBBBBBA
-** 64 bits - BBBBBBBBC
-*/
-
-#ifdef SQLITE_NOINLINE
-# define FTS5_NOINLINE SQLITE_NOINLINE
-#else
-# define FTS5_NOINLINE
-#endif
-
-/*
-** Write a 64-bit variable-length integer to memory starting at p[0].
-** The length of data write will be between 1 and 9 bytes. The number
-** of bytes written is returned.
-**
-** A variable-length integer consists of the lower 7 bits of each byte
-** for all bytes that have the 8th bit set and one byte with the 8th
-** bit clear. Except, if we get to the 9th byte, it stores the full
-** 8 bits and is the last byte.
-*/
-static int FTS5_NOINLINE fts5PutVarint64(unsigned char *p, u64 v){
- int i, j, n;
- u8 buf[10];
- if( v & (((u64)0xff000000)<<32) ){
- p[8] = (u8)v;
- v >>= 8;
- for(i=7; i>=0; i--){
- p[i] = (u8)((v & 0x7f) | 0x80);
- v >>= 7;
- }
- return 9;
- }
- n = 0;
- do{
- buf[n++] = (u8)((v & 0x7f) | 0x80);
- v >>= 7;
- }while( v!=0 );
- buf[0] &= 0x7f;
- assert( n<=9 );
- for(i=0, j=n-1; j>=0; j--, i++){
- p[i] = buf[j];
- }
- return n;
-}
-
-static int sqlite3Fts5PutVarint(unsigned char *p, u64 v){
- if( v<=0x7f ){
- p[0] = v&0x7f;
- return 1;
- }
- if( v<=0x3fff ){
- p[0] = ((v>>7)&0x7f)|0x80;
- p[1] = v&0x7f;
- return 2;
- }
- return fts5PutVarint64(p,v);
-}
-
-
-static int sqlite3Fts5GetVarintLen(u32 iVal){
-#if 0
- if( iVal<(1 << 7 ) ) return 1;
-#endif
- assert( iVal>=(1 << 7) );
- if( iVal<(1 << 14) ) return 2;
- if( iVal<(1 << 21) ) return 3;
- if( iVal<(1 << 28) ) return 4;
- return 5;
-}
-
-/*
-** 2015 May 08
-**
-** 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 is an SQLite virtual table module implementing direct access to an
+ assert( n>3 && n<=9 );
+ return n;
+ }
+}
+
+
+/*
+** Bitmasks used by sqlite3GetVarint(). These precomputed constants
+** are defined here rather than simply putting the constant expressions
+** inline in order to work around bugs in the RVT compiler.
+**
+** SLOT_2_0 A mask for (0x7f<<14) | 0x7f
+**
+** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0
+*/
+#define SLOT_2_0 0x001fc07f
+#define SLOT_4_2_0 0xf01fc07f
+
+/*
+** 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.
+*/
+static u8 sqlite3Fts5GetVarint(const unsigned char *p, u64 *v){
+ u32 a,b,s;
+
+ a = *p;
+ /* a: p0 (unmasked) */
+ if (!(a&0x80))
+ {
+ *v = a;
+ return 1;
+ }
+
+ p++;
+ b = *p;
+ /* b: p1 (unmasked) */
+ if (!(b&0x80))
+ {
+ a &= 0x7f;
+ a = a<<7;
+ a |= b;
+ *v = a;
+ return 2;
+ }
+
+ /* Verify that constants are precomputed correctly */
+ assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
+ assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ /* a: p0<<14 | p2 (unmasked) */
+ if (!(a&0x80))
+ {
+ a &= SLOT_2_0;
+ b &= 0x7f;
+ b = b<<7;
+ a |= b;
+ *v = a;
+ return 3;
+ }
+
+ /* CSE1 from below */
+ a &= SLOT_2_0;
+ p++;
+ b = b<<14;
+ b |= *p;
+ /* b: p1<<14 | p3 (unmasked) */
+ if (!(b&0x80))
+ {
+ b &= SLOT_2_0;
+ /* moved CSE1 up */
+ /* a &= (0x7f<<14)|(0x7f); */
+ a = a<<7;
+ a |= b;
+ *v = a;
+ return 4;
+ }
+
+ /* a: p0<<14 | p2 (masked) */
+ /* b: p1<<14 | p3 (unmasked) */
+ /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
+ /* moved CSE1 up */
+ /* a &= (0x7f<<14)|(0x7f); */
+ b &= SLOT_2_0;
+ s = a;
+ /* s: p0<<14 | p2 (masked) */
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ /* a: p0<<28 | p2<<14 | p4 (unmasked) */
+ if (!(a&0x80))
+ {
+ /* we can skip these cause they were (effectively) done above in calc'ing s */
+ /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
+ /* b &= (0x7f<<14)|(0x7f); */
+ b = b<<7;
+ a |= b;
+ s = s>>18;
+ *v = ((u64)s)<<32 | a;
+ return 5;
+ }
+
+ /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
+ s = s<<7;
+ s |= b;
+ /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
+
+ p++;
+ b = b<<14;
+ b |= *p;
+ /* b: p1<<28 | p3<<14 | p5 (unmasked) */
+ if (!(b&0x80))
+ {
+ /* we can skip this cause it was (effectively) done above in calc'ing s */
+ /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
+ a &= SLOT_2_0;
+ a = a<<7;
+ a |= b;
+ s = s>>18;
+ *v = ((u64)s)<<32 | a;
+ return 6;
+ }
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ /* a: p2<<28 | p4<<14 | p6 (unmasked) */
+ if (!(a&0x80))
+ {
+ a &= SLOT_4_2_0;
+ b &= SLOT_2_0;
+ b = b<<7;
+ a |= b;
+ s = s>>11;
+ *v = ((u64)s)<<32 | a;
+ return 7;
+ }
+
+ /* CSE2 from below */
+ a &= SLOT_2_0;
+ p++;
+ b = b<<14;
+ b |= *p;
+ /* b: p3<<28 | p5<<14 | p7 (unmasked) */
+ if (!(b&0x80))
+ {
+ b &= SLOT_4_2_0;
+ /* moved CSE2 up */
+ /* a &= (0x7f<<14)|(0x7f); */
+ a = a<<7;
+ a |= b;
+ s = s>>4;
+ *v = ((u64)s)<<32 | a;
+ return 8;
+ }
+
+ p++;
+ a = a<<15;
+ a |= *p;
+ /* a: p4<<29 | p6<<15 | p8 (unmasked) */
+
+ /* moved CSE2 up */
+ /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */
+ b &= SLOT_2_0;
+ b = b<<8;
+ a |= b;
+
+ s = s<<4;
+ b = p[-4];
+ b &= 0x7f;
+ b = b>>3;
+ s |= b;
+
+ *v = ((u64)s)<<32 | a;
+
+ return 9;
+}
+
+/*
+** The variable-length integer encoding is as follows:
+**
+** KEY:
+** A = 0xxxxxxx 7 bits of data and one flag bit
+** B = 1xxxxxxx 7 bits of data and one flag bit
+** C = xxxxxxxx 8 bits of data
+**
+** 7 bits - A
+** 14 bits - BA
+** 21 bits - BBA
+** 28 bits - BBBA
+** 35 bits - BBBBA
+** 42 bits - BBBBBA
+** 49 bits - BBBBBBA
+** 56 bits - BBBBBBBA
+** 64 bits - BBBBBBBBC
+*/
+
+#ifdef SQLITE_NOINLINE
+# define FTS5_NOINLINE SQLITE_NOINLINE
+#else
+# define FTS5_NOINLINE
+#endif
+
+/*
+** Write a 64-bit variable-length integer to memory starting at p[0].
+** The length of data write will be between 1 and 9 bytes. The number
+** of bytes written is returned.
+**
+** A variable-length integer consists of the lower 7 bits of each byte
+** for all bytes that have the 8th bit set and one byte with the 8th
+** bit clear. Except, if we get to the 9th byte, it stores the full
+** 8 bits and is the last byte.
+*/
+static int FTS5_NOINLINE fts5PutVarint64(unsigned char *p, u64 v){
+ int i, j, n;
+ u8 buf[10];
+ if( v & (((u64)0xff000000)<<32) ){
+ p[8] = (u8)v;
+ v >>= 8;
+ for(i=7; i>=0; i--){
+ p[i] = (u8)((v & 0x7f) | 0x80);
+ v >>= 7;
+ }
+ return 9;
+ }
+ n = 0;
+ do{
+ buf[n++] = (u8)((v & 0x7f) | 0x80);
+ v >>= 7;
+ }while( v!=0 );
+ buf[0] &= 0x7f;
+ assert( n<=9 );
+ for(i=0, j=n-1; j>=0; j--, i++){
+ p[i] = buf[j];
+ }
+ return n;
+}
+
+static int sqlite3Fts5PutVarint(unsigned char *p, u64 v){
+ if( v<=0x7f ){
+ p[0] = v&0x7f;
+ return 1;
+ }
+ if( v<=0x3fff ){
+ p[0] = ((v>>7)&0x7f)|0x80;
+ p[1] = v&0x7f;
+ return 2;
+ }
+ return fts5PutVarint64(p,v);
+}
+
+
+static int sqlite3Fts5GetVarintLen(u32 iVal){
+#if 0
+ if( iVal<(1 << 7 ) ) return 1;
+#endif
+ assert( iVal>=(1 << 7) );
+ if( iVal<(1 << 14) ) return 2;
+ if( iVal<(1 << 21) ) return 3;
+ if( iVal<(1 << 28) ) return 4;
+ return 5;
+}
+
+/*
+** 2015 May 08
+**
+** 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 is an SQLite virtual table module implementing direct access to an
** existing FTS5 index. The module may create several different types of
-** tables:
-**
-** col:
-** CREATE TABLE vocab(term, col, doc, cnt, PRIMARY KEY(term, col));
-**
-** One row for each term/column combination. The value of $doc is set to
-** the number of fts5 rows that contain at least one instance of term
+** tables:
+**
+** col:
+** CREATE TABLE vocab(term, col, doc, cnt, PRIMARY KEY(term, col));
+**
+** One row for each term/column combination. The value of $doc is set to
+** the number of fts5 rows that contain at least one instance of term
** $term within column $col. Field $cnt is set to the total number of
** instances of term $term in column $col (in any row of the fts5 table).
-**
-** row:
-** CREATE TABLE vocab(term, doc, cnt, PRIMARY KEY(term));
-**
-** One row for each term in the database. The value of $doc is set to
-** the number of fts5 rows that contain at least one instance of term
+**
+** row:
+** CREATE TABLE vocab(term, doc, cnt, PRIMARY KEY(term));
+**
+** One row for each term in the database. The value of $doc is set to
+** the number of fts5 rows that contain at least one instance of term
** $term. Field $cnt is set to the total number of instances of term
-** $term in the database.
-**
-** instance:
-** CREATE TABLE vocab(term, doc, col, offset, PRIMARY KEY(<all-fields>));
-**
+** $term in the database.
+**
+** instance:
+** CREATE TABLE vocab(term, doc, col, offset, PRIMARY KEY(<all-fields>));
+**
** One row for each term instance in the database.
-*/
-
-
-/* #include "fts5Int.h" */
-
-
-typedef struct Fts5VocabTable Fts5VocabTable;
-typedef struct Fts5VocabCursor Fts5VocabCursor;
-
-struct Fts5VocabTable {
- sqlite3_vtab base;
- char *zFts5Tbl; /* Name of fts5 table */
- char *zFts5Db; /* Db containing fts5 table */
- sqlite3 *db; /* Database handle */
- Fts5Global *pGlobal; /* FTS5 global object for this database */
- int eType; /* FTS5_VOCAB_COL, ROW or INSTANCE */
+*/
+
+
+/* #include "fts5Int.h" */
+
+
+typedef struct Fts5VocabTable Fts5VocabTable;
+typedef struct Fts5VocabCursor Fts5VocabCursor;
+
+struct Fts5VocabTable {
+ sqlite3_vtab base;
+ char *zFts5Tbl; /* Name of fts5 table */
+ char *zFts5Db; /* Db containing fts5 table */
+ sqlite3 *db; /* Database handle */
+ Fts5Global *pGlobal; /* FTS5 global object for this database */
+ int eType; /* FTS5_VOCAB_COL, ROW or INSTANCE */
unsigned bBusy; /* True if busy */
-};
-
-struct Fts5VocabCursor {
- sqlite3_vtab_cursor base;
- sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */
+};
+
+struct Fts5VocabCursor {
+ sqlite3_vtab_cursor base;
+ sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */
Fts5Table *pFts5; /* Associated FTS5 table */
-
- int bEof; /* True if this cursor is at EOF */
- Fts5IndexIter *pIter; /* Term/rowid iterator object */
+
+ int bEof; /* True if this cursor is at EOF */
+ Fts5IndexIter *pIter; /* Term/rowid iterator object */
void *pStruct; /* From sqlite3Fts5StructureRef() */
-
- int nLeTerm; /* Size of zLeTerm in bytes */
- char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
-
- /* These are used by 'col' tables only */
- int iCol;
- i64 *aCnt;
- i64 *aDoc;
-
- /* Output values used by all tables. */
- i64 rowid; /* This table's current rowid value */
- Fts5Buffer term; /* Current value of 'term' column */
-
- /* Output values Used by 'instance' tables only */
- i64 iInstPos;
- int iInstOff;
-};
-
-#define FTS5_VOCAB_COL 0
-#define FTS5_VOCAB_ROW 1
-#define FTS5_VOCAB_INSTANCE 2
-
-#define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt"
-#define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt"
-#define FTS5_VOCAB_INST_SCHEMA "term, doc, col, offset"
-
-/*
-** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
-*/
-#define FTS5_VOCAB_TERM_EQ 0x01
-#define FTS5_VOCAB_TERM_GE 0x02
-#define FTS5_VOCAB_TERM_LE 0x04
-
-
-/*
+
+ int nLeTerm; /* Size of zLeTerm in bytes */
+ char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
+
+ /* These are used by 'col' tables only */
+ int iCol;
+ i64 *aCnt;
+ i64 *aDoc;
+
+ /* Output values used by all tables. */
+ i64 rowid; /* This table's current rowid value */
+ Fts5Buffer term; /* Current value of 'term' column */
+
+ /* Output values Used by 'instance' tables only */
+ i64 iInstPos;
+ int iInstOff;
+};
+
+#define FTS5_VOCAB_COL 0
+#define FTS5_VOCAB_ROW 1
+#define FTS5_VOCAB_INSTANCE 2
+
+#define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt"
+#define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt"
+#define FTS5_VOCAB_INST_SCHEMA "term, doc, col, offset"
+
+/*
+** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
+*/
+#define FTS5_VOCAB_TERM_EQ 0x01
+#define FTS5_VOCAB_TERM_GE 0x02
+#define FTS5_VOCAB_TERM_LE 0x04
+
+
+/*
** Translate a string containing an fts5vocab table type to an
-** FTS5_VOCAB_XXX constant. If successful, set *peType to the output
-** value and return SQLITE_OK. Otherwise, set *pzErr to an error message
-** and return SQLITE_ERROR.
-*/
-static int fts5VocabTableType(const char *zType, char **pzErr, int *peType){
- int rc = SQLITE_OK;
- char *zCopy = sqlite3Fts5Strndup(&rc, zType, -1);
- if( rc==SQLITE_OK ){
- sqlite3Fts5Dequote(zCopy);
- if( sqlite3_stricmp(zCopy, "col")==0 ){
- *peType = FTS5_VOCAB_COL;
- }else
-
- if( sqlite3_stricmp(zCopy, "row")==0 ){
- *peType = FTS5_VOCAB_ROW;
- }else
- if( sqlite3_stricmp(zCopy, "instance")==0 ){
- *peType = FTS5_VOCAB_INSTANCE;
- }else
- {
- *pzErr = sqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy);
- rc = SQLITE_ERROR;
- }
- sqlite3_free(zCopy);
- }
-
- return rc;
-}
-
-
-/*
-** The xDisconnect() virtual table method.
-*/
-static int fts5VocabDisconnectMethod(sqlite3_vtab *pVtab){
- Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab;
- sqlite3_free(pTab);
- return SQLITE_OK;
-}
-
-/*
-** The xDestroy() virtual table method.
-*/
-static int fts5VocabDestroyMethod(sqlite3_vtab *pVtab){
- Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab;
- sqlite3_free(pTab);
- return SQLITE_OK;
-}
-
-/*
-** This function is the implementation of both the xConnect and xCreate
-** methods of the FTS3 virtual table.
-**
-** The argv[] array contains the following:
-**
-** argv[0] -> module name ("fts5vocab")
-** argv[1] -> database name
-** argv[2] -> table name
-**
-** then:
-**
-** argv[3] -> name of fts5 table
-** argv[4] -> type of fts5vocab table
-**
-** or, for tables in the TEMP schema only.
-**
-** argv[3] -> name of fts5 tables database
-** argv[4] -> name of fts5 table
-** argv[5] -> type of fts5vocab table
-*/
-static int fts5VocabInitVtab(
- sqlite3 *db, /* The SQLite database connection */
- void *pAux, /* Pointer to Fts5Global object */
- int argc, /* Number of elements in argv array */
- const char * const *argv, /* xCreate/xConnect argument array */
- sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */
- char **pzErr /* Write any error message here */
-){
+** FTS5_VOCAB_XXX constant. If successful, set *peType to the output
+** value and return SQLITE_OK. Otherwise, set *pzErr to an error message
+** and return SQLITE_ERROR.
+*/
+static int fts5VocabTableType(const char *zType, char **pzErr, int *peType){
+ int rc = SQLITE_OK;
+ char *zCopy = sqlite3Fts5Strndup(&rc, zType, -1);
+ if( rc==SQLITE_OK ){
+ sqlite3Fts5Dequote(zCopy);
+ if( sqlite3_stricmp(zCopy, "col")==0 ){
+ *peType = FTS5_VOCAB_COL;
+ }else
+
+ if( sqlite3_stricmp(zCopy, "row")==0 ){
+ *peType = FTS5_VOCAB_ROW;
+ }else
+ if( sqlite3_stricmp(zCopy, "instance")==0 ){
+ *peType = FTS5_VOCAB_INSTANCE;
+ }else
+ {
+ *pzErr = sqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy);
+ rc = SQLITE_ERROR;
+ }
+ sqlite3_free(zCopy);
+ }
+
+ return rc;
+}
+
+
+/*
+** The xDisconnect() virtual table method.
+*/
+static int fts5VocabDisconnectMethod(sqlite3_vtab *pVtab){
+ Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab;
+ sqlite3_free(pTab);
+ return SQLITE_OK;
+}
+
+/*
+** The xDestroy() virtual table method.
+*/
+static int fts5VocabDestroyMethod(sqlite3_vtab *pVtab){
+ Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab;
+ sqlite3_free(pTab);
+ return SQLITE_OK;
+}
+
+/*
+** This function is the implementation of both the xConnect and xCreate
+** methods of the FTS3 virtual table.
+**
+** The argv[] array contains the following:
+**
+** argv[0] -> module name ("fts5vocab")
+** argv[1] -> database name
+** argv[2] -> table name
+**
+** then:
+**
+** argv[3] -> name of fts5 table
+** argv[4] -> type of fts5vocab table
+**
+** or, for tables in the TEMP schema only.
+**
+** argv[3] -> name of fts5 tables database
+** argv[4] -> name of fts5 table
+** argv[5] -> type of fts5vocab table
+*/
+static int fts5VocabInitVtab(
+ sqlite3 *db, /* The SQLite database connection */
+ void *pAux, /* Pointer to Fts5Global object */
+ int argc, /* Number of elements in argv array */
+ const char * const *argv, /* xCreate/xConnect argument array */
+ sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */
+ char **pzErr /* Write any error message here */
+){
const char *azSchema[] = {
"CREATE TABlE vocab(" FTS5_VOCAB_COL_SCHEMA ")",
- "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA ")",
- "CREATE TABlE vocab(" FTS5_VOCAB_INST_SCHEMA ")"
- };
-
- Fts5VocabTable *pRet = 0;
- int rc = SQLITE_OK; /* Return code */
- int bDb;
-
- bDb = (argc==6 && strlen(argv[1])==4 && memcmp("temp", argv[1], 4)==0);
-
- if( argc!=5 && bDb==0 ){
- *pzErr = sqlite3_mprintf("wrong number of vtable arguments");
- rc = SQLITE_ERROR;
- }else{
- int nByte; /* Bytes of space to allocate */
- const char *zDb = bDb ? argv[3] : argv[1];
- const char *zTab = bDb ? argv[4] : argv[3];
- const char *zType = bDb ? argv[5] : argv[4];
+ "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA ")",
+ "CREATE TABlE vocab(" FTS5_VOCAB_INST_SCHEMA ")"
+ };
+
+ Fts5VocabTable *pRet = 0;
+ int rc = SQLITE_OK; /* Return code */
+ int bDb;
+
+ bDb = (argc==6 && strlen(argv[1])==4 && memcmp("temp", argv[1], 4)==0);
+
+ if( argc!=5 && bDb==0 ){
+ *pzErr = sqlite3_mprintf("wrong number of vtable arguments");
+ rc = SQLITE_ERROR;
+ }else{
+ int nByte; /* Bytes of space to allocate */
+ const char *zDb = bDb ? argv[3] : argv[1];
+ const char *zTab = bDb ? argv[4] : argv[3];
+ const char *zType = bDb ? argv[5] : argv[4];
int nDb = (int)strlen(zDb)+1;
- int nTab = (int)strlen(zTab)+1;
- int eType = 0;
-
- rc = fts5VocabTableType(zType, pzErr, &eType);
- if( rc==SQLITE_OK ){
- assert( eType>=0 && eType<ArraySize(azSchema) );
- rc = sqlite3_declare_vtab(db, azSchema[eType]);
- }
-
- nByte = sizeof(Fts5VocabTable) + nDb + nTab;
- pRet = sqlite3Fts5MallocZero(&rc, nByte);
- if( pRet ){
- pRet->pGlobal = (Fts5Global*)pAux;
- pRet->eType = eType;
- pRet->db = db;
- pRet->zFts5Tbl = (char*)&pRet[1];
- pRet->zFts5Db = &pRet->zFts5Tbl[nTab];
- memcpy(pRet->zFts5Tbl, zTab, nTab);
- memcpy(pRet->zFts5Db, zDb, nDb);
- sqlite3Fts5Dequote(pRet->zFts5Tbl);
- sqlite3Fts5Dequote(pRet->zFts5Db);
- }
- }
-
- *ppVTab = (sqlite3_vtab*)pRet;
- return rc;
-}
-
-
-/*
-** The xConnect() and xCreate() methods for the virtual table. All the
-** work is done in function fts5VocabInitVtab().
-*/
-static int fts5VocabConnectMethod(
- sqlite3 *db, /* Database connection */
- void *pAux, /* Pointer to tokenizer hash table */
- int argc, /* Number of elements in argv array */
- const char * const *argv, /* xCreate/xConnect argument array */
- sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
- char **pzErr /* OUT: sqlite3_malloc'd error message */
-){
- return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr);
-}
-static int fts5VocabCreateMethod(
- sqlite3 *db, /* Database connection */
- void *pAux, /* Pointer to tokenizer hash table */
- int argc, /* Number of elements in argv array */
- const char * const *argv, /* xCreate/xConnect argument array */
- sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
- char **pzErr /* OUT: sqlite3_malloc'd error message */
-){
- return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr);
-}
-
-/*
-** Implementation of the xBestIndex method.
-**
-** Only constraints of the form:
-**
-** term <= ?
-** term == ?
-** term >= ?
-**
+ int nTab = (int)strlen(zTab)+1;
+ int eType = 0;
+
+ rc = fts5VocabTableType(zType, pzErr, &eType);
+ if( rc==SQLITE_OK ){
+ assert( eType>=0 && eType<ArraySize(azSchema) );
+ rc = sqlite3_declare_vtab(db, azSchema[eType]);
+ }
+
+ nByte = sizeof(Fts5VocabTable) + nDb + nTab;
+ pRet = sqlite3Fts5MallocZero(&rc, nByte);
+ if( pRet ){
+ pRet->pGlobal = (Fts5Global*)pAux;
+ pRet->eType = eType;
+ pRet->db = db;
+ pRet->zFts5Tbl = (char*)&pRet[1];
+ pRet->zFts5Db = &pRet->zFts5Tbl[nTab];
+ memcpy(pRet->zFts5Tbl, zTab, nTab);
+ memcpy(pRet->zFts5Db, zDb, nDb);
+ sqlite3Fts5Dequote(pRet->zFts5Tbl);
+ sqlite3Fts5Dequote(pRet->zFts5Db);
+ }
+ }
+
+ *ppVTab = (sqlite3_vtab*)pRet;
+ return rc;
+}
+
+
+/*
+** The xConnect() and xCreate() methods for the virtual table. All the
+** work is done in function fts5VocabInitVtab().
+*/
+static int fts5VocabConnectMethod(
+ sqlite3 *db, /* Database connection */
+ void *pAux, /* Pointer to tokenizer hash table */
+ int argc, /* Number of elements in argv array */
+ const char * const *argv, /* xCreate/xConnect argument array */
+ sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
+ char **pzErr /* OUT: sqlite3_malloc'd error message */
+){
+ return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr);
+}
+static int fts5VocabCreateMethod(
+ sqlite3 *db, /* Database connection */
+ void *pAux, /* Pointer to tokenizer hash table */
+ int argc, /* Number of elements in argv array */
+ const char * const *argv, /* xCreate/xConnect argument array */
+ sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
+ char **pzErr /* OUT: sqlite3_malloc'd error message */
+){
+ return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr);
+}
+
+/*
+** Implementation of the xBestIndex method.
+**
+** Only constraints of the form:
+**
+** term <= ?
+** term == ?
+** term >= ?
+**
** are interpreted. Less-than and less-than-or-equal are treated
-** identically, as are greater-than and greater-than-or-equal.
-*/
-static int fts5VocabBestIndexMethod(
- sqlite3_vtab *pUnused,
- sqlite3_index_info *pInfo
-){
- int i;
- int iTermEq = -1;
- int iTermGe = -1;
- int iTermLe = -1;
- int idxNum = 0;
- int nArg = 0;
-
- UNUSED_PARAM(pUnused);
-
- for(i=0; i<pInfo->nConstraint; i++){
- struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
- if( p->usable==0 ) continue;
- if( p->iColumn==0 ){ /* term column */
- if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i;
- if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i;
- if( p->op==SQLITE_INDEX_CONSTRAINT_LT ) iTermLe = i;
- if( p->op==SQLITE_INDEX_CONSTRAINT_GE ) iTermGe = i;
- if( p->op==SQLITE_INDEX_CONSTRAINT_GT ) iTermGe = i;
- }
- }
-
- if( iTermEq>=0 ){
- idxNum |= FTS5_VOCAB_TERM_EQ;
- pInfo->aConstraintUsage[iTermEq].argvIndex = ++nArg;
- pInfo->estimatedCost = 100;
- }else{
- pInfo->estimatedCost = 1000000;
- if( iTermGe>=0 ){
- idxNum |= FTS5_VOCAB_TERM_GE;
- pInfo->aConstraintUsage[iTermGe].argvIndex = ++nArg;
- pInfo->estimatedCost = pInfo->estimatedCost / 2;
- }
- if( iTermLe>=0 ){
- idxNum |= FTS5_VOCAB_TERM_LE;
- pInfo->aConstraintUsage[iTermLe].argvIndex = ++nArg;
- pInfo->estimatedCost = pInfo->estimatedCost / 2;
- }
- }
-
- /* This virtual table always delivers results in ascending order of
- ** the "term" column (column 0). So if the user has requested this
- ** specifically - "ORDER BY term" or "ORDER BY term ASC" - set the
- ** sqlite3_index_info.orderByConsumed flag to tell the core the results
- ** are already in sorted order. */
+** identically, as are greater-than and greater-than-or-equal.
+*/
+static int fts5VocabBestIndexMethod(
+ sqlite3_vtab *pUnused,
+ sqlite3_index_info *pInfo
+){
+ int i;
+ int iTermEq = -1;
+ int iTermGe = -1;
+ int iTermLe = -1;
+ int idxNum = 0;
+ int nArg = 0;
+
+ UNUSED_PARAM(pUnused);
+
+ for(i=0; i<pInfo->nConstraint; i++){
+ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
+ if( p->usable==0 ) continue;
+ if( p->iColumn==0 ){ /* term column */
+ if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i;
+ if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i;
+ if( p->op==SQLITE_INDEX_CONSTRAINT_LT ) iTermLe = i;
+ if( p->op==SQLITE_INDEX_CONSTRAINT_GE ) iTermGe = i;
+ if( p->op==SQLITE_INDEX_CONSTRAINT_GT ) iTermGe = i;
+ }
+ }
+
+ if( iTermEq>=0 ){
+ idxNum |= FTS5_VOCAB_TERM_EQ;
+ pInfo->aConstraintUsage[iTermEq].argvIndex = ++nArg;
+ pInfo->estimatedCost = 100;
+ }else{
+ pInfo->estimatedCost = 1000000;
+ if( iTermGe>=0 ){
+ idxNum |= FTS5_VOCAB_TERM_GE;
+ pInfo->aConstraintUsage[iTermGe].argvIndex = ++nArg;
+ pInfo->estimatedCost = pInfo->estimatedCost / 2;
+ }
+ if( iTermLe>=0 ){
+ idxNum |= FTS5_VOCAB_TERM_LE;
+ pInfo->aConstraintUsage[iTermLe].argvIndex = ++nArg;
+ pInfo->estimatedCost = pInfo->estimatedCost / 2;
+ }
+ }
+
+ /* This virtual table always delivers results in ascending order of
+ ** the "term" column (column 0). So if the user has requested this
+ ** specifically - "ORDER BY term" or "ORDER BY term ASC" - set the
+ ** sqlite3_index_info.orderByConsumed flag to tell the core the results
+ ** are already in sorted order. */
if( pInfo->nOrderBy==1
&& pInfo->aOrderBy[0].iColumn==0
- && pInfo->aOrderBy[0].desc==0
- ){
- pInfo->orderByConsumed = 1;
- }
-
- pInfo->idxNum = idxNum;
- return SQLITE_OK;
-}
-
-/*
-** Implementation of xOpen method.
-*/
-static int fts5VocabOpenMethod(
+ && pInfo->aOrderBy[0].desc==0
+ ){
+ pInfo->orderByConsumed = 1;
+ }
+
+ pInfo->idxNum = idxNum;
+ return SQLITE_OK;
+}
+
+/*
+** Implementation of xOpen method.
+*/
+static int fts5VocabOpenMethod(
sqlite3_vtab *pVTab,
- sqlite3_vtab_cursor **ppCsr
-){
- Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
+ sqlite3_vtab_cursor **ppCsr
+){
+ Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
Fts5Table *pFts5 = 0;
- Fts5VocabCursor *pCsr = 0;
- int rc = SQLITE_OK;
- sqlite3_stmt *pStmt = 0;
- char *zSql = 0;
-
+ Fts5VocabCursor *pCsr = 0;
+ int rc = SQLITE_OK;
+ sqlite3_stmt *pStmt = 0;
+ char *zSql = 0;
+
if( pTab->bBusy ){
pVTab->zErrMsg = sqlite3_mprintf(
"recursive definition for %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
);
return SQLITE_ERROR;
}
- zSql = sqlite3Fts5Mprintf(&rc,
- "SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'",
- pTab->zFts5Tbl, pTab->zFts5Db, pTab->zFts5Tbl, pTab->zFts5Tbl
- );
- if( zSql ){
- rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
- }
- sqlite3_free(zSql);
- assert( rc==SQLITE_OK || pStmt==0 );
- if( rc==SQLITE_ERROR ) rc = SQLITE_OK;
-
+ zSql = sqlite3Fts5Mprintf(&rc,
+ "SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'",
+ pTab->zFts5Tbl, pTab->zFts5Db, pTab->zFts5Tbl, pTab->zFts5Tbl
+ );
+ if( zSql ){
+ rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
+ }
+ sqlite3_free(zSql);
+ assert( rc==SQLITE_OK || pStmt==0 );
+ if( rc==SQLITE_ERROR ) rc = SQLITE_OK;
+
pTab->bBusy = 1;
- if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
- i64 iId = sqlite3_column_int64(pStmt, 0);
+ if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
+ i64 iId = sqlite3_column_int64(pStmt, 0);
pFts5 = sqlite3Fts5TableFromCsrid(pTab->pGlobal, iId);
- }
+ }
pTab->bBusy = 0;
-
+
if( rc==SQLITE_OK ){
if( pFts5==0 ){
rc = sqlite3_finalize(pStmt);
@@ -236764,734 +236764,734 @@ static int fts5VocabOpenMethod(
}
}else{
rc = sqlite3Fts5FlushToDisk(pFts5);
- }
- }
-
- if( rc==SQLITE_OK ){
+ }
+ }
+
+ if( rc==SQLITE_OK ){
i64 nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor);
- pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
- }
-
- if( pCsr ){
+ pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
+ }
+
+ if( pCsr ){
pCsr->pFts5 = pFts5;
- pCsr->pStmt = pStmt;
- pCsr->aCnt = (i64*)&pCsr[1];
+ pCsr->pStmt = pStmt;
+ pCsr->aCnt = (i64*)&pCsr[1];
pCsr->aDoc = &pCsr->aCnt[pFts5->pConfig->nCol];
- }else{
- sqlite3_finalize(pStmt);
- }
-
- *ppCsr = (sqlite3_vtab_cursor*)pCsr;
- return rc;
-}
-
-static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
- pCsr->rowid = 0;
- sqlite3Fts5IterClose(pCsr->pIter);
+ }else{
+ sqlite3_finalize(pStmt);
+ }
+
+ *ppCsr = (sqlite3_vtab_cursor*)pCsr;
+ return rc;
+}
+
+static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
+ pCsr->rowid = 0;
+ sqlite3Fts5IterClose(pCsr->pIter);
sqlite3Fts5StructureRelease(pCsr->pStruct);
pCsr->pStruct = 0;
- pCsr->pIter = 0;
- sqlite3_free(pCsr->zLeTerm);
- pCsr->nLeTerm = -1;
- pCsr->zLeTerm = 0;
+ pCsr->pIter = 0;
+ sqlite3_free(pCsr->zLeTerm);
+ pCsr->nLeTerm = -1;
+ pCsr->zLeTerm = 0;
pCsr->bEof = 0;
-}
-
-/*
-** Close the cursor. For additional information see the documentation
-** on the xClose method of the virtual table interface.
-*/
-static int fts5VocabCloseMethod(sqlite3_vtab_cursor *pCursor){
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
- fts5VocabResetCursor(pCsr);
- sqlite3Fts5BufferFree(&pCsr->term);
- sqlite3_finalize(pCsr->pStmt);
- sqlite3_free(pCsr);
- return SQLITE_OK;
-}
-
-static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){
- int rc = SQLITE_OK;
-
- if( sqlite3Fts5IterEof(pCsr->pIter) ){
- pCsr->bEof = 1;
- }else{
- const char *zTerm;
- int nTerm;
- zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
- if( pCsr->nLeTerm>=0 ){
- int nCmp = MIN(nTerm, pCsr->nLeTerm);
- int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
- if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
- pCsr->bEof = 1;
- }
- }
-
- sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
- }
- return rc;
-}
-
-static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
+}
+
+/*
+** Close the cursor. For additional information see the documentation
+** on the xClose method of the virtual table interface.
+*/
+static int fts5VocabCloseMethod(sqlite3_vtab_cursor *pCursor){
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+ fts5VocabResetCursor(pCsr);
+ sqlite3Fts5BufferFree(&pCsr->term);
+ sqlite3_finalize(pCsr->pStmt);
+ sqlite3_free(pCsr);
+ return SQLITE_OK;
+}
+
+static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){
+ int rc = SQLITE_OK;
+
+ if( sqlite3Fts5IterEof(pCsr->pIter) ){
+ pCsr->bEof = 1;
+ }else{
+ const char *zTerm;
+ int nTerm;
+ zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
+ if( pCsr->nLeTerm>=0 ){
+ int nCmp = MIN(nTerm, pCsr->nLeTerm);
+ int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
+ if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
+ pCsr->bEof = 1;
+ }
+ }
+
+ sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
+ }
+ return rc;
+}
+
+static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
int eDetail = pCsr->pFts5->pConfig->eDetail;
- int rc = SQLITE_OK;
- Fts5IndexIter *pIter = pCsr->pIter;
- i64 *pp = &pCsr->iInstPos;
- int *po = &pCsr->iInstOff;
+ int rc = SQLITE_OK;
+ Fts5IndexIter *pIter = pCsr->pIter;
+ i64 *pp = &pCsr->iInstPos;
+ int *po = &pCsr->iInstOff;
assert( sqlite3Fts5IterEof(pIter)==0 );
assert( pCsr->bEof==0 );
- while( eDetail==FTS5_DETAIL_NONE
+ while( eDetail==FTS5_DETAIL_NONE
|| sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp)
- ){
- pCsr->iInstPos = 0;
- pCsr->iInstOff = 0;
-
- rc = sqlite3Fts5IterNextScan(pCsr->pIter);
- if( rc==SQLITE_OK ){
- rc = fts5VocabInstanceNewTerm(pCsr);
+ ){
+ pCsr->iInstPos = 0;
+ pCsr->iInstOff = 0;
+
+ rc = sqlite3Fts5IterNextScan(pCsr->pIter);
+ if( rc==SQLITE_OK ){
+ rc = fts5VocabInstanceNewTerm(pCsr);
if( pCsr->bEof || eDetail==FTS5_DETAIL_NONE ) break;
- }
- if( rc ){
- pCsr->bEof = 1;
- break;
- }
- }
-
- return rc;
-}
-
-/*
-** Advance the cursor to the next row in the table.
-*/
-static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
- Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
+ }
+ if( rc ){
+ pCsr->bEof = 1;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Advance the cursor to the next row in the table.
+*/
+static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+ Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
int nCol = pCsr->pFts5->pConfig->nCol;
int rc;
-
+
rc = sqlite3Fts5StructureTest(pCsr->pFts5->pIndex, pCsr->pStruct);
if( rc!=SQLITE_OK ) return rc;
- pCsr->rowid++;
-
- if( pTab->eType==FTS5_VOCAB_INSTANCE ){
- return fts5VocabInstanceNext(pCsr);
- }
-
- if( pTab->eType==FTS5_VOCAB_COL ){
- for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){
- if( pCsr->aDoc[pCsr->iCol] ) break;
- }
- }
-
- if( pTab->eType!=FTS5_VOCAB_COL || pCsr->iCol>=nCol ){
- if( sqlite3Fts5IterEof(pCsr->pIter) ){
- pCsr->bEof = 1;
- }else{
- const char *zTerm;
- int nTerm;
-
- zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
+ pCsr->rowid++;
+
+ if( pTab->eType==FTS5_VOCAB_INSTANCE ){
+ return fts5VocabInstanceNext(pCsr);
+ }
+
+ if( pTab->eType==FTS5_VOCAB_COL ){
+ for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){
+ if( pCsr->aDoc[pCsr->iCol] ) break;
+ }
+ }
+
+ if( pTab->eType!=FTS5_VOCAB_COL || pCsr->iCol>=nCol ){
+ if( sqlite3Fts5IterEof(pCsr->pIter) ){
+ pCsr->bEof = 1;
+ }else{
+ const char *zTerm;
+ int nTerm;
+
+ zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
assert( nTerm>=0 );
- if( pCsr->nLeTerm>=0 ){
- int nCmp = MIN(nTerm, pCsr->nLeTerm);
- int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
- if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
- pCsr->bEof = 1;
- return SQLITE_OK;
- }
- }
-
- sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
- memset(pCsr->aCnt, 0, nCol * sizeof(i64));
- memset(pCsr->aDoc, 0, nCol * sizeof(i64));
- pCsr->iCol = 0;
-
- assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
- while( rc==SQLITE_OK ){
+ if( pCsr->nLeTerm>=0 ){
+ int nCmp = MIN(nTerm, pCsr->nLeTerm);
+ int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
+ if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
+ pCsr->bEof = 1;
+ return SQLITE_OK;
+ }
+ }
+
+ sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
+ memset(pCsr->aCnt, 0, nCol * sizeof(i64));
+ memset(pCsr->aDoc, 0, nCol * sizeof(i64));
+ pCsr->iCol = 0;
+
+ assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
+ while( rc==SQLITE_OK ){
int eDetail = pCsr->pFts5->pConfig->eDetail;
- const u8 *pPos; int nPos; /* Position list */
- i64 iPos = 0; /* 64-bit position read from poslist */
- int iOff = 0; /* Current offset within position list */
-
- pPos = pCsr->pIter->pData;
- nPos = pCsr->pIter->nData;
-
- switch( pTab->eType ){
- case FTS5_VOCAB_ROW:
- if( eDetail==FTS5_DETAIL_FULL ){
- while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
- pCsr->aCnt[0]++;
- }
- }
- pCsr->aDoc[0]++;
- break;
-
- case FTS5_VOCAB_COL:
- if( eDetail==FTS5_DETAIL_FULL ){
- int iCol = -1;
- while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
- int ii = FTS5_POS2COLUMN(iPos);
- if( iCol!=ii ){
- if( ii>=nCol ){
- rc = FTS5_CORRUPT;
- break;
- }
- pCsr->aDoc[ii]++;
- iCol = ii;
- }
+ const u8 *pPos; int nPos; /* Position list */
+ i64 iPos = 0; /* 64-bit position read from poslist */
+ int iOff = 0; /* Current offset within position list */
+
+ pPos = pCsr->pIter->pData;
+ nPos = pCsr->pIter->nData;
+
+ switch( pTab->eType ){
+ case FTS5_VOCAB_ROW:
+ if( eDetail==FTS5_DETAIL_FULL ){
+ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
+ pCsr->aCnt[0]++;
+ }
+ }
+ pCsr->aDoc[0]++;
+ break;
+
+ case FTS5_VOCAB_COL:
+ if( eDetail==FTS5_DETAIL_FULL ){
+ int iCol = -1;
+ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
+ int ii = FTS5_POS2COLUMN(iPos);
+ if( iCol!=ii ){
+ if( ii>=nCol ){
+ rc = FTS5_CORRUPT;
+ break;
+ }
+ pCsr->aDoc[ii]++;
+ iCol = ii;
+ }
pCsr->aCnt[ii]++;
- }
- }else if( eDetail==FTS5_DETAIL_COLUMNS ){
- while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
- assert_nc( iPos>=0 && iPos<nCol );
- if( iPos>=nCol ){
- rc = FTS5_CORRUPT;
- break;
- }
- pCsr->aDoc[iPos]++;
- }
- }else{
- assert( eDetail==FTS5_DETAIL_NONE );
- pCsr->aDoc[0]++;
- }
- break;
-
- default:
- assert( pTab->eType==FTS5_VOCAB_INSTANCE );
- break;
- }
-
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5IterNextScan(pCsr->pIter);
- }
- if( pTab->eType==FTS5_VOCAB_INSTANCE ) break;
-
- if( rc==SQLITE_OK ){
- zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
+ }
+ }else if( eDetail==FTS5_DETAIL_COLUMNS ){
+ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
+ assert_nc( iPos>=0 && iPos<nCol );
+ if( iPos>=nCol ){
+ rc = FTS5_CORRUPT;
+ break;
+ }
+ pCsr->aDoc[iPos]++;
+ }
+ }else{
+ assert( eDetail==FTS5_DETAIL_NONE );
+ pCsr->aDoc[0]++;
+ }
+ break;
+
+ default:
+ assert( pTab->eType==FTS5_VOCAB_INSTANCE );
+ break;
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IterNextScan(pCsr->pIter);
+ }
+ if( pTab->eType==FTS5_VOCAB_INSTANCE ) break;
+
+ if( rc==SQLITE_OK ){
+ zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
if( nTerm!=pCsr->term.n
|| (nTerm>0 && memcmp(zTerm, pCsr->term.p, nTerm))
){
- break;
- }
- if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
- }
- }
- }
- }
-
- if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
+ break;
+ }
+ if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
+ }
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
for(/* noop */; pCsr->iCol<nCol && pCsr->aDoc[pCsr->iCol]==0; pCsr->iCol++);
if( pCsr->iCol==nCol ){
rc = FTS5_CORRUPT;
}
- }
- return rc;
-}
-
-/*
-** This is the xFilter implementation for the virtual table.
-*/
-static int fts5VocabFilterMethod(
- sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
- int idxNum, /* Strategy index */
- const char *zUnused, /* Unused */
- int nUnused, /* Number of elements in apVal */
- sqlite3_value **apVal /* Arguments for the indexing scheme */
-){
- Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
- int eType = pTab->eType;
- int rc = SQLITE_OK;
-
- int iVal = 0;
- int f = FTS5INDEX_QUERY_SCAN;
- const char *zTerm = 0;
- int nTerm = 0;
-
- sqlite3_value *pEq = 0;
- sqlite3_value *pGe = 0;
- sqlite3_value *pLe = 0;
-
- UNUSED_PARAM2(zUnused, nUnused);
-
- fts5VocabResetCursor(pCsr);
- if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
- if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
- if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
-
- if( pEq ){
- zTerm = (const char *)sqlite3_value_text(pEq);
- nTerm = sqlite3_value_bytes(pEq);
- f = 0;
- }else{
- if( pGe ){
- zTerm = (const char *)sqlite3_value_text(pGe);
- nTerm = sqlite3_value_bytes(pGe);
- }
- if( pLe ){
- const char *zCopy = (const char *)sqlite3_value_text(pLe);
+ }
+ return rc;
+}
+
+/*
+** This is the xFilter implementation for the virtual table.
+*/
+static int fts5VocabFilterMethod(
+ sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
+ int idxNum, /* Strategy index */
+ const char *zUnused, /* Unused */
+ int nUnused, /* Number of elements in apVal */
+ sqlite3_value **apVal /* Arguments for the indexing scheme */
+){
+ Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+ int eType = pTab->eType;
+ int rc = SQLITE_OK;
+
+ int iVal = 0;
+ int f = FTS5INDEX_QUERY_SCAN;
+ const char *zTerm = 0;
+ int nTerm = 0;
+
+ sqlite3_value *pEq = 0;
+ sqlite3_value *pGe = 0;
+ sqlite3_value *pLe = 0;
+
+ UNUSED_PARAM2(zUnused, nUnused);
+
+ fts5VocabResetCursor(pCsr);
+ if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
+ if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
+ if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
+
+ if( pEq ){
+ zTerm = (const char *)sqlite3_value_text(pEq);
+ nTerm = sqlite3_value_bytes(pEq);
+ f = 0;
+ }else{
+ if( pGe ){
+ zTerm = (const char *)sqlite3_value_text(pGe);
+ nTerm = sqlite3_value_bytes(pGe);
+ }
+ if( pLe ){
+ const char *zCopy = (const char *)sqlite3_value_text(pLe);
if( zCopy==0 ) zCopy = "";
- pCsr->nLeTerm = sqlite3_value_bytes(pLe);
- pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
- if( pCsr->zLeTerm==0 ){
- rc = SQLITE_NOMEM;
- }else{
- memcpy(pCsr->zLeTerm, zCopy, pCsr->nLeTerm+1);
- }
- }
- }
-
- if( rc==SQLITE_OK ){
+ pCsr->nLeTerm = sqlite3_value_bytes(pLe);
+ pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
+ if( pCsr->zLeTerm==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memcpy(pCsr->zLeTerm, zCopy, pCsr->nLeTerm+1);
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK ){
Fts5Index *pIndex = pCsr->pFts5->pIndex;
rc = sqlite3Fts5IndexQuery(pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
if( rc==SQLITE_OK ){
pCsr->pStruct = sqlite3Fts5StructureRef(pIndex);
}
- }
- if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){
- rc = fts5VocabInstanceNewTerm(pCsr);
- }
+ }
+ if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){
+ rc = fts5VocabInstanceNewTerm(pCsr);
+ }
if( rc==SQLITE_OK && !pCsr->bEof
&& (eType!=FTS5_VOCAB_INSTANCE
|| pCsr->pFts5->pConfig->eDetail!=FTS5_DETAIL_NONE)
- ){
- rc = fts5VocabNextMethod(pCursor);
- }
-
- return rc;
-}
-
+ ){
+ rc = fts5VocabNextMethod(pCursor);
+ }
+
+ return rc;
+}
+
/*
** This is the xEof method of the virtual table. SQLite calls this
-** routine to find out if it has reached the end of a result set.
-*/
-static int fts5VocabEofMethod(sqlite3_vtab_cursor *pCursor){
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
- return pCsr->bEof;
-}
-
-static int fts5VocabColumnMethod(
- sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
- sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */
- int iCol /* Index of column to read value from */
-){
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+** routine to find out if it has reached the end of a result set.
+*/
+static int fts5VocabEofMethod(sqlite3_vtab_cursor *pCursor){
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+ return pCsr->bEof;
+}
+
+static int fts5VocabColumnMethod(
+ sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
+ sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */
+ int iCol /* Index of column to read value from */
+){
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
int eDetail = pCsr->pFts5->pConfig->eDetail;
- int eType = ((Fts5VocabTable*)(pCursor->pVtab))->eType;
- i64 iVal = 0;
-
- if( iCol==0 ){
- sqlite3_result_text(
- pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT
- );
- }else if( eType==FTS5_VOCAB_COL ){
- assert( iCol==1 || iCol==2 || iCol==3 );
- if( iCol==1 ){
- if( eDetail!=FTS5_DETAIL_NONE ){
+ int eType = ((Fts5VocabTable*)(pCursor->pVtab))->eType;
+ i64 iVal = 0;
+
+ if( iCol==0 ){
+ sqlite3_result_text(
+ pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT
+ );
+ }else if( eType==FTS5_VOCAB_COL ){
+ assert( iCol==1 || iCol==2 || iCol==3 );
+ if( iCol==1 ){
+ if( eDetail!=FTS5_DETAIL_NONE ){
const char *z = pCsr->pFts5->pConfig->azCol[pCsr->iCol];
- sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
- }
- }else if( iCol==2 ){
- iVal = pCsr->aDoc[pCsr->iCol];
- }else{
- iVal = pCsr->aCnt[pCsr->iCol];
- }
- }else if( eType==FTS5_VOCAB_ROW ){
- assert( iCol==1 || iCol==2 );
- if( iCol==1 ){
- iVal = pCsr->aDoc[0];
- }else{
- iVal = pCsr->aCnt[0];
- }
- }else{
- assert( eType==FTS5_VOCAB_INSTANCE );
- switch( iCol ){
- case 1:
- sqlite3_result_int64(pCtx, pCsr->pIter->iRowid);
- break;
- case 2: {
- int ii = -1;
- if( eDetail==FTS5_DETAIL_FULL ){
- ii = FTS5_POS2COLUMN(pCsr->iInstPos);
- }else if( eDetail==FTS5_DETAIL_COLUMNS ){
- ii = (int)pCsr->iInstPos;
- }
+ sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
+ }
+ }else if( iCol==2 ){
+ iVal = pCsr->aDoc[pCsr->iCol];
+ }else{
+ iVal = pCsr->aCnt[pCsr->iCol];
+ }
+ }else if( eType==FTS5_VOCAB_ROW ){
+ assert( iCol==1 || iCol==2 );
+ if( iCol==1 ){
+ iVal = pCsr->aDoc[0];
+ }else{
+ iVal = pCsr->aCnt[0];
+ }
+ }else{
+ assert( eType==FTS5_VOCAB_INSTANCE );
+ switch( iCol ){
+ case 1:
+ sqlite3_result_int64(pCtx, pCsr->pIter->iRowid);
+ break;
+ case 2: {
+ int ii = -1;
+ if( eDetail==FTS5_DETAIL_FULL ){
+ ii = FTS5_POS2COLUMN(pCsr->iInstPos);
+ }else if( eDetail==FTS5_DETAIL_COLUMNS ){
+ ii = (int)pCsr->iInstPos;
+ }
if( ii>=0 && ii<pCsr->pFts5->pConfig->nCol ){
const char *z = pCsr->pFts5->pConfig->azCol[ii];
- sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
- }
- break;
- }
- default: {
- assert( iCol==3 );
- if( eDetail==FTS5_DETAIL_FULL ){
- int ii = FTS5_POS2OFFSET(pCsr->iInstPos);
- sqlite3_result_int(pCtx, ii);
- }
- break;
- }
- }
- }
-
- if( iVal>0 ) sqlite3_result_int64(pCtx, iVal);
- return SQLITE_OK;
-}
-
-/*
-** This is the xRowid method. The SQLite core calls this routine to
-** retrieve the rowid for the current row of the result set. The
-** rowid should be written to *pRowid.
-*/
-static int fts5VocabRowidMethod(
+ sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
+ }
+ break;
+ }
+ default: {
+ assert( iCol==3 );
+ if( eDetail==FTS5_DETAIL_FULL ){
+ int ii = FTS5_POS2OFFSET(pCsr->iInstPos);
+ sqlite3_result_int(pCtx, ii);
+ }
+ break;
+ }
+ }
+ }
+
+ if( iVal>0 ) sqlite3_result_int64(pCtx, iVal);
+ return SQLITE_OK;
+}
+
+/*
+** This is the xRowid method. The SQLite core calls this routine to
+** retrieve the rowid for the current row of the result set. The
+** rowid should be written to *pRowid.
+*/
+static int fts5VocabRowidMethod(
sqlite3_vtab_cursor *pCursor,
- sqlite_int64 *pRowid
-){
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
- *pRowid = pCsr->rowid;
- return SQLITE_OK;
-}
-
-static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){
- static const sqlite3_module fts5Vocab = {
- /* iVersion */ 2,
- /* xCreate */ fts5VocabCreateMethod,
- /* xConnect */ fts5VocabConnectMethod,
- /* xBestIndex */ fts5VocabBestIndexMethod,
- /* xDisconnect */ fts5VocabDisconnectMethod,
- /* xDestroy */ fts5VocabDestroyMethod,
- /* xOpen */ fts5VocabOpenMethod,
- /* xClose */ fts5VocabCloseMethod,
- /* xFilter */ fts5VocabFilterMethod,
- /* xNext */ fts5VocabNextMethod,
- /* xEof */ fts5VocabEofMethod,
- /* xColumn */ fts5VocabColumnMethod,
- /* xRowid */ fts5VocabRowidMethod,
- /* xUpdate */ 0,
- /* xBegin */ 0,
- /* xSync */ 0,
- /* xCommit */ 0,
- /* xRollback */ 0,
- /* xFindFunction */ 0,
- /* xRename */ 0,
- /* xSavepoint */ 0,
- /* xRelease */ 0,
- /* xRollbackTo */ 0,
+ sqlite_int64 *pRowid
+){
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+ *pRowid = pCsr->rowid;
+ return SQLITE_OK;
+}
+
+static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){
+ static const sqlite3_module fts5Vocab = {
+ /* iVersion */ 2,
+ /* xCreate */ fts5VocabCreateMethod,
+ /* xConnect */ fts5VocabConnectMethod,
+ /* xBestIndex */ fts5VocabBestIndexMethod,
+ /* xDisconnect */ fts5VocabDisconnectMethod,
+ /* xDestroy */ fts5VocabDestroyMethod,
+ /* xOpen */ fts5VocabOpenMethod,
+ /* xClose */ fts5VocabCloseMethod,
+ /* xFilter */ fts5VocabFilterMethod,
+ /* xNext */ fts5VocabNextMethod,
+ /* xEof */ fts5VocabEofMethod,
+ /* xColumn */ fts5VocabColumnMethod,
+ /* xRowid */ fts5VocabRowidMethod,
+ /* xUpdate */ 0,
+ /* xBegin */ 0,
+ /* xSync */ 0,
+ /* xCommit */ 0,
+ /* xRollback */ 0,
+ /* xFindFunction */ 0,
+ /* xRename */ 0,
+ /* xSavepoint */ 0,
+ /* xRelease */ 0,
+ /* xRollbackTo */ 0,
/* xShadowName */ 0
- };
- void *p = (void*)pGlobal;
-
- return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
-}
-
-
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
-
-/************** End of fts5.c ************************************************/
-/************** Begin file stmt.c ********************************************/
-/*
-** 2017-05-31
-**
-** 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 demonstrates an eponymous virtual table that returns information
-** about all prepared statements for the database connection.
-**
-** Usage example:
-**
-** .load ./stmt
-** .mode line
-** .header on
-** SELECT * FROM stmt;
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB)
-#if !defined(SQLITEINT_H)
-/* #include "sqlite3ext.h" */
-#endif
-SQLITE_EXTENSION_INIT1
-/* #include <assert.h> */
-/* #include <string.h> */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-
-/* stmt_vtab is a subclass of sqlite3_vtab which will
-** serve as the underlying representation of a stmt virtual table
-*/
-typedef struct stmt_vtab stmt_vtab;
-struct stmt_vtab {
- sqlite3_vtab base; /* Base class - must be first */
- sqlite3 *db; /* Database connection for this stmt vtab */
-};
-
-/* stmt_cursor is a subclass of sqlite3_vtab_cursor which will
-** serve as the underlying representation of a cursor that scans
-** over rows of the result
-*/
-typedef struct stmt_cursor stmt_cursor;
-struct stmt_cursor {
- sqlite3_vtab_cursor base; /* Base class - must be first */
- sqlite3 *db; /* Database connection for this cursor */
- sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */
- sqlite3_int64 iRowid; /* The rowid */
-};
-
-/*
-** The stmtConnect() method is invoked to create a new
-** stmt_vtab that describes the stmt virtual table.
-**
-** Think of this routine as the constructor for stmt_vtab objects.
-**
-** All this routine needs to do is:
-**
-** (1) Allocate the stmt_vtab object and initialize all fields.
-**
-** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
-** result set of queries against stmt will look like.
-*/
-static int stmtConnect(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- stmt_vtab *pNew;
- int rc;
-
-/* Column numbers */
-#define STMT_COLUMN_SQL 0 /* SQL for the statement */
-#define STMT_COLUMN_NCOL 1 /* Number of result columns */
-#define STMT_COLUMN_RO 2 /* True if read-only */
-#define STMT_COLUMN_BUSY 3 /* True if currently busy */
-#define STMT_COLUMN_NSCAN 4 /* SQLITE_STMTSTATUS_FULLSCAN_STEP */
-#define STMT_COLUMN_NSORT 5 /* SQLITE_STMTSTATUS_SORT */
-#define STMT_COLUMN_NAIDX 6 /* SQLITE_STMTSTATUS_AUTOINDEX */
-#define STMT_COLUMN_NSTEP 7 /* SQLITE_STMTSTATUS_VM_STEP */
-#define STMT_COLUMN_REPREP 8 /* SQLITE_STMTSTATUS_REPREPARE */
-#define STMT_COLUMN_RUN 9 /* SQLITE_STMTSTATUS_RUN */
-#define STMT_COLUMN_MEM 10 /* SQLITE_STMTSTATUS_MEMUSED */
-
-
- rc = sqlite3_declare_vtab(db,
- "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
- "reprep,run,mem)");
- if( rc==SQLITE_OK ){
- pNew = sqlite3_malloc( sizeof(*pNew) );
- *ppVtab = (sqlite3_vtab*)pNew;
- if( pNew==0 ) return SQLITE_NOMEM;
- memset(pNew, 0, sizeof(*pNew));
- pNew->db = db;
- }
- return rc;
-}
-
-/*
-** This method is the destructor for stmt_cursor objects.
-*/
-static int stmtDisconnect(sqlite3_vtab *pVtab){
- sqlite3_free(pVtab);
- return SQLITE_OK;
-}
-
-/*
-** Constructor for a new stmt_cursor object.
-*/
-static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
- stmt_cursor *pCur;
- pCur = sqlite3_malloc( sizeof(*pCur) );
- if( pCur==0 ) return SQLITE_NOMEM;
- memset(pCur, 0, sizeof(*pCur));
- pCur->db = ((stmt_vtab*)p)->db;
- *ppCursor = &pCur->base;
- return SQLITE_OK;
-}
-
-/*
-** Destructor for a stmt_cursor.
-*/
-static int stmtClose(sqlite3_vtab_cursor *cur){
- sqlite3_free(cur);
- return SQLITE_OK;
-}
-
-
-/*
-** Advance a stmt_cursor to its next row of output.
-*/
-static int stmtNext(sqlite3_vtab_cursor *cur){
- stmt_cursor *pCur = (stmt_cursor*)cur;
- pCur->iRowid++;
- pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt);
- return SQLITE_OK;
-}
-
-/*
-** Return values of columns for the row at which the stmt_cursor
-** is currently pointing.
-*/
-static int stmtColumn(
- sqlite3_vtab_cursor *cur, /* The cursor */
- sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
- int i /* Which column to return */
-){
- stmt_cursor *pCur = (stmt_cursor*)cur;
- switch( i ){
- case STMT_COLUMN_SQL: {
- sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT);
- break;
- }
- case STMT_COLUMN_NCOL: {
- sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt));
- break;
- }
- case STMT_COLUMN_RO: {
- sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt));
- break;
- }
- case STMT_COLUMN_BUSY: {
- sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
- break;
- }
+ };
+ void *p = (void*)pGlobal;
+
+ return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
+}
+
+
+
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
+
+/************** End of fts5.c ************************************************/
+/************** Begin file stmt.c ********************************************/
+/*
+** 2017-05-31
+**
+** 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 demonstrates an eponymous virtual table that returns information
+** about all prepared statements for the database connection.
+**
+** Usage example:
+**
+** .load ./stmt
+** .mode line
+** .header on
+** SELECT * FROM stmt;
+*/
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB)
+#if !defined(SQLITEINT_H)
+/* #include "sqlite3ext.h" */
+#endif
+SQLITE_EXTENSION_INIT1
+/* #include <assert.h> */
+/* #include <string.h> */
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+
+/* stmt_vtab is a subclass of sqlite3_vtab which will
+** serve as the underlying representation of a stmt virtual table
+*/
+typedef struct stmt_vtab stmt_vtab;
+struct stmt_vtab {
+ sqlite3_vtab base; /* Base class - must be first */
+ sqlite3 *db; /* Database connection for this stmt vtab */
+};
+
+/* stmt_cursor is a subclass of sqlite3_vtab_cursor which will
+** serve as the underlying representation of a cursor that scans
+** over rows of the result
+*/
+typedef struct stmt_cursor stmt_cursor;
+struct stmt_cursor {
+ sqlite3_vtab_cursor base; /* Base class - must be first */
+ sqlite3 *db; /* Database connection for this cursor */
+ sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */
+ sqlite3_int64 iRowid; /* The rowid */
+};
+
+/*
+** The stmtConnect() method is invoked to create a new
+** stmt_vtab that describes the stmt virtual table.
+**
+** Think of this routine as the constructor for stmt_vtab objects.
+**
+** All this routine needs to do is:
+**
+** (1) Allocate the stmt_vtab object and initialize all fields.
+**
+** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
+** result set of queries against stmt will look like.
+*/
+static int stmtConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ stmt_vtab *pNew;
+ int rc;
+
+/* Column numbers */
+#define STMT_COLUMN_SQL 0 /* SQL for the statement */
+#define STMT_COLUMN_NCOL 1 /* Number of result columns */
+#define STMT_COLUMN_RO 2 /* True if read-only */
+#define STMT_COLUMN_BUSY 3 /* True if currently busy */
+#define STMT_COLUMN_NSCAN 4 /* SQLITE_STMTSTATUS_FULLSCAN_STEP */
+#define STMT_COLUMN_NSORT 5 /* SQLITE_STMTSTATUS_SORT */
+#define STMT_COLUMN_NAIDX 6 /* SQLITE_STMTSTATUS_AUTOINDEX */
+#define STMT_COLUMN_NSTEP 7 /* SQLITE_STMTSTATUS_VM_STEP */
+#define STMT_COLUMN_REPREP 8 /* SQLITE_STMTSTATUS_REPREPARE */
+#define STMT_COLUMN_RUN 9 /* SQLITE_STMTSTATUS_RUN */
+#define STMT_COLUMN_MEM 10 /* SQLITE_STMTSTATUS_MEMUSED */
+
+
+ rc = sqlite3_declare_vtab(db,
+ "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
+ "reprep,run,mem)");
+ if( rc==SQLITE_OK ){
+ pNew = sqlite3_malloc( sizeof(*pNew) );
+ *ppVtab = (sqlite3_vtab*)pNew;
+ if( pNew==0 ) return SQLITE_NOMEM;
+ memset(pNew, 0, sizeof(*pNew));
+ pNew->db = db;
+ }
+ return rc;
+}
+
+/*
+** This method is the destructor for stmt_cursor objects.
+*/
+static int stmtDisconnect(sqlite3_vtab *pVtab){
+ sqlite3_free(pVtab);
+ return SQLITE_OK;
+}
+
+/*
+** Constructor for a new stmt_cursor object.
+*/
+static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+ stmt_cursor *pCur;
+ pCur = sqlite3_malloc( sizeof(*pCur) );
+ if( pCur==0 ) return SQLITE_NOMEM;
+ memset(pCur, 0, sizeof(*pCur));
+ pCur->db = ((stmt_vtab*)p)->db;
+ *ppCursor = &pCur->base;
+ return SQLITE_OK;
+}
+
+/*
+** Destructor for a stmt_cursor.
+*/
+static int stmtClose(sqlite3_vtab_cursor *cur){
+ sqlite3_free(cur);
+ return SQLITE_OK;
+}
+
+
+/*
+** Advance a stmt_cursor to its next row of output.
+*/
+static int stmtNext(sqlite3_vtab_cursor *cur){
+ stmt_cursor *pCur = (stmt_cursor*)cur;
+ pCur->iRowid++;
+ pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt);
+ return SQLITE_OK;
+}
+
+/*
+** Return values of columns for the row at which the stmt_cursor
+** is currently pointing.
+*/
+static int stmtColumn(
+ sqlite3_vtab_cursor *cur, /* The cursor */
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
+ int i /* Which column to return */
+){
+ stmt_cursor *pCur = (stmt_cursor*)cur;
+ switch( i ){
+ case STMT_COLUMN_SQL: {
+ sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT);
+ break;
+ }
+ case STMT_COLUMN_NCOL: {
+ sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt));
+ break;
+ }
+ case STMT_COLUMN_RO: {
+ sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt));
+ break;
+ }
+ case STMT_COLUMN_BUSY: {
+ sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
+ break;
+ }
default: {
assert( i==STMT_COLUMN_MEM );
i = SQLITE_STMTSTATUS_MEMUSED +
- STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
- /* Fall thru */
- }
- case STMT_COLUMN_NSCAN:
- case STMT_COLUMN_NSORT:
- case STMT_COLUMN_NAIDX:
- case STMT_COLUMN_NSTEP:
- case STMT_COLUMN_REPREP:
- case STMT_COLUMN_RUN: {
- sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt,
- i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0));
- break;
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** Return the rowid for the current row. In this implementation, the
-** rowid is the same as the output value.
-*/
-static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
- stmt_cursor *pCur = (stmt_cursor*)cur;
- *pRowid = pCur->iRowid;
- return SQLITE_OK;
-}
-
-/*
-** Return TRUE if the cursor has been moved off of the last
-** row of output.
-*/
-static int stmtEof(sqlite3_vtab_cursor *cur){
- stmt_cursor *pCur = (stmt_cursor*)cur;
- return pCur->pStmt==0;
-}
-
-/*
-** This method is called to "rewind" the stmt_cursor object back
-** to the first row of output. This method is always called at least
+ STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
+ /* Fall thru */
+ }
+ case STMT_COLUMN_NSCAN:
+ case STMT_COLUMN_NSORT:
+ case STMT_COLUMN_NAIDX:
+ case STMT_COLUMN_NSTEP:
+ case STMT_COLUMN_REPREP:
+ case STMT_COLUMN_RUN: {
+ sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt,
+ i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0));
+ break;
+ }
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Return the rowid for the current row. In this implementation, the
+** rowid is the same as the output value.
+*/
+static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+ stmt_cursor *pCur = (stmt_cursor*)cur;
+ *pRowid = pCur->iRowid;
+ return SQLITE_OK;
+}
+
+/*
+** Return TRUE if the cursor has been moved off of the last
+** row of output.
+*/
+static int stmtEof(sqlite3_vtab_cursor *cur){
+ stmt_cursor *pCur = (stmt_cursor*)cur;
+ return pCur->pStmt==0;
+}
+
+/*
+** This method is called to "rewind" the stmt_cursor object back
+** to the first row of output. This method is always called at least
** once prior to any call to stmtColumn() or stmtRowid() or
-** stmtEof().
-*/
-static int stmtFilter(
+** stmtEof().
+*/
+static int stmtFilter(
sqlite3_vtab_cursor *pVtabCursor,
- int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv
-){
- stmt_cursor *pCur = (stmt_cursor *)pVtabCursor;
- pCur->pStmt = 0;
- pCur->iRowid = 0;
- return stmtNext(pVtabCursor);
-}
-
-/*
-** SQLite will invoke this method one or more times while planning a query
-** that uses the stmt virtual table. This routine needs to create
-** a query plan for each invocation and compute an estimated cost for that
-** plan.
-*/
-static int stmtBestIndex(
- sqlite3_vtab *tab,
- sqlite3_index_info *pIdxInfo
-){
- pIdxInfo->estimatedCost = (double)500;
- pIdxInfo->estimatedRows = 500;
- return SQLITE_OK;
-}
-
-/*
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ stmt_cursor *pCur = (stmt_cursor *)pVtabCursor;
+ pCur->pStmt = 0;
+ pCur->iRowid = 0;
+ return stmtNext(pVtabCursor);
+}
+
+/*
+** SQLite will invoke this method one or more times while planning a query
+** that uses the stmt virtual table. This routine needs to create
+** a query plan for each invocation and compute an estimated cost for that
+** plan.
+*/
+static int stmtBestIndex(
+ sqlite3_vtab *tab,
+ sqlite3_index_info *pIdxInfo
+){
+ pIdxInfo->estimatedCost = (double)500;
+ pIdxInfo->estimatedRows = 500;
+ return SQLITE_OK;
+}
+
+/*
** This following structure defines all the methods for the
-** stmt virtual table.
-*/
-static sqlite3_module stmtModule = {
- 0, /* iVersion */
- 0, /* xCreate */
- stmtConnect, /* xConnect */
- stmtBestIndex, /* xBestIndex */
- stmtDisconnect, /* xDisconnect */
- 0, /* xDestroy */
- stmtOpen, /* xOpen - open a cursor */
- stmtClose, /* xClose - close a cursor */
- stmtFilter, /* xFilter - configure scan constraints */
- stmtNext, /* xNext - advance a cursor */
- stmtEof, /* xEof - check for end of scan */
- stmtColumn, /* xColumn - read data */
- stmtRowid, /* xRowid - read data */
- 0, /* xUpdate */
- 0, /* xBegin */
- 0, /* xSync */
- 0, /* xCommit */
- 0, /* xRollback */
- 0, /* xFindMethod */
- 0, /* xRename */
- 0, /* xSavepoint */
- 0, /* xRelease */
- 0, /* xRollbackTo */
+** stmt virtual table.
+*/
+static sqlite3_module stmtModule = {
+ 0, /* iVersion */
+ 0, /* xCreate */
+ stmtConnect, /* xConnect */
+ stmtBestIndex, /* xBestIndex */
+ stmtDisconnect, /* xDisconnect */
+ 0, /* xDestroy */
+ stmtOpen, /* xOpen - open a cursor */
+ stmtClose, /* xClose - close a cursor */
+ stmtFilter, /* xFilter - configure scan constraints */
+ stmtNext, /* xNext - advance a cursor */
+ stmtEof, /* xEof - check for end of scan */
+ stmtColumn, /* xColumn - read data */
+ stmtRowid, /* xRowid - read data */
+ 0, /* xUpdate */
+ 0, /* xBegin */
+ 0, /* xSync */
+ 0, /* xCommit */
+ 0, /* xRollback */
+ 0, /* xFindMethod */
+ 0, /* xRename */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0, /* xRollbackTo */
0, /* xShadowName */
-};
-
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3 *db){
- int rc = SQLITE_OK;
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- rc = sqlite3_create_module(db, "sqlite_stmt", &stmtModule, 0);
-#endif
- return rc;
-}
-
-#ifndef SQLITE_CORE
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-SQLITE_API int sqlite3_stmt_init(
+};
+
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3 *db){
+ int rc = SQLITE_OK;
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ rc = sqlite3_create_module(db, "sqlite_stmt", &stmtModule, 0);
+#endif
+ return rc;
+}
+
+#ifndef SQLITE_CORE
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int sqlite3_stmt_init(
sqlite3 *db,
char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- int rc = SQLITE_OK;
- SQLITE_EXTENSION_INIT2(pApi);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- rc = sqlite3StmtVtabInit(db);
-#endif
- return rc;
-}
-#endif /* SQLITE_CORE */
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
-
-/************** End of stmt.c ************************************************/
-/* Return the source-id for this library */
-SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
-/************************** End of sqlite3.c ******************************/
+ const sqlite3_api_routines *pApi
+){
+ int rc = SQLITE_OK;
+ SQLITE_EXTENSION_INIT2(pApi);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ rc = sqlite3StmtVtabInit(db);
+#endif
+ return rc;
+}
+#endif /* SQLITE_CORE */
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
+
+/************** End of stmt.c ************************************************/
+/* Return the source-id for this library */
+SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
+/************************** End of sqlite3.c ******************************/
diff --git a/contrib/libs/sqlite3/sqlite3.h b/contrib/libs/sqlite3/sqlite3.h
index cf299bb3dee..4463e8ec135 100644
--- a/contrib/libs/sqlite3/sqlite3.h
+++ b/contrib/libs/sqlite3/sqlite3.h
@@ -1,5 +1,5 @@
/*
-** 2001-09-15
+** 2001-09-15
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -30,8 +30,8 @@
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
*/
-#ifndef SQLITE3_H
-#define SQLITE3_H
+#ifndef SQLITE3_H
+#define SQLITE3_H
#include <stdarg.h> /* Needed for the definition of va_list */
/*
@@ -77,18 +77,18 @@ extern "C" {
#ifndef SQLITE_CDECL
# define SQLITE_CDECL
#endif
-#ifndef SQLITE_APICALL
-# define SQLITE_APICALL
-#endif
+#ifndef SQLITE_APICALL
+# define SQLITE_APICALL
+#endif
#ifndef SQLITE_STDCALL
-# define SQLITE_STDCALL SQLITE_APICALL
+# define SQLITE_STDCALL SQLITE_APICALL
+#endif
+#ifndef SQLITE_CALLBACK
+# define SQLITE_CALLBACK
+#endif
+#ifndef SQLITE_SYSAPI
+# define SQLITE_SYSAPI
#endif
-#ifndef SQLITE_CALLBACK
-# define SQLITE_CALLBACK
-#endif
-#ifndef SQLITE_SYSAPI
-# define SQLITE_SYSAPI
-#endif
/*
** These no-op macros are used in front of interfaces to mark those
@@ -132,15 +132,15 @@ extern "C" {
** and Z will be reset to zero.
**
** Since [version 3.6.18] ([dateof:3.6.18]),
-** SQLite source code has been stored in the
+** SQLite source code has been stored in the
** <a href="http://www.fossil-scm.org/">Fossil configuration management
** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to
** a string which identifies a particular check-in of SQLite
** within its configuration management system. ^The SQLITE_SOURCE_ID
-** string contains the date and time of the check-in (UTC) and a SHA1
-** or SHA3-256 hash of the entire source tree. If the source code has
-** been edited in any way since it was last checked in, then the last
-** four hexadecimal digits of the hash may be modified.
+** string contains the date and time of the check-in (UTC) and a SHA1
+** or SHA3-256 hash of the entire source tree. If the source code has
+** been edited in any way since it was last checked in, then the last
+** four hexadecimal digits of the hash may be modified.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
@@ -152,19 +152,19 @@ extern "C" {
/*
** CAPI3REF: Run-Time Library Version Numbers
-** KEYWORDS: sqlite3_version sqlite3_sourceid
+** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
** but are associated with the library instead of the header file. ^(Cautious
** programmers might include assert() statements in their application to
** verify that values returned by these interfaces match the macros in
-** the header, and thus ensure that the application is
+** the header, and thus ensure that the application is
** compiled with matching library and header files.
**
** <blockquote><pre>
** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
+** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
** </pre></blockquote>)^
**
@@ -176,16 +176,16 @@ extern "C" {
** sqlite3_libversion_number() function returns an integer equal to
** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns
** a pointer to a string constant whose value is the same as the
-** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built
-** using an edited copy of [the amalgamation], then the last four characters
-** of the hash might be different from [SQLITE_SOURCE_ID].)^
+** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built
+** using an edited copy of [the amalgamation], then the last four characters
+** of the hash might be different from [SQLITE_SOURCE_ID].)^
**
** See also: [sqlite_version()] and [sqlite_source_id()].
*/
SQLITE_API SQLITE_EXTERN const char sqlite3_version[];
-SQLITE_API const char *sqlite3_libversion(void);
-SQLITE_API const char *sqlite3_sourceid(void);
-SQLITE_API int sqlite3_libversion_number(void);
+SQLITE_API const char *sqlite3_libversion(void);
+SQLITE_API const char *sqlite3_sourceid(void);
+SQLITE_API int sqlite3_libversion_number(void);
/*
** CAPI3REF: Run-Time Library Compilation Options Diagnostics
@@ -210,8 +210,8 @@ SQLITE_API int sqlite3_libversion_number(void);
** [sqlite_compileoption_get()] and the [compile_options pragma].
*/
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
-SQLITE_API const char *sqlite3_compileoption_get(int N);
+SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
+SQLITE_API const char *sqlite3_compileoption_get(int N);
#else
# define sqlite3_compileoption_used(X) 0
# define sqlite3_compileoption_get(X) ((void*)0)
@@ -253,7 +253,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N);
**
** See the [threading mode] documentation for additional information.
*/
-SQLITE_API int sqlite3_threadsafe(void);
+SQLITE_API int sqlite3_threadsafe(void);
/*
** CAPI3REF: Database Connection Handle
@@ -289,11 +289,11 @@ typedef struct sqlite3 sqlite3;
*/
#ifdef SQLITE_INT64_TYPE
typedef SQLITE_INT64_TYPE sqlite_int64;
-# ifdef SQLITE_UINT64_TYPE
- typedef SQLITE_UINT64_TYPE sqlite_uint64;
+# ifdef SQLITE_UINT64_TYPE
+ typedef SQLITE_UINT64_TYPE sqlite_uint64;
# else
- typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
-# endif
+ typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
+# endif
#elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 sqlite_int64;
typedef unsigned __int64 sqlite_uint64;
@@ -350,8 +350,8 @@ typedef sqlite_uint64 sqlite3_uint64;
** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
** argument is a harmless no-op.
*/
-SQLITE_API int sqlite3_close(sqlite3*);
-SQLITE_API int sqlite3_close_v2(sqlite3*);
+SQLITE_API int sqlite3_close(sqlite3*);
+SQLITE_API int sqlite3_close_v2(sqlite3*);
/*
** The type for a callback function.
@@ -387,7 +387,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** from [sqlite3_malloc()] and passed back through the 5th parameter.
** To avoid memory leaks, the application should invoke [sqlite3_free()]
** on error message strings returned through the 5th parameter of
-** sqlite3_exec() after the error message string is no longer needed.
+** sqlite3_exec() after the error message string is no longer needed.
** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors
** occur, then sqlite3_exec() sets the pointer in its 5th parameter to
** NULL before returning.
@@ -414,7 +414,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** Restrictions:
**
** <ul>
-** <li> The application must ensure that the 1st parameter to sqlite3_exec()
+** <li> The application must ensure that the 1st parameter to sqlite3_exec()
** is a valid and open [database connection].
** <li> The application must not close the [database connection] specified by
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
@@ -422,7 +422,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
** </ul>
*/
-SQLITE_API int sqlite3_exec(
+SQLITE_API int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
@@ -443,7 +443,7 @@ SQLITE_API int sqlite3_exec(
*/
#define SQLITE_OK 0 /* Successful result */
/* beginning-of-error-codes */
-#define SQLITE_ERROR 1 /* Generic error */
+#define SQLITE_ERROR 1 /* Generic error */
#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */
#define SQLITE_PERM 3 /* Access permission denied */
#define SQLITE_ABORT 4 /* Callback routine requested an abort */
@@ -458,7 +458,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_FULL 13 /* Insertion failed because database is full */
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
-#define SQLITE_EMPTY 16 /* Internal use only */
+#define SQLITE_EMPTY 16 /* Internal use only */
#define SQLITE_SCHEMA 17 /* The database schema changed */
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
@@ -466,7 +466,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_MISUSE 21 /* Library used incorrectly */
#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
#define SQLITE_AUTH 23 /* Authorization denied */
-#define SQLITE_FORMAT 24 /* Not used */
+#define SQLITE_FORMAT 24 /* Not used */
#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */
@@ -483,8 +483,8 @@ SQLITE_API int sqlite3_exec(
** [result codes]. However, experience has shown that many of
** these result codes are too coarse-grained. They do not provide as
** much information about problems as programmers might like. In an effort to
-** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8]
-** and later) include
+** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8]
+** and later) include
** support for additional result codes that provide more detailed information
** about errors. These [extended result codes] are enabled or disabled
** on a per database connection basis using the
@@ -492,8 +492,8 @@ SQLITE_API int sqlite3_exec(
** the most recent error can be obtained using
** [sqlite3_extended_errcode()].
*/
-#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
-#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
+#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
+#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8))
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
@@ -521,11 +521,11 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
-#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
-#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
-#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
-#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
-#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
+#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
+#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
+#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
+#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
+#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
#define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
@@ -546,8 +546,8 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
-#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
-#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8))
+#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
+#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
@@ -565,7 +565,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
-#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
+#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
/*
@@ -639,15 +639,15 @@ SQLITE_API int sqlite3_exec(
** file that were written at the application level might have changed
** and that adjacent bytes, even bytes within the same sector are
** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
-** flag indicates that a file cannot be deleted when open. The
+** flag indicates that a file cannot be deleted when open. The
** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
** read-only media and cannot be changed even by processes with
** elevated privileges.
-**
-** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying
-** filesystem supports doing multiple write operations atomically when those
-** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
-** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
+**
+** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying
+** filesystem supports doing multiple write operations atomically when those
+** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
+** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@@ -663,7 +663,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800
#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
#define SQLITE_IOCAP_IMMUTABLE 0x00002000
-#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000
+#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000
/*
** CAPI3REF: File Locking Levels
@@ -795,10 +795,10 @@ struct sqlite3_file {
** <li> [SQLITE_IOCAP_ATOMIC64K]
** <li> [SQLITE_IOCAP_SAFE_APPEND]
** <li> [SQLITE_IOCAP_SEQUENTIAL]
-** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
-** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
-** <li> [SQLITE_IOCAP_IMMUTABLE]
-** <li> [SQLITE_IOCAP_BATCH_ATOMIC]
+** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
+** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
+** <li> [SQLITE_IOCAP_IMMUTABLE]
+** <li> [SQLITE_IOCAP_BATCH_ATOMIC]
** </ul>
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
@@ -892,14 +892,14 @@ struct sqlite3_io_methods {
** <li>[[SQLITE_FCNTL_FILE_POINTER]]
** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer
** to the [sqlite3_file] object associated with a particular database
-** connection. See also [SQLITE_FCNTL_JOURNAL_POINTER].
-**
-** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]]
-** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer
-** to the [sqlite3_file] object associated with the journal file (either
-** the [rollback journal] or the [write-ahead log]) for a particular database
-** connection. See also [SQLITE_FCNTL_FILE_POINTER].
-**
+** connection. See also [SQLITE_FCNTL_JOURNAL_POINTER].
+**
+** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]]
+** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer
+** to the [sqlite3_file] object associated with the journal file (either
+** the [rollback journal] or the [write-ahead log]) for a particular database
+** connection. See also [SQLITE_FCNTL_FILE_POINTER].
+**
** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
** No longer in use.
**
@@ -936,7 +936,7 @@ struct sqlite3_io_methods {
** opcode allows these two values (10 retries and 25 milliseconds of delay)
** to be adjusted. The values are changed for all database connections
** within the same process. The argument is a pointer to an array of two
-** integers where the first integer is the new retry count and the second
+** integers where the first integer is the new retry count and the second
** integer is the delay. If either integer is negative, then the setting
** is not changed but instead the prior value of that setting is written
** into the array entry, allowing the current retry settings to be
@@ -986,15 +986,15 @@ struct sqlite3_io_methods {
** pointer in case this file-control is not implemented. This file-control
** is intended for diagnostic use only.
**
-** <li>[[SQLITE_FCNTL_VFS_POINTER]]
-** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level
-** [VFSes] currently in use. ^(The argument X in
-** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be
-** of type "[sqlite3_vfs] **". This opcodes will set *X
-** to a pointer to the top-level VFS.)^
-** ^When there are multiple VFS shims in the stack, this opcode finds the
-** upper-most shim only.
-**
+** <li>[[SQLITE_FCNTL_VFS_POINTER]]
+** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level
+** [VFSes] currently in use. ^(The argument X in
+** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be
+** of type "[sqlite3_vfs] **". This opcodes will set *X
+** to a pointer to the top-level VFS.)^
+** ^When there are multiple VFS shims in the stack, this opcode finds the
+** upper-most shim only.
+**
** <li>[[SQLITE_FCNTL_PRAGMA]]
** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA]
** file control is sent to the open [sqlite3_file] object corresponding
@@ -1065,12 +1065,12 @@ struct sqlite3_io_methods {
** on whether or not the file has been renamed, moved, or deleted since it
** was first opened.
**
-** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
-** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
-** underlying native file handle associated with a file handle. This file
-** control interprets its argument as a pointer to a native file handle and
-** writes the resulting value there.
-**
+** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
+** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
+** underlying native file handle associated with a file handle. This file
+** control interprets its argument as a pointer to a native file handle and
+** writes the resulting value there.
+**
** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
** opcode causes the xFileControl method to swap the file handle with the one
@@ -1092,40 +1092,40 @@ struct sqlite3_io_methods {
** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for
** this opcode.
-**
-** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]]
-** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then
-** the file descriptor is placed in "batch write mode", which
-** means all subsequent write operations will be deferred and done
-** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. Systems
-** that do not support batch atomic writes will return SQLITE_NOTFOUND.
-** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to
-** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or
-** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make
-** no VFS interface calls on the same [sqlite3_file] file descriptor
-** except for calls to the xWrite method and the xFileControl method
-** with [SQLITE_FCNTL_SIZE_HINT].
-**
-** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]]
-** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write
+**
+** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]]
+** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then
+** the file descriptor is placed in "batch write mode", which
+** means all subsequent write operations will be deferred and done
+** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. Systems
+** that do not support batch atomic writes will return SQLITE_NOTFOUND.
+** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to
+** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or
+** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make
+** no VFS interface calls on the same [sqlite3_file] file descriptor
+** except for calls to the xWrite method and the xFileControl method
+** with [SQLITE_FCNTL_SIZE_HINT].
+**
+** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]]
+** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write
** operations since the previous successful call to
-** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically.
-** This file control returns [SQLITE_OK] if and only if the writes were
-** all performed successfully and have been committed to persistent storage.
-** ^Regardless of whether or not it is successful, this file control takes
-** the file descriptor out of batch write mode so that all subsequent
-** write operations are independent.
-** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without
-** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
-**
-** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]]
-** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write
+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically.
+** This file control returns [SQLITE_OK] if and only if the writes were
+** all performed successfully and have been committed to persistent storage.
+** ^Regardless of whether or not it is successful, this file control takes
+** the file descriptor out of batch write mode so that all subsequent
+** write operations are independent.
+** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without
+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
+**
+** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]]
+** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write
** operations since the previous successful call to
-** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
-** ^This file control takes the file descriptor out of batch write mode
-** so that all subsequent write operations are independent.
-** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
-** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
+** ^This file control takes the file descriptor out of batch write mode
+** so that all subsequent write operations are independent.
+** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
**
** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS
@@ -1209,13 +1209,13 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_WAL_BLOCK 24
#define SQLITE_FCNTL_ZIPVFS 25
#define SQLITE_FCNTL_RBU 26
-#define SQLITE_FCNTL_VFS_POINTER 27
-#define SQLITE_FCNTL_JOURNAL_POINTER 28
-#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
-#define SQLITE_FCNTL_PDB 30
-#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31
-#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
-#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
+#define SQLITE_FCNTL_VFS_POINTER 27
+#define SQLITE_FCNTL_JOURNAL_POINTER 28
+#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
+#define SQLITE_FCNTL_PDB 30
+#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31
+#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
+#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
#define SQLITE_FCNTL_DATA_VERSION 35
#define SQLITE_FCNTL_SIZE_LIMIT 36
@@ -1244,16 +1244,16 @@ struct sqlite3_io_methods {
typedef struct sqlite3_mutex sqlite3_mutex;
/*
-** CAPI3REF: Loadable Extension Thunk
-**
-** A pointer to the opaque sqlite3_api_routines structure is passed as
-** the third parameter to entry points of [loadable extensions]. This
-** structure must be typedefed in order to work around compiler warnings
-** on some platforms.
-*/
-typedef struct sqlite3_api_routines sqlite3_api_routines;
-
-/*
+** CAPI3REF: Loadable Extension Thunk
+**
+** A pointer to the opaque sqlite3_api_routines structure is passed as
+** the third parameter to entry points of [loadable extensions]. This
+** structure must be typedefed in order to work around compiler warnings
+** on some platforms.
+*/
+typedef struct sqlite3_api_routines sqlite3_api_routines;
+
+/*
** CAPI3REF: OS Interface Object
**
** An instance of the sqlite3_vfs object defines the interface between
@@ -1261,17 +1261,17 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** in the name of the object stands for "virtual file system". See
** the [VFS | VFS documentation] for further information.
**
-** The VFS interface is sometimes extended by adding new methods onto
-** the end. Each time such an extension occurs, the iVersion field
-** is incremented. The iVersion value started out as 1 in
-** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
-** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
-** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields
-** may be appended to the sqlite3_vfs object and the iVersion value
-** may increase again in future versions of SQLite.
+** The VFS interface is sometimes extended by adding new methods onto
+** the end. Each time such an extension occurs, the iVersion field
+** is incremented. The iVersion value started out as 1 in
+** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
+** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
+** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields
+** may be appended to the sqlite3_vfs object and the iVersion value
+** may increase again in future versions of SQLite.
** Note that due to an oversight, the structure
** of the sqlite3_vfs object changed in the transition from
-** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
+** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
** and yet the iVersion field was not increased.
**
** The szOsFile field is the size of the subclassed [sqlite3_file]
@@ -1458,7 +1458,7 @@ struct sqlite3_vfs {
const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
/*
** The methods above are in versions 1 through 3 of the sqlite_vfs object.
- ** New fields may be appended in future versions. The iVersion
+ ** New fields may be appended in future versions. The iVersion
** value will increment whenever this happens.
*/
};
@@ -1600,10 +1600,10 @@ struct sqlite3_vfs {
** must return [SQLITE_OK] on success and some other [error code] upon
** failure.
*/
-SQLITE_API int sqlite3_initialize(void);
-SQLITE_API int sqlite3_shutdown(void);
-SQLITE_API int sqlite3_os_init(void);
-SQLITE_API int sqlite3_os_end(void);
+SQLITE_API int sqlite3_initialize(void);
+SQLITE_API int sqlite3_shutdown(void);
+SQLITE_API int sqlite3_os_init(void);
+SQLITE_API int sqlite3_os_end(void);
/*
** CAPI3REF: Configuring The SQLite Library
@@ -1614,11 +1614,11 @@ SQLITE_API int sqlite3_os_end(void);
** applications and so this routine is usually not necessary. It is
** provided to support rare applications with unusual needs.
**
-** <b>The sqlite3_config() interface is not threadsafe. The application
-** must ensure that no other SQLite interfaces are invoked by other
-** threads while sqlite3_config() is running.</b>
-**
-** The sqlite3_config() interface
+** <b>The sqlite3_config() interface is not threadsafe. The application
+** must ensure that no other SQLite interfaces are invoked by other
+** threads while sqlite3_config() is running.</b>
+**
+** The sqlite3_config() interface
** may only be invoked prior to library initialization using
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
@@ -1636,7 +1636,7 @@ SQLITE_API int sqlite3_os_end(void);
** ^If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
*/
-SQLITE_API int sqlite3_config(int, ...);
+SQLITE_API int sqlite3_config(int, ...);
/*
** CAPI3REF: Configure database connections
@@ -1655,7 +1655,7 @@ SQLITE_API int sqlite3_config(int, ...);
** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
** the call is considered successful.
*/
-SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Memory Allocation Routines
@@ -1806,16 +1806,16 @@ struct sqlite3_mem_methods {
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
-** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt>
-** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of
-** type int, interpreted as a boolean, which if true provides a hint to
-** SQLite that it should avoid large memory allocations if possible.
-** SQLite will run faster if it is free to make large memory allocations,
-** but some application might prefer to run slower in exchange for
-** guarantees about memory fragmentation that are possible if large
-** allocations are avoided. This hint is normally off.
-** </dd>
-**
+** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt>
+** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of
+** type int, interpreted as a boolean, which if true provides a hint to
+** SQLite that it should avoid large memory allocations if possible.
+** SQLite will run faster if it is free to make large memory allocations,
+** but some application might prefer to run slower in exchange for
+** guarantees about memory fragmentation that are possible if large
+** allocations are avoided. This hint is normally off.
+** </dd>
+**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
** interpreted as a boolean, which enables or disables the collection of
@@ -1834,43 +1834,43 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
-** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used.
+** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used.
** </dd>
**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
-** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
+** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
** that SQLite can use for the database page cache with the default page
** cache implementation.
** This configuration option is a no-op if an application-defined page
-** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
+** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
-** 8-byte aligned memory (pMem), the size of each page cache line (sz),
-** and the number of cache lines (N).
+** 8-byte aligned memory (pMem), the size of each page cache line (sz),
+** and the number of cache lines (N).
** The sz argument should be the size of the largest database page
** (a power of two between 512 and 65536) plus some extra bytes for each
** page header. ^The number of extra bytes needed by the page header
-** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ].
+** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ].
** ^It is harmless, apart from the wasted memory,
-** for the sz parameter to be larger than necessary. The pMem
-** argument must be either a NULL pointer or a pointer to an 8-byte
-** aligned block of memory of at least sz*N bytes, otherwise
-** subsequent behavior is undefined.
-** ^When pMem is not NULL, SQLite will strive to use the memory provided
-** to satisfy page cache needs, falling back to [sqlite3_malloc()] if
-** a page cache line is larger than sz bytes or if all of the pMem buffer
-** is exhausted.
-** ^If pMem is NULL and N is non-zero, then each database connection
-** does an initial bulk allocation for page cache memory
-** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or
-** of -1024*N bytes if N is negative, . ^If additional
-** page cache memory is needed beyond what is provided by the initial
-** allocation, then SQLite goes to [sqlite3_malloc()] separately for each
-** additional cache line. </dd>
+** for the sz parameter to be larger than necessary. The pMem
+** argument must be either a NULL pointer or a pointer to an 8-byte
+** aligned block of memory of at least sz*N bytes, otherwise
+** subsequent behavior is undefined.
+** ^When pMem is not NULL, SQLite will strive to use the memory provided
+** to satisfy page cache needs, falling back to [sqlite3_malloc()] if
+** a page cache line is larger than sz bytes or if all of the pMem buffer
+** is exhausted.
+** ^If pMem is NULL and N is non-zero, then each database connection
+** does an initial bulk allocation for page cache memory
+** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or
+** of -1024*N bytes if N is negative, . ^If additional
+** page cache memory is needed beyond what is provided by the initial
+** allocation, then SQLite goes to [sqlite3_malloc()] separately for each
+** additional cache line. </dd>
**
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer
** that SQLite will use for all of its dynamic memory allocation needs
-** beyond those provided for by [SQLITE_CONFIG_PAGECACHE].
+** beyond those provided for by [SQLITE_CONFIG_PAGECACHE].
** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
** [SQLITE_ERROR] if invoked otherwise.
@@ -2042,20 +2042,20 @@ struct sqlite3_mem_methods {
** is enabled (using the [PRAGMA threads] command) and the amount of content
** to be sorted exceeds the page size times the minimum of the
** [PRAGMA cache_size] setting and this value.
-**
-** [[SQLITE_CONFIG_STMTJRNL_SPILL]]
-** <dt>SQLITE_CONFIG_STMTJRNL_SPILL
-** <dd>^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which
+**
+** [[SQLITE_CONFIG_STMTJRNL_SPILL]]
+** <dt>SQLITE_CONFIG_STMTJRNL_SPILL
+** <dd>^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which
** becomes the [statement journal] spill-to-disk threshold.
-** [Statement journals] are held in memory until their size (in bytes)
-** exceeds this threshold, at which point they are written to disk.
-** Or if the threshold is -1, statement journals are always held
-** exclusively in memory.
-** Since many statement journals never become large, setting the spill
-** threshold to a value such as 64KiB can greatly reduce the amount of
-** I/O required to support statement rollback.
-** The default value for this setting is controlled by the
-** [SQLITE_STMTJRNL_SPILL] compile-time option.
+** [Statement journals] are held in memory until their size (in bytes)
+** exceeds this threshold, at which point they are written to disk.
+** Or if the threshold is -1, statement journals are always held
+** exclusively in memory.
+** Since many statement journals never become large, setting the spill
+** threshold to a value such as 64KiB can greatly reduce the amount of
+** I/O required to support statement rollback.
+** The default value for this setting is controlled by the
+** [SQLITE_STMTJRNL_SPILL] compile-time option.
**
** [[SQLITE_CONFIG_SORTERREF_SIZE]]
** <dt>SQLITE_CONFIG_SORTERREF_SIZE
@@ -2090,7 +2090,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */
+#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */
#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */
#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */
#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
@@ -2110,8 +2110,8 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
-#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
-#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
+#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
+#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
@@ -2198,87 +2198,87 @@ struct sqlite3_mem_methods {
** databases.)^ </dd>
**
** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
-** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
+** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
** <dd> ^This option is used to enable or disable the
** [fts3_tokenizer()] function which is part of the
-** [FTS3] full-text search engine extension.
-** There should be two additional arguments.
-** The first argument is an integer which is 0 to disable fts3_tokenizer() or
-** positive to enable fts3_tokenizer() or negative to leave the setting
-** unchanged.
-** The second parameter is a pointer to an integer into which
-** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
-** following this call. The second parameter may be a NULL pointer, in
-** which case the new setting is not reported back. </dd>
-**
+** [FTS3] full-text search engine extension.
+** There should be two additional arguments.
+** The first argument is an integer which is 0 to disable fts3_tokenizer() or
+** positive to enable fts3_tokenizer() or negative to leave the setting
+** unchanged.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
+** following this call. The second parameter may be a NULL pointer, in
+** which case the new setting is not reported back. </dd>
+**
** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
-** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
-** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
-** interface independently of the [load_extension()] SQL function.
-** The [sqlite3_enable_load_extension()] API enables or disables both the
-** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
-** There should be two additional arguments.
-** When the first argument to this interface is 1, then only the C-API is
-** enabled and the SQL function remains disabled. If the first argument to
-** this interface is 0, then both the C-API and the SQL function are disabled.
-** If the first argument is -1, then no changes are made to state of either the
-** C-API or the SQL function.
-** The second parameter is a pointer to an integer into which
-** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
-** is disabled or enabled following this call. The second parameter may
-** be a NULL pointer, in which case the new setting is not reported back.
-** </dd>
-**
+** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
+** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
+** interface independently of the [load_extension()] SQL function.
+** The [sqlite3_enable_load_extension()] API enables or disables both the
+** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
+** There should be two additional arguments.
+** When the first argument to this interface is 1, then only the C-API is
+** enabled and the SQL function remains disabled. If the first argument to
+** this interface is 0, then both the C-API and the SQL function are disabled.
+** If the first argument is -1, then no changes are made to state of either the
+** C-API or the SQL function.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
+** is disabled or enabled following this call. The second parameter may
+** be a NULL pointer, in which case the new setting is not reported back.
+** </dd>
+**
** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
-** <dd> ^This option is used to change the name of the "main" database
-** schema. ^The sole argument is a pointer to a constant UTF8 string
-** which will become the new schema name in place of "main". ^SQLite
-** does not make a copy of the new main schema name string, so the application
-** must ensure that the argument passed into this DBCONFIG option is unchanged
-** until after the database connection closes.
-** </dd>
-**
+** <dd> ^This option is used to change the name of the "main" database
+** schema. ^The sole argument is a pointer to a constant UTF8 string
+** which will become the new schema name in place of "main". ^SQLite
+** does not make a copy of the new main schema name string, so the application
+** must ensure that the argument passed into this DBCONFIG option is unchanged
+** until after the database connection closes.
+** </dd>
+**
** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
-** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
+** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
** <dd> Usually, when a database in wal mode is closed or detached from a
** database handle, SQLite checks if this will mean that there are now no
** connections at all to the database. If so, it performs a checkpoint
-** operation before closing the connection. This option may be used to
-** override this behaviour. The first parameter passed to this operation
+** operation before closing the connection. This option may be used to
+** override this behaviour. The first parameter passed to this operation
** is an integer - positive to disable checkpoints-on-close, or zero (the
** default) to enable them, and negative to leave the setting unchanged.
** The second parameter is a pointer to an integer
-** into which is written 0 or 1 to indicate whether checkpoints-on-close
-** have been disabled - 0 if they are not disabled, 1 if they are.
-** </dd>
+** into which is written 0 or 1 to indicate whether checkpoints-on-close
+** have been disabled - 0 if they are not disabled, 1 if they are.
+** </dd>
**
** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
-** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
-** the [query planner stability guarantee] (QPSG). When the QPSG is active,
-** a single SQL query statement will always use the same algorithm regardless
-** of values of [bound parameters].)^ The QPSG disables some query optimizations
-** that look at the values of bound parameters, which can make some queries
-** slower. But the QPSG has the advantage of more predictable behavior. With
-** the QPSG active, SQLite will always use the same query plan in the field as
-** was used during testing in the lab.
+** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
+** the [query planner stability guarantee] (QPSG). When the QPSG is active,
+** a single SQL query statement will always use the same algorithm regardless
+** of values of [bound parameters].)^ The QPSG disables some query optimizations
+** that look at the values of bound parameters, which can make some queries
+** slower. But the QPSG has the advantage of more predictable behavior. With
+** the QPSG active, SQLite will always use the same query plan in the field as
+** was used during testing in the lab.
** The first argument to this setting is an integer which is 0 to disable
** the QPSG, positive to enable QPSG, or negative to leave the setting
** unchanged. The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
** following this call.
-** </dd>
+** </dd>
**
** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
-** include output for any operations performed by trigger programs. This
-** option is used to set or clear (the default) a flag that governs this
-** behavior. The first parameter passed to this operation is an integer -
+** include output for any operations performed by trigger programs. This
+** option is used to set or clear (the default) a flag that governs this
+** behavior. The first parameter passed to this operation is an integer -
** positive to enable output for trigger programs, or zero to disable it,
** or negative to leave the setting unchanged.
** The second parameter is a pointer to an integer into which is written
** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
** it is not disabled, 1 if it is.
-** </dd>
+** </dd>
**
** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
@@ -2396,15 +2396,15 @@ struct sqlite3_mem_methods {
** </dd>
** </dl>
*/
-#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
-#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
-#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
-#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
-#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
+#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
+#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
+#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
+#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
+#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
#define SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011 /* int int* */
@@ -2424,7 +2424,7 @@ struct sqlite3_mem_methods {
** [extended result codes] feature of SQLite. ^The extended result
** codes are disabled by default for historical compatibility.
*/
-SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
+SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
** CAPI3REF: Last Insert Rowid
@@ -2438,31 +2438,31 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
-** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
-** the most recent successful [INSERT] into a rowid table or [virtual table]
-** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
+** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
+** the most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred
** on the database connection D, then sqlite3_last_insert_rowid(D) returns
-** zero.
+** zero.
**
-** As well as being set automatically as rows are inserted into database
-** tables, the value returned by this function may be set explicitly by
-** [sqlite3_set_last_insert_rowid()]
+** As well as being set automatically as rows are inserted into database
+** tables, the value returned by this function may be set explicitly by
+** [sqlite3_set_last_insert_rowid()]
**
-** Some virtual table implementations may INSERT rows into rowid tables as
-** part of committing a transaction (e.g. to flush data accumulated in memory
-** to disk). In this case subsequent calls to this function return the rowid
+** Some virtual table implementations may INSERT rows into rowid tables as
+** part of committing a transaction (e.g. to flush data accumulated in memory
+** to disk). In this case subsequent calls to this function return the rowid
** associated with these internal INSERT operations, which leads to
-** unintuitive results. Virtual table implementations that do write to rowid
+** unintuitive results. Virtual table implementations that do write to rowid
** tables in this way can avoid this problem by restoring the original
** rowid value using [sqlite3_set_last_insert_rowid()] before returning
-** control to the user.
-**
+** control to the user.
+**
** ^(If an [INSERT] occurs within a trigger then this routine will
** return the [rowid] of the inserted row as long as the trigger is
** running. Once the trigger program ends, the value returned
-** by this routine reverts to what it was before the trigger was fired.)^
-**
+** by this routine reverts to what it was before the trigger was fired.)^
+**
** ^An [INSERT] that fails due to a constraint violation is not a
** successful [INSERT] and does not change the value returned by this
** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
@@ -2486,19 +2486,19 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
** unpredictable and might not equal either the old or the new
** last insert [rowid].
*/
-SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
+SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
/*
-** CAPI3REF: Set the Last Insert Rowid value.
-** METHOD: sqlite3
-**
-** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
+** CAPI3REF: Set the Last Insert Rowid value.
+** METHOD: sqlite3
+**
+** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
** set the value returned by calling sqlite3_last_insert_rowid(D) to R
-** without inserting a row into the database.
-*/
-SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
-
-/*
+** without inserting a row into the database.
+*/
+SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
+
+/*
** CAPI3REF: Count The Number Of Rows Modified
** METHOD: sqlite3
**
@@ -2557,7 +2557,7 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
** <li> the [data_version pragma]
** </ul>
*/
-SQLITE_API int sqlite3_changes(sqlite3*);
+SQLITE_API int sqlite3_changes(sqlite3*);
SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3*);
/*
@@ -2599,7 +2599,7 @@ SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3*);
** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
** </ul>
*/
-SQLITE_API int sqlite3_total_changes(sqlite3*);
+SQLITE_API int sqlite3_total_changes(sqlite3*);
SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*);
/*
@@ -2637,7 +2637,7 @@ SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*);
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite3_interrupt() call returns.
*/
-SQLITE_API void sqlite3_interrupt(sqlite3*);
+SQLITE_API void sqlite3_interrupt(sqlite3*);
/*
** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -2672,8 +2672,8 @@ SQLITE_API void sqlite3_interrupt(sqlite3*);
** The input to [sqlite3_complete16()] must be a zero-terminated
** UTF-16 string in native byte order.
*/
-SQLITE_API int sqlite3_complete(const char *sql);
-SQLITE_API int sqlite3_complete16(const void *sql);
+SQLITE_API int sqlite3_complete(const char *sql);
+SQLITE_API int sqlite3_complete16(const void *sql);
/*
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
@@ -2734,7 +2734,7 @@ SQLITE_API int sqlite3_complete16(const void *sql);
** A busy handler must not close the database connection
** or [prepared statement] that invoked the busy handler.
*/
-SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
+SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
/*
** CAPI3REF: Set A Busy Timeout
@@ -2757,7 +2757,7 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
**
** See also: [PRAGMA busy_timeout]
*/
-SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
+SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
/*
** CAPI3REF: Convenience Routines For Running Queries
@@ -2832,7 +2832,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
** reflected in subsequent calls to [sqlite3_errcode()] or
** [sqlite3_errmsg()].
*/
-SQLITE_API int sqlite3_get_table(
+SQLITE_API int sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
@@ -2840,7 +2840,7 @@ SQLITE_API int sqlite3_get_table(
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);
-SQLITE_API void sqlite3_free_table(char **result);
+SQLITE_API void sqlite3_free_table(char **result);
/*
** CAPI3REF: Formatted String Printing Functions
@@ -2882,10 +2882,10 @@ SQLITE_API void sqlite3_free_table(char **result);
**
** See also: [built-in printf()], [printf() SQL function]
*/
-SQLITE_API char *sqlite3_mprintf(const char*,...);
-SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
-SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
+SQLITE_API char *sqlite3_mprintf(const char*,...);
+SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
+SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
+SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
/*
** CAPI3REF: Memory Allocation Subsystem
@@ -2962,12 +2962,12 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
** a block of memory after it has been released using
** [sqlite3_free()] or [sqlite3_realloc()].
*/
-SQLITE_API void *sqlite3_malloc(int);
-SQLITE_API void *sqlite3_malloc64(sqlite3_uint64);
-SQLITE_API void *sqlite3_realloc(void*, int);
-SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64);
-SQLITE_API void sqlite3_free(void*);
-SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
+SQLITE_API void *sqlite3_malloc(int);
+SQLITE_API void *sqlite3_malloc64(sqlite3_uint64);
+SQLITE_API void *sqlite3_realloc(void*, int);
+SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64);
+SQLITE_API void sqlite3_free(void*);
+SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
/*
** CAPI3REF: Memory Allocator Statistics
@@ -2992,8 +2992,8 @@ SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
** by [sqlite3_memory_highwater(1)] is the high-water mark
** prior to the reset.
*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
+SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
+SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
/*
** CAPI3REF: Pseudo-Random Number Generator
@@ -3016,19 +3016,19 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
-SQLITE_API void sqlite3_randomness(int N, void *P);
+SQLITE_API void sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
** METHOD: sqlite3
-** KEYWORDS: {authorizer callback}
+** KEYWORDS: {authorizer callback}
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
** ^The authorizer callback is invoked as SQL statements are being compiled
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
-** [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()],
-** and [sqlite3_prepare16_v3()]. ^At various
+** [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()],
+** and [sqlite3_prepare16_v3()]. ^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
@@ -3050,10 +3050,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
** to the callback is an integer [SQLITE_COPY | action code] that specifies
** the particular action to be authorized. ^The third through sixth parameters
-** to the callback are either NULL pointers or zero-terminated strings
-** that contain additional details about the action to be authorized.
-** Applications must always be prepared to encounter a NULL pointer in any
-** of the third through the sixth parameters of the authorization callback.
+** to the callback are either NULL pointers or zero-terminated strings
+** that contain additional details about the action to be authorized.
+** Applications must always be prepared to encounter a NULL pointer in any
+** of the third through the sixth parameters of the authorization callback.
**
** ^If the action code is [SQLITE_READ]
** and the callback returns [SQLITE_IGNORE] then the
@@ -3062,10 +3062,10 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** 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.
-** ^When a table is referenced by a [SELECT] but no column values are
-** extracted from that table (for example in a query like
-** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
-** is invoked once for that table with a column name that is an empty string.
+** ^When a table is referenced by a [SELECT] but no column values are
+** extracted from that table (for example in a query like
+** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
+** is invoked once for that table with a column name that is an empty string.
** ^If the action code is [SQLITE_DELETE] and the callback returns
** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
** [truncate optimization] is disabled and all rows are deleted individually.
@@ -3107,7 +3107,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** as stated in the previous paragraph, sqlite3_step() invokes
** sqlite3_prepare_v2() to reprepare a statement after a schema change.
*/
-SQLITE_API int sqlite3_set_authorizer(
+SQLITE_API int sqlite3_set_authorizer(
sqlite3*,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pUserData
@@ -3187,9 +3187,9 @@ SQLITE_API int sqlite3_set_authorizer(
** CAPI3REF: Tracing And Profiling Functions
** METHOD: sqlite3
**
-** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
-** instead of the routines described here.
-**
+** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
+** instead of the routines described here.
+**
** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements.
**
@@ -3215,105 +3215,105 @@ SQLITE_API int sqlite3_set_authorizer(
** either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the
** profile callback.
*/
-SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
- void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
+SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
+ void(*xTrace)(void*,const char*), void*);
+SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
/*
-** CAPI3REF: SQL Trace Event Codes
-** KEYWORDS: SQLITE_TRACE
-**
-** These constants identify classes of events that can be monitored
-** using the [sqlite3_trace_v2()] tracing logic. The M argument
-** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
-** the following constants. ^The first argument to the trace callback
-** is one of the following constants.
-**
-** New tracing constants may be added in future releases.
-**
-** ^A trace callback has four arguments: xCallback(T,C,P,X).
-** ^The T argument is one of the integer type codes above.
-** ^The C argument is a copy of the context pointer passed in as the
-** fourth argument to [sqlite3_trace_v2()].
-** The P and X arguments are pointers whose meanings depend on T.
-**
-** <dl>
-** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt>
-** <dd>^An SQLITE_TRACE_STMT callback is invoked when a prepared statement
-** first begins running and possibly at other times during the
-** execution of the prepared statement, such as at the start of each
-** trigger subprogram. ^The P argument is a pointer to the
-** [prepared statement]. ^The X argument is a pointer to a string which
+** CAPI3REF: SQL Trace Event Codes
+** KEYWORDS: SQLITE_TRACE
+**
+** These constants identify classes of events that can be monitored
+** using the [sqlite3_trace_v2()] tracing logic. The M argument
+** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
+** the following constants. ^The first argument to the trace callback
+** is one of the following constants.
+**
+** New tracing constants may be added in future releases.
+**
+** ^A trace callback has four arguments: xCallback(T,C,P,X).
+** ^The T argument is one of the integer type codes above.
+** ^The C argument is a copy of the context pointer passed in as the
+** fourth argument to [sqlite3_trace_v2()].
+** The P and X arguments are pointers whose meanings depend on T.
+**
+** <dl>
+** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt>
+** <dd>^An SQLITE_TRACE_STMT callback is invoked when a prepared statement
+** first begins running and possibly at other times during the
+** execution of the prepared statement, such as at the start of each
+** trigger subprogram. ^The P argument is a pointer to the
+** [prepared statement]. ^The X argument is a pointer to a string which
** is the unexpanded SQL text of the prepared statement or an SQL comment
-** that indicates the invocation of a trigger. ^The callback can compute
-** the same text that would have been returned by the legacy [sqlite3_trace()]
-** interface by using the X argument when X begins with "--" and invoking
-** [sqlite3_expanded_sql(P)] otherwise.
-**
-** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt>
-** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
-** information as is provided by the [sqlite3_profile()] callback.
-** ^The P argument is a pointer to the [prepared statement] and the
-** X argument points to a 64-bit integer which is the estimated of
-** the number of nanosecond that the prepared statement took to run.
-** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
-**
-** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
-** <dd>^An SQLITE_TRACE_ROW callback is invoked whenever a prepared
+** that indicates the invocation of a trigger. ^The callback can compute
+** the same text that would have been returned by the legacy [sqlite3_trace()]
+** interface by using the X argument when X begins with "--" and invoking
+** [sqlite3_expanded_sql(P)] otherwise.
+**
+** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt>
+** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
+** information as is provided by the [sqlite3_profile()] callback.
+** ^The P argument is a pointer to the [prepared statement] and the
+** X argument points to a 64-bit integer which is the estimated of
+** the number of nanosecond that the prepared statement took to run.
+** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
+**
+** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
+** <dd>^An SQLITE_TRACE_ROW callback is invoked whenever a prepared
** statement generates a single row of result.
-** ^The P argument is a pointer to the [prepared statement] and the
-** X argument is unused.
-**
-** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt>
-** <dd>^An SQLITE_TRACE_CLOSE callback is invoked when a database
-** connection closes.
-** ^The P argument is a pointer to the [database connection] object
-** and the X argument is unused.
-** </dl>
-*/
-#define SQLITE_TRACE_STMT 0x01
-#define SQLITE_TRACE_PROFILE 0x02
-#define SQLITE_TRACE_ROW 0x04
-#define SQLITE_TRACE_CLOSE 0x08
-
-/*
-** CAPI3REF: SQL Trace Hook
-** METHOD: sqlite3
-**
-** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback
-** function X against [database connection] D, using property mask M
-** and context pointer P. ^If the X callback is
-** NULL or if the M mask is zero, then tracing is disabled. The
-** M argument should be the bitwise OR-ed combination of
-** zero or more [SQLITE_TRACE] constants.
-**
+** ^The P argument is a pointer to the [prepared statement] and the
+** X argument is unused.
+**
+** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt>
+** <dd>^An SQLITE_TRACE_CLOSE callback is invoked when a database
+** connection closes.
+** ^The P argument is a pointer to the [database connection] object
+** and the X argument is unused.
+** </dl>
+*/
+#define SQLITE_TRACE_STMT 0x01
+#define SQLITE_TRACE_PROFILE 0x02
+#define SQLITE_TRACE_ROW 0x04
+#define SQLITE_TRACE_CLOSE 0x08
+
+/*
+** CAPI3REF: SQL Trace Hook
+** METHOD: sqlite3
+**
+** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback
+** function X against [database connection] D, using property mask M
+** and context pointer P. ^If the X callback is
+** NULL or if the M mask is zero, then tracing is disabled. The
+** M argument should be the bitwise OR-ed combination of
+** zero or more [SQLITE_TRACE] constants.
+**
** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides
-** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().
-**
+** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().
+**
** ^The X callback is invoked whenever any of the events identified by
-** mask M occur. ^The integer return value from the callback is currently
-** ignored, though this may change in future releases. Callback
-** implementations should return zero to ensure future compatibility.
-**
-** ^A trace callback is invoked with four arguments: callback(T,C,P,X).
-** ^The T argument is one of the [SQLITE_TRACE]
-** constants to indicate why the callback was invoked.
-** ^The C argument is a copy of the context pointer.
-** The P and X arguments are pointers whose meanings depend on T.
-**
-** The sqlite3_trace_v2() interface is intended to replace the legacy
-** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
-** are deprecated.
-*/
-SQLITE_API int sqlite3_trace_v2(
- sqlite3*,
- unsigned uMask,
- int(*xCallback)(unsigned,void*,void*,void*),
- void *pCtx
-);
-
-/*
+** mask M occur. ^The integer return value from the callback is currently
+** ignored, though this may change in future releases. Callback
+** implementations should return zero to ensure future compatibility.
+**
+** ^A trace callback is invoked with four arguments: callback(T,C,P,X).
+** ^The T argument is one of the [SQLITE_TRACE]
+** constants to indicate why the callback was invoked.
+** ^The C argument is a copy of the context pointer.
+** The P and X arguments are pointers whose meanings depend on T.
+**
+** The sqlite3_trace_v2() interface is intended to replace the legacy
+** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
+** are deprecated.
+*/
+SQLITE_API int sqlite3_trace_v2(
+ sqlite3*,
+ unsigned uMask,
+ int(*xCallback)(unsigned,void*,void*,void*),
+ void *pCtx
+);
+
+/*
** CAPI3REF: Query Progress Callbacks
** METHOD: sqlite3
**
@@ -3345,7 +3345,7 @@ SQLITE_API int sqlite3_trace_v2(
** database connections for the meaning of "modify" in this paragraph.
**
*/
-SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
/*
** CAPI3REF: Opening A New Database Connection
@@ -3477,10 +3477,10 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** ^If [URI filename] interpretation is enabled, and the filename argument
** begins with "file:", then the filename is interpreted as a URI. ^URI
** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
-** set in the third argument to sqlite3_open_v2(), or if it has
+** set in the third argument to sqlite3_open_v2(), or if it has
** been enabled globally using the [SQLITE_CONFIG_URI] option with the
** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
-** URI filename interpretation is turned off
+** URI filename interpretation is turned off
** by default, but future releases of SQLite might enable URI filename
** interpretation by default. See "[URI filenames]" for additional
** information.
@@ -3617,15 +3617,15 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
**
** See also: [sqlite3_temp_directory]
*/
-SQLITE_API int sqlite3_open(
+SQLITE_API int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int sqlite3_open16(
+SQLITE_API int sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int sqlite3_open_v2(
+SQLITE_API int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
@@ -3698,9 +3698,9 @@ SQLITE_API int sqlite3_open_v2(
**
** See the [URI filename] documentation for additional information.
*/
-SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
-SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
-SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
+SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
+SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N);
/*
@@ -3859,11 +3859,11 @@ SQLITE_API void sqlite3_free_filename(char*);
** was invoked incorrectly by the application. In that case, the
** error code and message may or may not be set.
*/
-SQLITE_API int sqlite3_errcode(sqlite3 *db);
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
-SQLITE_API const char *sqlite3_errstr(int);
+SQLITE_API int sqlite3_errcode(sqlite3 *db);
+SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
+SQLITE_API const char *sqlite3_errmsg(sqlite3*);
+SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *sqlite3_errstr(int);
/*
** CAPI3REF: Prepared Statement Object
@@ -3931,7 +3931,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
**
** New run-time limit categories may be added in future releases.
*/
-SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
+SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
/*
** CAPI3REF: Run-Time Limit Categories
@@ -3962,9 +3962,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
**
** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
** <dd>The maximum number of instructions in a virtual machine program
-** used to implement an SQL statement. If [sqlite3_prepare_v2()] or
-** the equivalent tries to allocate space for more than this many opcodes
-** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
+** used to implement an SQL statement. If [sqlite3_prepare_v2()] or
+** the equivalent tries to allocate space for more than this many opcodes
+** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
**
** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
** <dd>The maximum number of arguments on a function.</dd>)^
@@ -4003,25 +4003,25 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
#define SQLITE_LIMIT_WORKER_THREADS 11
/*
-** CAPI3REF: Prepare Flags
-**
-** These constants define various flags that can be passed into
-** "prepFlags" parameter of the [sqlite3_prepare_v3()] and
-** [sqlite3_prepare16_v3()] interfaces.
-**
-** New flags may be added in future releases of SQLite.
-**
-** <dl>
-** [[SQLITE_PREPARE_PERSISTENT]] ^(<dt>SQLITE_PREPARE_PERSISTENT</dt>
-** <dd>The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner
-** that the prepared statement will be retained for a long time and
-** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()]
+** CAPI3REF: Prepare Flags
+**
+** These constants define various flags that can be passed into
+** "prepFlags" parameter of the [sqlite3_prepare_v3()] and
+** [sqlite3_prepare16_v3()] interfaces.
+**
+** New flags may be added in future releases of SQLite.
+**
+** <dl>
+** [[SQLITE_PREPARE_PERSISTENT]] ^(<dt>SQLITE_PREPARE_PERSISTENT</dt>
+** <dd>The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner
+** that the prepared statement will be retained for a long time and
+** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()]
** and [sqlite3_prepare16_v3()] assume that the prepared statement will
-** be used just once or at most a few times and then destroyed using
-** [sqlite3_finalize()] relatively soon. The current implementation acts
-** on this hint by avoiding the use of [lookaside memory] so as not to
-** deplete the limited store of lookaside memory. Future versions of
-** SQLite may act on this hint differently.
+** be used just once or at most a few times and then destroyed using
+** [sqlite3_finalize()] relatively soon. The current implementation acts
+** on this hint by avoiding the use of [lookaside memory] so as not to
+** deplete the limited store of lookaside memory. Future versions of
+** SQLite may act on this hint differently.
**
** [[SQLITE_PREPARE_NORMALIZE]] <dt>SQLITE_PREPARE_NORMALIZE</dt>
** <dd>The SQLITE_PREPARE_NORMALIZE flag is a no-op. This flag used
@@ -4035,41 +4035,41 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
** to return an error (error code SQLITE_ERROR) if the statement uses
** any virtual tables.
-** </dl>
-*/
-#define SQLITE_PREPARE_PERSISTENT 0x01
+** </dl>
+*/
+#define SQLITE_PREPARE_PERSISTENT 0x01
#define SQLITE_PREPARE_NORMALIZE 0x02
#define SQLITE_PREPARE_NO_VTAB 0x04
-
-/*
+
+/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
** METHOD: sqlite3
** CONSTRUCTOR: sqlite3_stmt
**
-** To execute an SQL statement, it must first be compiled into a byte-code
-** program using one of these routines. Or, in other words, these routines
-** are constructors for the [prepared statement] object.
-**
-** The preferred routine to use is [sqlite3_prepare_v2()]. The
-** [sqlite3_prepare()] interface is legacy and should be avoided.
-** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used
-** for special purposes.
-**
-** The use of the UTF-8 interfaces is preferred, as SQLite currently
-** does all parsing using UTF-8. The UTF-16 interfaces are provided
-** as a convenience. The UTF-16 interfaces work by converting the
-** input text into UTF-8, then invoking the corresponding UTF-8 interface.
-**
+** To execute an SQL statement, it must first be compiled into a byte-code
+** program using one of these routines. Or, in other words, these routines
+** are constructors for the [prepared statement] object.
+**
+** The preferred routine to use is [sqlite3_prepare_v2()]. The
+** [sqlite3_prepare()] interface is legacy and should be avoided.
+** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used
+** for special purposes.
+**
+** The use of the UTF-8 interfaces is preferred, as SQLite currently
+** does all parsing using UTF-8. The UTF-16 interfaces are provided
+** as a convenience. The UTF-16 interfaces work by converting the
+** input text into UTF-8, then invoking the corresponding UTF-8 interface.
+**
** The first argument, "db", is a [database connection] obtained from a
** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
** [sqlite3_open16()]. The database connection must not have been closed.
**
** The second argument, "zSql", is the statement to be compiled, encoded
-** as either UTF-8 or UTF-16. The sqlite3_prepare(), sqlite3_prepare_v2(),
-** and sqlite3_prepare_v3()
-** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(),
-** and sqlite3_prepare16_v3() use UTF-16.
+** as either UTF-8 or UTF-16. The sqlite3_prepare(), sqlite3_prepare_v2(),
+** and sqlite3_prepare_v3()
+** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(),
+** and sqlite3_prepare16_v3() use UTF-16.
**
** ^If the nByte argument is negative, then zSql is read up to the
** first zero terminator. ^If nByte is positive, then it is the
@@ -4096,11 +4096,11 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK];
** otherwise an [error code] is returned.
**
-** The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(),
-** and sqlite3_prepare16_v3() interfaces are recommended for all new programs.
-** The older interfaces (sqlite3_prepare() and sqlite3_prepare16())
-** are retained for backwards compatibility, but their use is discouraged.
-** ^In the "vX" interfaces, the prepared statement
+** The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(),
+** and sqlite3_prepare16_v3() interfaces are recommended for all new programs.
+** The older interfaces (sqlite3_prepare() and sqlite3_prepare16())
+** are retained for backwards compatibility, but their use is discouraged.
+** ^In the "vX" interfaces, the prepared statement
** that is returned (the [sqlite3_stmt] object) contains a copy of the
** original SQL text. This causes the [sqlite3_step()] interface to
** behave differently in three ways:
@@ -4134,101 +4134,101 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled.
** </li>
** </ol>
-**
-** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
-** the extra prepFlags parameter, which is a bit array consisting of zero or
-** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The
-** sqlite3_prepare_v2() interface works exactly the same as
-** sqlite3_prepare_v3() with a zero prepFlags parameter.
-*/
-SQLITE_API int sqlite3_prepare(
+**
+** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
+** the extra prepFlags parameter, which is a bit array consisting of zero or
+** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The
+** sqlite3_prepare_v2() interface works exactly the same as
+** sqlite3_prepare_v3() with a zero prepFlags parameter.
+*/
+SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int sqlite3_prepare_v2(
+SQLITE_API int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int sqlite3_prepare_v3(
+SQLITE_API int sqlite3_prepare_v3(
+ sqlite3 *db, /* Database handle */
+ const char *zSql, /* SQL statement, UTF-8 encoded */
+ int nByte, /* Maximum length of zSql in bytes. */
+ unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
+ sqlite3_stmt **ppStmt, /* OUT: Statement handle */
+ const char **pzTail /* OUT: Pointer to unused portion of zSql */
+);
+SQLITE_API int sqlite3_prepare16(
+ sqlite3 *db, /* Database handle */
+ const void *zSql, /* SQL statement, UTF-16 encoded */
+ int nByte, /* Maximum length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: Statement handle */
+ const void **pzTail /* OUT: Pointer to unused portion of zSql */
+);
+SQLITE_API int sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle */
- const char *zSql, /* SQL statement, UTF-8 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const char **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare16(
- sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const void **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int sqlite3_prepare16_v2(
+SQLITE_API int sqlite3_prepare16_v3(
sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
+ unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const void **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int sqlite3_prepare16_v3(
- sqlite3 *db, /* Database handle */
- const void *zSql, /* SQL statement, UTF-16 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const void **pzTail /* OUT: Pointer to unused portion of zSql */
-);
/*
** CAPI3REF: Retrieving Statement SQL
** METHOD: sqlite3_stmt
**
-** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8
-** SQL text used to create [prepared statement] P if P was
-** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
-** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
-** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
-** string containing the SQL text of prepared statement P with
-** [bound parameters] expanded.
+** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8
+** SQL text used to create [prepared statement] P if P was
+** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
+** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
+** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
+** string containing the SQL text of prepared statement P with
+** [bound parameters] expanded.
** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
** string containing the normalized SQL text of prepared statement P. The
** semantics used to normalize a SQL statement are unspecified and subject
** to change. At a minimum, literal values will be replaced with suitable
** placeholders.
-**
-** ^(For example, if a prepared statement is created using the SQL
-** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
-** and parameter :xyz is unbound, then sqlite3_sql() will return
-** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
-** will return "SELECT 2345,NULL".)^
-**
-** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory
-** is available to hold the result, or if the result would exceed the
-** the maximum string length determined by the [SQLITE_LIMIT_LENGTH].
-**
-** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
-** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
-** option causes sqlite3_expanded_sql() to always return NULL.
-**
+**
+** ^(For example, if a prepared statement is created using the SQL
+** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
+** and parameter :xyz is unbound, then sqlite3_sql() will return
+** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
+** will return "SELECT 2345,NULL".)^
+**
+** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory
+** is available to hold the result, or if the result would exceed the
+** the maximum string length determined by the [SQLITE_LIMIT_LENGTH].
+**
+** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
+** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
+** option causes sqlite3_expanded_sql() to always return NULL.
+**
** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
** are managed by SQLite and are automatically freed when the prepared
** statement is finalized.
-** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
+** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
** is obtained from [sqlite3_malloc()] and must be freed by the application
-** by passing it to [sqlite3_free()].
+** by passing it to [sqlite3_free()].
**
** ^The sqlite3_normalized_sql() interface is only available if
** the [SQLITE_ENABLE_NORMALIZE] compile-time option is defined.
*/
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
-SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
+SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
+SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
#ifdef SQLITE_ENABLE_NORMALIZE
SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
#endif
@@ -4262,10 +4262,10 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
** sqlite3_stmt_readonly() to return true since, while those statements
** change the configuration of a database connection, they do not make
** changes to the content of the database files on disk.
-** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since
-** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
-** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
-** sqlite3_stmt_readonly() returns false for those commands.
+** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since
+** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
+** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
+** sqlite3_stmt_readonly() returns false for those commands.
**
** ^This routine returns false if there is any possibility that the
** statement might change the database file. ^A false return does
@@ -4276,7 +4276,7 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
** read-only no-op if the table already exists, but
** sqlite3_stmt_readonly() still returns false for such a statement.
*/
-SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4296,8 +4296,8 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
**
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
** [prepared statement] S has been stepped at least once using
-** [sqlite3_step(S)] but has neither run to completion (returned
-** [SQLITE_DONE] from [sqlite3_step(S)]) nor
+** [sqlite3_step(S)] but has neither run to completion (returned
+** [SQLITE_DONE] from [sqlite3_step(S)]) nor
** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S)
** interface returns false if S is a NULL pointer. If S is not a
** NULL pointer and is not a pointer to a valid [prepared statement]
@@ -4309,7 +4309,7 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
** for example, in diagnostic routines to search for prepared
** statements that are holding a transaction open.
*/
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
+SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
/*
** CAPI3REF: Dynamically Typed Value Object
@@ -4345,13 +4345,13 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
** 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 as arguments
-** to [sqlite3_result_value()], [sqlite3_bind_value()], and
-** [sqlite3_value_dup()].
+** Unprotected sqlite3_value objects may only be used as arguments
+** to [sqlite3_result_value()], [sqlite3_bind_value()], and
+** [sqlite3_value_dup()].
** The [sqlite3_value_blob | sqlite3_value_type()] family of
** interfaces require protected sqlite3_value objects.
*/
-typedef struct sqlite3_value sqlite3_value;
+typedef struct sqlite3_value sqlite3_value;
/*
** CAPI3REF: SQL Function Context Object
@@ -4477,15 +4477,15 @@ typedef struct sqlite3_context sqlite3_context;
** [sqlite3_blob_open | incremental BLOB I/O] routines.
** ^A negative value for the zeroblob results in a zero-length BLOB.
**
-** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
-** [prepared statement] S to have an SQL value of NULL, but to also be
-** associated with the pointer P of type T. ^D is either a NULL pointer or
-** a pointer to a destructor function for P. ^SQLite will invoke the
-** destructor D with a single argument of P when it is finished using
-** P. The T parameter should be a static string, preferably a string
-** literal. The sqlite3_bind_pointer() routine is part of the
-** [pointer passing interface] added for SQLite 3.20.0.
-**
+** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
+** [prepared statement] S to have an SQL value of NULL, but to also be
+** associated with the pointer P of type T. ^D is either a NULL pointer or
+** a pointer to a destructor function for P. ^SQLite will invoke the
+** destructor D with a single argument of P when it is finished using
+** P. The T parameter should be a static string, preferably a string
+** literal. The sqlite3_bind_pointer() routine is part of the
+** [pointer passing interface] added for SQLite 3.20.0.
+**
** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
** for the [prepared statement] or with a prepared statement for which
** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
@@ -4507,21 +4507,21 @@ typedef struct sqlite3_context sqlite3_context;
** See also: [sqlite3_bind_parameter_count()],
** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
void(*)(void*));
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
-SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
+SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
+SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
+SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
void(*)(void*), unsigned char encoding);
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
-SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
+SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
+SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
+SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
/*
** CAPI3REF: Number Of SQL Parameters
@@ -4542,7 +4542,7 @@ SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
** [sqlite3_bind_parameter_name()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
+SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
** CAPI3REF: Name Of A Host Parameter
@@ -4563,14 +4563,14 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
** ^If the value N is out of range or if the N-th parameter is
** nameless, then NULL is returned. ^The returned string is
** always in UTF-8 encoding even if the named parameter was
-** originally specified as UTF-16 in [sqlite3_prepare16()],
-** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
+** originally specified as UTF-16 in [sqlite3_prepare16()],
+** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
/*
** CAPI3REF: Index Of A Parameter With A Given Name
@@ -4581,14 +4581,14 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero
** is returned if no matching parameter is found. ^The parameter
** name must be given in UTF-8 even if the original statement
-** was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or
-** [sqlite3_prepare16_v3()].
+** was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or
+** [sqlite3_prepare16_v3()].
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_name()].
+** [sqlite3_bind_parameter_name()].
*/
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
/*
** CAPI3REF: Reset All Bindings On A Prepared Statement
@@ -4598,7 +4598,7 @@ SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
** the [sqlite3_bind_blob | bindings] on a [prepared statement].
** ^Use this routine to reset all host parameters to NULL.
*/
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
+SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
/*
** CAPI3REF: Number Of Columns In A Result Set
@@ -4606,15 +4606,15 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
**
** ^Return the number of columns in the result set returned by the
** [prepared statement]. ^If this routine returns 0, that means the
-** [prepared statement] returns no data (for example an [UPDATE]).
-** ^However, just because this routine returns a positive number does not
-** mean that one or more rows of data will be returned. ^A SELECT statement
-** will always have a positive sqlite3_column_count() but depending on the
-** WHERE clause constraints and the table content, it might return no rows.
+** [prepared statement] returns no data (for example an [UPDATE]).
+** ^However, just because this routine returns a positive number does not
+** mean that one or more rows of data will be returned. ^A SELECT statement
+** will always have a positive sqlite3_column_count() but depending on the
+** WHERE clause constraints and the table content, it might return no rows.
**
** See also: [sqlite3_data_count()]
*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Column Names In A Result Set
@@ -4643,8 +4643,8 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
** then the name of the column is unspecified and may change from
** one release of SQLite to the next.
*/
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
+SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
+SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
/*
** CAPI3REF: Source Of Data In A Query Result
@@ -4688,12 +4688,12 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
** for the same [prepared statement] and result column
** at the same time then the results are undefined.
*/
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
/*
** CAPI3REF: Declared Datatype Of A Query Result
@@ -4725,25 +4725,25 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
** is associated with individual values, not with the containers
** used to hold those values.
*/
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
/*
** CAPI3REF: Evaluate An SQL Statement
** METHOD: sqlite3_stmt
**
-** After a [prepared statement] has been prepared using any of
-** [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()],
-** or [sqlite3_prepare16_v3()] or one of the legacy
+** After a [prepared statement] has been prepared using any of
+** [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()],
+** or [sqlite3_prepare16_v3()] or one of the legacy
** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
** must be called one or more times to evaluate the statement.
**
** The details of the behavior of the sqlite3_step() interface depend
-** on whether the statement was prepared using the newer "vX" interfaces
-** [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()],
-** [sqlite3_prepare16_v2()] or the older legacy
-** interfaces [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the
-** new "vX" interface is recommended for new applications but the legacy
+** on whether the statement was prepared using the newer "vX" interfaces
+** [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()],
+** [sqlite3_prepare16_v2()] or the older legacy
+** interfaces [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the
+** new "vX" interface is recommended for new applications but the legacy
** interface will continue to be supported.
**
** ^In the legacy interface, the return value will be either [SQLITE_BUSY],
@@ -4789,8 +4789,8 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step(). Failure to reset the prepared statement using
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
-** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
-** sqlite3_step() began
+** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
+** sqlite3_step() began
** calling [sqlite3_reset()] automatically in this circumstance rather
** than returning [SQLITE_MISUSE]. This is not considered a compatibility
** break because any application that ever receives an SQLITE_MISUSE error
@@ -4804,13 +4804,13 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** specific [error codes] that better describes the error.
** We admit that this is a goofy design. The problem has been fixed
** with the "v2" interface. If you prepare all of your SQL statements
-** using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()]
-** or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead
+** using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()]
+** or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead
** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
** then the more specific [error codes] are returned directly
-** by sqlite3_step(). The use of the "vX" interfaces is recommended.
+** by sqlite3_step(). The use of the "vX" interfaces is recommended.
*/
-SQLITE_API int sqlite3_step(sqlite3_stmt*);
+SQLITE_API int sqlite3_step(sqlite3_stmt*);
/*
** CAPI3REF: Number of columns in a result set
@@ -4831,7 +4831,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt*);
**
** See also: [sqlite3_column_count()]
*/
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Fundamental Datatypes
@@ -4870,28 +4870,28 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** KEYWORDS: {column access functions}
** METHOD: sqlite3_stmt
**
-** <b>Summary:</b>
-** <blockquote><table border=0 cellpadding=0 cellspacing=0>
-** <tr><td><b>sqlite3_column_blob</b><td>&rarr;<td>BLOB result
-** <tr><td><b>sqlite3_column_double</b><td>&rarr;<td>REAL result
-** <tr><td><b>sqlite3_column_int</b><td>&rarr;<td>32-bit INTEGER result
-** <tr><td><b>sqlite3_column_int64</b><td>&rarr;<td>64-bit INTEGER result
-** <tr><td><b>sqlite3_column_text</b><td>&rarr;<td>UTF-8 TEXT result
-** <tr><td><b>sqlite3_column_text16</b><td>&rarr;<td>UTF-16 TEXT result
+** <b>Summary:</b>
+** <blockquote><table border=0 cellpadding=0 cellspacing=0>
+** <tr><td><b>sqlite3_column_blob</b><td>&rarr;<td>BLOB result
+** <tr><td><b>sqlite3_column_double</b><td>&rarr;<td>REAL result
+** <tr><td><b>sqlite3_column_int</b><td>&rarr;<td>32-bit INTEGER result
+** <tr><td><b>sqlite3_column_int64</b><td>&rarr;<td>64-bit INTEGER result
+** <tr><td><b>sqlite3_column_text</b><td>&rarr;<td>UTF-8 TEXT result
+** <tr><td><b>sqlite3_column_text16</b><td>&rarr;<td>UTF-16 TEXT result
** <tr><td><b>sqlite3_column_value</b><td>&rarr;<td>The result as an
-** [sqlite3_value|unprotected sqlite3_value] object.
-** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
-** <tr><td><b>sqlite3_column_bytes</b><td>&rarr;<td>Size of a BLOB
-** or a UTF-8 TEXT result in bytes
-** <tr><td><b>sqlite3_column_bytes16&nbsp;&nbsp;</b>
-** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
-** TEXT in bytes
-** <tr><td><b>sqlite3_column_type</b><td>&rarr;<td>Default
-** datatype of the result
-** </table></blockquote>
-**
-** <b>Details:</b>
-**
+** [sqlite3_value|unprotected sqlite3_value] object.
+** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
+** <tr><td><b>sqlite3_column_bytes</b><td>&rarr;<td>Size of a BLOB
+** or a UTF-8 TEXT result in bytes
+** <tr><td><b>sqlite3_column_bytes16&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
+** TEXT in bytes
+** <tr><td><b>sqlite3_column_type</b><td>&rarr;<td>Default
+** datatype of the result
+** </table></blockquote>
+**
+** <b>Details:</b>
+**
** ^These routines return information about a single column of the current
** result row of a query. ^In every case the first argument is a pointer
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
@@ -4913,29 +4913,29 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** are called from a different thread while any of these routines
** are pending, then the results are undefined.
**
-** The first six interfaces (_blob, _double, _int, _int64, _text, and _text16)
-** each return the value of a result column in a specific data format. If
-** the result column is not initially in the requested format (for example,
-** if the query returns an integer but the sqlite3_column_text() interface
-** is used to extract the value) then an automatic type conversion is performed.
-**
+** The first six interfaces (_blob, _double, _int, _int64, _text, and _text16)
+** each return the value of a result column in a specific data format. If
+** the result column is not initially in the requested format (for example,
+** if the query returns an integer but the sqlite3_column_text() interface
+** is used to extract the value) then an automatic type conversion is performed.
+**
** ^The sqlite3_column_type() routine returns the
** [SQLITE_INTEGER | datatype code] for the initial data type
** of the result column. ^The returned value is one of [SQLITE_INTEGER],
-** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].
-** The return value of sqlite3_column_type() can be used to decide which
-** of the first six interface should be used to extract the column value.
-** The value returned by sqlite3_column_type() is only meaningful if no
+** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].
+** The return value of sqlite3_column_type() can be used to decide which
+** of the first six interface should be used to extract the column value.
+** The value returned by sqlite3_column_type() is only meaningful if no
** automatic type conversions have occurred for the value in question.
-** After a type conversion, the result of calling sqlite3_column_type()
-** is undefined, though harmless. Future
+** After a type conversion, the result of calling sqlite3_column_type()
+** is undefined, though harmless. Future
** versions of SQLite may change the behavior of sqlite3_column_type()
** following a type conversion.
**
-** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes()
-** or sqlite3_column_bytes16() interfaces can be used to determine the size
-** of that BLOB or string.
-**
+** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes()
+** or sqlite3_column_bytes16() interfaces can be used to determine the size
+** of that BLOB or string.
+**
** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
** routine returns the number of bytes in that BLOB or string.
** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts
@@ -4972,13 +4972,13 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** [sqlite3_column_value()] is used in any other way, including calls
** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
** or [sqlite3_value_bytes()], the behavior is not threadsafe.
-** Hence, the sqlite3_column_value() interface
+** Hence, the sqlite3_column_value() interface
** is normally only useful within the implementation of
-** [application-defined SQL functions] or [virtual tables], not within
-** top-level application code.
+** [application-defined SQL functions] or [virtual tables], not within
+** top-level application code.
**
-** The these routines may attempt to convert the datatype of the result.
-** ^For example, if the internal representation is FLOAT and a text result
+** The these routines may attempt to convert the datatype of the result.
+** ^For example, if the internal representation is FLOAT and a text result
** is requested, [sqlite3_snprintf()] is used internally to perform the
** conversion automatically. ^(The following table details the conversions
** that are applied:
@@ -5050,7 +5050,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** ^The pointers returned are valid until a type conversion occurs as
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
** [sqlite3_finalize()] is called. ^The memory space used to hold strings
-** and BLOBs is freed automatically. Do not pass the pointers returned
+** and BLOBs is freed automatically. Do not pass the pointers returned
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
** [sqlite3_free()].
**
@@ -5074,16 +5074,16 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** return value is obtained and before any
** other SQLite interface is called on the same [database connection].
*/
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
+SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
/*
** CAPI3REF: Destroy A Prepared Statement Object
@@ -5111,7 +5111,7 @@ SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
** statement after it has been finalized can result in undefined and
** undesirable behavior such as segfaults and heap corruption.
*/
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Reset A Prepared Statement Object
@@ -5138,7 +5138,7 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
** ^The [sqlite3_reset(S)] interface does not change the values
** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Create Or Redefine SQL Functions
@@ -5263,7 +5263,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** close the database connection nor finalize or reset the prepared
** statement in which the function is running.
*/
-SQLITE_API int sqlite3_create_function(
+SQLITE_API int sqlite3_create_function(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -5273,7 +5273,7 @@ SQLITE_API int sqlite3_create_function(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int sqlite3_create_function16(
+SQLITE_API int sqlite3_create_function16(
sqlite3 *db,
const void *zFunctionName,
int nArg,
@@ -5283,7 +5283,7 @@ SQLITE_API int sqlite3_create_function16(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int sqlite3_create_function_v2(
+SQLITE_API int sqlite3_create_function_v2(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -5401,12 +5401,12 @@ SQLITE_API int sqlite3_create_window_function(
** these functions, we will not explain what they do.
*/
#ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
-SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
+SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
void*,sqlite3_int64);
#endif
@@ -5414,45 +5414,45 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** CAPI3REF: Obtaining SQL Values
** METHOD: sqlite3_value
**
-** <b>Summary:</b>
-** <blockquote><table border=0 cellpadding=0 cellspacing=0>
-** <tr><td><b>sqlite3_value_blob</b><td>&rarr;<td>BLOB value
-** <tr><td><b>sqlite3_value_double</b><td>&rarr;<td>REAL value
-** <tr><td><b>sqlite3_value_int</b><td>&rarr;<td>32-bit INTEGER value
-** <tr><td><b>sqlite3_value_int64</b><td>&rarr;<td>64-bit INTEGER value
-** <tr><td><b>sqlite3_value_pointer</b><td>&rarr;<td>Pointer value
-** <tr><td><b>sqlite3_value_text</b><td>&rarr;<td>UTF-8 TEXT value
-** <tr><td><b>sqlite3_value_text16</b><td>&rarr;<td>UTF-16 TEXT value in
-** the native byteorder
-** <tr><td><b>sqlite3_value_text16be</b><td>&rarr;<td>UTF-16be TEXT value
-** <tr><td><b>sqlite3_value_text16le</b><td>&rarr;<td>UTF-16le TEXT value
-** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
-** <tr><td><b>sqlite3_value_bytes</b><td>&rarr;<td>Size of a BLOB
-** or a UTF-8 TEXT in bytes
-** <tr><td><b>sqlite3_value_bytes16&nbsp;&nbsp;</b>
-** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
-** TEXT in bytes
-** <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
-** datatype of the value
-** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
-** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
-** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
-** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
-** against a virtual table.
+** <b>Summary:</b>
+** <blockquote><table border=0 cellpadding=0 cellspacing=0>
+** <tr><td><b>sqlite3_value_blob</b><td>&rarr;<td>BLOB value
+** <tr><td><b>sqlite3_value_double</b><td>&rarr;<td>REAL value
+** <tr><td><b>sqlite3_value_int</b><td>&rarr;<td>32-bit INTEGER value
+** <tr><td><b>sqlite3_value_int64</b><td>&rarr;<td>64-bit INTEGER value
+** <tr><td><b>sqlite3_value_pointer</b><td>&rarr;<td>Pointer value
+** <tr><td><b>sqlite3_value_text</b><td>&rarr;<td>UTF-8 TEXT value
+** <tr><td><b>sqlite3_value_text16</b><td>&rarr;<td>UTF-16 TEXT value in
+** the native byteorder
+** <tr><td><b>sqlite3_value_text16be</b><td>&rarr;<td>UTF-16be TEXT value
+** <tr><td><b>sqlite3_value_text16le</b><td>&rarr;<td>UTF-16le TEXT value
+** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
+** <tr><td><b>sqlite3_value_bytes</b><td>&rarr;<td>Size of a BLOB
+** or a UTF-8 TEXT in bytes
+** <tr><td><b>sqlite3_value_bytes16&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
+** TEXT in bytes
+** <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
+** datatype of the value
+** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
+** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
+** against a virtual table.
** <tr><td><b>sqlite3_value_frombind&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>True if value originated from a [bound parameter]
-** </table></blockquote>
+** </table></blockquote>
**
-** <b>Details:</b>
+** <b>Details:</b>
**
-** These routines extract type, size, and content information from
-** [protected sqlite3_value] objects. Protected sqlite3_value objects
+** These routines extract type, size, and content information from
+** [protected sqlite3_value] objects. Protected sqlite3_value objects
** are used to pass parameter information into the functions that
** implement [application-defined SQL functions] and [virtual tables].
-**
+**
** These routines work only with [protected sqlite3_value] objects.
** Any attempt to use these routines on an [unprotected sqlite3_value]
-** is not threadsafe.
+** is not threadsafe.
**
** ^These routines work just like the corresponding [column access functions]
** except that these routines take a single [protected sqlite3_value] object
@@ -5464,23 +5464,23 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** extract UTF-16 strings as big-endian and little-endian respectively.
**
** ^If [sqlite3_value] object V was initialized
-** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)]
-** and if X and Y are strings that compare equal according to strcmp(X,Y),
-** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise,
+** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)]
+** and if X and Y are strings that compare equal according to strcmp(X,Y),
+** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise,
** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer()
-** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
-**
-** ^(The sqlite3_value_type(V) interface returns the
-** [SQLITE_INTEGER | datatype code] for the initial datatype of the
-** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER],
-** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^
-** Other interfaces might change the datatype for an sqlite3_value object.
-** For example, if the datatype is initially SQLITE_INTEGER and
-** sqlite3_value_text(V) is called to extract a text value for that
-** integer, then subsequent calls to sqlite3_value_type(V) might return
-** SQLITE_TEXT. Whether or not a persistent internal datatype conversion
-** occurs is undefined and may change from one release of SQLite to the next.
-**
+** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
+**
+** ^(The sqlite3_value_type(V) interface returns the
+** [SQLITE_INTEGER | datatype code] for the initial datatype of the
+** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER],
+** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^
+** Other interfaces might change the datatype for an sqlite3_value object.
+** For example, if the datatype is initially SQLITE_INTEGER and
+** sqlite3_value_text(V) is called to extract a text value for that
+** integer, then subsequent calls to sqlite3_value_type(V) might return
+** SQLITE_TEXT. Whether or not a persistent internal datatype conversion
+** occurs is undefined and may change from one release of SQLite to the next.
+**
** ^(The sqlite3_value_numeric_type() interface attempts to apply
** numeric affinity to the value. This means that an attempt is
** made to convert the value to an integer or floating point. If
@@ -5489,19 +5489,19 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** then the conversion is performed. Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
-** ^Within the [xUpdate] method of a [virtual table], the
-** sqlite3_value_nochange(X) interface returns true if and only if
-** the column corresponding to X is unchanged by the UPDATE operation
-** that the xUpdate method call was invoked to implement and if
-** and the prior [xColumn] method call that was invoked to extracted
-** the value for that column returned without setting a result (probably
-** because it queried [sqlite3_vtab_nochange()] and found that the column
-** was unchanging). ^Within an [xUpdate] method, any value for which
-** sqlite3_value_nochange(X) is true will in all other respects appear
-** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other
-** than within an [xUpdate] method call for an UPDATE statement, then
-** the return value is arbitrary and meaningless.
-**
+** ^Within the [xUpdate] method of a [virtual table], the
+** sqlite3_value_nochange(X) interface returns true if and only if
+** the column corresponding to X is unchanged by the UPDATE operation
+** that the xUpdate method call was invoked to implement and if
+** and the prior [xColumn] method call that was invoked to extracted
+** the value for that column returned without setting a result (probably
+** because it queried [sqlite3_vtab_nochange()] and found that the column
+** was unchanging). ^Within an [xUpdate] method, any value for which
+** sqlite3_value_nochange(X) is true will in all other respects appear
+** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other
+** than within an [xUpdate] method call for an UPDATE statement, then
+** the return value is arbitrary and meaningless.
+**
** ^The sqlite3_value_frombind(X) interface returns non-zero if the
** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
** interfaces. ^If X comes from an SQL literal value, or a table column,
@@ -5538,35 +5538,35 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** return value is obtained and before any
** other SQLite interface is called on the same [database connection].
*/
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
-SQLITE_API double sqlite3_value_double(sqlite3_value*);
-SQLITE_API int sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
-SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*);
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API int sqlite3_value_type(sqlite3_value*);
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
-SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
+SQLITE_API double sqlite3_value_double(sqlite3_value*);
+SQLITE_API int sqlite3_value_int(sqlite3_value*);
+SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
+SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*);
+SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
+SQLITE_API int sqlite3_value_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
/*
-** CAPI3REF: Finding The Subtype Of SQL Values
-** METHOD: sqlite3_value
-**
-** The sqlite3_value_subtype(V) function returns the subtype for
-** an [application-defined SQL function] argument V. The subtype
-** information can be used to pass a limited amount of context from
-** one SQL function to another. Use the [sqlite3_result_subtype()]
-** routine to set the subtype for the return value of an SQL function.
-*/
-SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
-
-/*
+** CAPI3REF: Finding The Subtype Of SQL Values
+** METHOD: sqlite3_value
+**
+** The sqlite3_value_subtype(V) function returns the subtype for
+** an [application-defined SQL function] argument V. The subtype
+** information can be used to pass a limited amount of context from
+** one SQL function to another. Use the [sqlite3_result_subtype()]
+** routine to set the subtype for the return value of an SQL function.
+*/
+SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
+
+/*
** CAPI3REF: Copy And Free SQL Values
** METHOD: sqlite3_value
**
@@ -5580,8 +5580,8 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
** then sqlite3_value_free(V) is a harmless no-op.
*/
-SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
-SQLITE_API void sqlite3_value_free(sqlite3_value*);
+SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
+SQLITE_API void sqlite3_value_free(sqlite3_value*);
/*
** CAPI3REF: Obtain Aggregate Function Context
@@ -5626,7 +5626,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*);
** This routine must be called from the same thread in which
** the aggregate SQL function is running.
*/
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/*
** CAPI3REF: User Data For Functions
@@ -5641,7 +5641,7 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
** This routine must be called from the same thread in which
** the application-defined function is running.
*/
-SQLITE_API void *sqlite3_user_data(sqlite3_context*);
+SQLITE_API void *sqlite3_user_data(sqlite3_context*);
/*
** CAPI3REF: Database Connection For Functions
@@ -5653,7 +5653,7 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context*);
** and [sqlite3_create_function16()] routines that originally
** registered the application defined function.
*/
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
+SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/*
** CAPI3REF: Function Auxiliary Data
@@ -5670,11 +5670,11 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
-** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
-** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
-** value to the application-defined function. ^N is zero for the left-most
-** function argument. ^If there is no metadata
-** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
+** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
+** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
+** value to the application-defined function. ^N is zero for the left-most
+** function argument. ^If there is no metadata
+** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
@@ -5686,13 +5686,13 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** SQLite will invoke the destructor function X with parameter P exactly
** once, when the metadata is discarded.
** SQLite is free to discard the metadata at any time, including: <ul>
-** <li> ^(when the corresponding function parameter changes)^, or
-** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
-** SQL statement)^, or
-** <li> ^(when sqlite3_set_auxdata() is invoked again on the same
-** parameter)^, or
+** <li> ^(when the corresponding function parameter changes)^, or
+** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+** SQL statement)^, or
+** <li> ^(when sqlite3_set_auxdata() is invoked again on the same
+** parameter)^, or
** <li> ^(during the original sqlite3_set_auxdata() call when a memory
-** allocation error occurs.)^ </ul>
+** allocation error occurs.)^ </ul>
**
** Note the last bullet in particular. The destructor X in
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
@@ -5705,15 +5705,15 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
-** The value of the N parameter to these interfaces should be non-negative.
-** Future enhancements may make use of negative N values to define new
-** kinds of function caching behavior.
-**
+** The value of the N parameter to these interfaces should be non-negative.
+** Future enhancements may make use of negative N values to define new
+** kinds of function caching behavior.
+**
** These routines must be called from the same thread in which
** the SQL function is running.
*/
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
+SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
+SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
/*
@@ -5833,7 +5833,7 @@ typedef void (*sqlite3_destructor_type)(void*);
** when it has finished using that result.
** ^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
+** then SQLite makes a copy of the result into space obtained
** from [sqlite3_malloc()] before it returns.
**
** ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and
@@ -5865,60 +5865,60 @@ typedef void (*sqlite3_destructor_type)(void*);
** [unprotected sqlite3_value] object is required, so either
** kind of [sqlite3_value] object can be used with this interface.
**
-** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an
-** SQL NULL value, just like [sqlite3_result_null(C)], except that it
+** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an
+** SQL NULL value, just like [sqlite3_result_null(C)], except that it
** also associates the host-language pointer P or type T with that
-** NULL value such that the pointer can be retrieved within an
-** [application-defined SQL function] using [sqlite3_value_pointer()].
-** ^If the D parameter is not NULL, then it is a pointer to a destructor
-** for the P parameter. ^SQLite invokes D with P as its only argument
-** when SQLite is finished with P. The T parameter should be a static
-** string and preferably a string literal. The sqlite3_result_pointer()
-** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
-**
+** NULL value such that the pointer can be retrieved within an
+** [application-defined SQL function] using [sqlite3_value_pointer()].
+** ^If the D parameter is not NULL, then it is a pointer to a destructor
+** for the P parameter. ^SQLite invokes D with P as its only argument
+** when SQLite is finished with P. The T parameter should be a static
+** string and preferably a string literal. The sqlite3_result_pointer()
+** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
+**
** If these routines are called from within the different thread
** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined.
*/
-SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
+SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
sqlite3_uint64,void(*)(void*));
-SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void sqlite3_result_null(sqlite3_context*);
-SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
+SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
+SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
+SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+SQLITE_API void sqlite3_result_null(sqlite3_context*);
+SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
void(*)(void*), unsigned char encoding);
-SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*));
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
-SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
-
-
-/*
-** CAPI3REF: Setting The Subtype Of An SQL Function
-** METHOD: sqlite3_context
-**
-** The sqlite3_result_subtype(C,T) function causes the subtype of
+SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*));
+SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
+SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
+
+
+/*
+** CAPI3REF: Setting The Subtype Of An SQL Function
+** METHOD: sqlite3_context
+**
+** The sqlite3_result_subtype(C,T) function causes the subtype of
** the result from the [application-defined SQL function] with
** [sqlite3_context] C to be the value T. Only the lower 8 bits
-** of the subtype T are preserved in current versions of SQLite;
-** higher order bits are discarded.
-** The number of subtype bytes preserved by SQLite might increase
-** in future releases of SQLite.
-*/
-SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
-
-/*
+** of the subtype T are preserved in current versions of SQLite;
+** higher order bits are discarded.
+** The number of subtype bytes preserved by SQLite might increase
+** in future releases of SQLite.
+*/
+SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
+
+/*
** CAPI3REF: Define New Collating Sequences
** METHOD: sqlite3
**
@@ -5999,14 +5999,14 @@ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
**
** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
*/
-SQLITE_API int sqlite3_create_collation(
+SQLITE_API int sqlite3_create_collation(
sqlite3*,
const char *zName,
int eTextRep,
void *pArg,
int(*xCompare)(void*,int,const void*,int,const void*)
);
-SQLITE_API int sqlite3_create_collation_v2(
+SQLITE_API int sqlite3_create_collation_v2(
sqlite3*,
const char *zName,
int eTextRep,
@@ -6014,7 +6014,7 @@ SQLITE_API int sqlite3_create_collation_v2(
int(*xCompare)(void*,int,const void*,int,const void*),
void(*xDestroy)(void*)
);
-SQLITE_API int sqlite3_create_collation16(
+SQLITE_API int sqlite3_create_collation16(
sqlite3*,
const void *zName,
int eTextRep,
@@ -6049,12 +6049,12 @@ SQLITE_API int sqlite3_create_collation16(
** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
** [sqlite3_create_collation_v2()].
*/
-SQLITE_API int sqlite3_collation_needed(
+SQLITE_API int sqlite3_collation_needed(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const char*)
);
-SQLITE_API int sqlite3_collation_needed16(
+SQLITE_API int sqlite3_collation_needed16(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const void*)
@@ -6065,7 +6065,7 @@ SQLITE_API int sqlite3_collation_needed16(
** Specify the activation key for a CEROD database. Unless
** activated, none of the CEROD routines will work.
*/
-SQLITE_API void sqlite3_activate_cerod(
+SQLITE_API void sqlite3_activate_cerod(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -6087,7 +6087,7 @@ SQLITE_API void sqlite3_activate_cerod(
** all, then the behavior of sqlite3_sleep() may deviate from the description
** in the previous paragraphs.
*/
-SQLITE_API int sqlite3_sleep(int);
+SQLITE_API int sqlite3_sleep(int);
/*
** CAPI3REF: Name Of The Folder Holding Temporary Files
@@ -6241,7 +6241,7 @@ SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zVa
** connection while this routine is running, then the return value
** is undefined.
*/
-SQLITE_API int sqlite3_get_autocommit(sqlite3*);
+SQLITE_API int sqlite3_get_autocommit(sqlite3*);
/*
** CAPI3REF: Find The Database Handle Of A Prepared Statement
@@ -6254,7 +6254,7 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*);
** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
** create the statement in the first place.
*/
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
+SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
/*
** CAPI3REF: Return The Filename For A Database Connection
@@ -6286,7 +6286,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
** <li> [sqlite3_filename_wal()]
** </ul>
*/
-SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
+SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine if a database is read-only
@@ -6296,7 +6296,7 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
** of connection D is read-only, 0 if it is read/write, or -1 if N is not
** the name of a database on connection D.
*/
-SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
+SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine the transaction state of a database
@@ -6363,7 +6363,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema);
** [sqlite3_next_stmt(D,S)] must refer to an open database
** connection and in particular must not be a NULL pointer.
*/
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
+SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
** CAPI3REF: Commit And Rollback Notification Callbacks
@@ -6412,8 +6412,8 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
**
** See also the [sqlite3_update_hook()] interface.
*/
-SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
** CAPI3REF: Autovacuum Compaction Amount Callback
@@ -6488,7 +6488,7 @@ SQLITE_API int sqlite3_autovacuum_pages(
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
** to be invoked whenever a row is updated, inserted or deleted in
-** a [rowid table].
+** a [rowid table].
** ^Any callback set by a previous call to this function
** for the same database connection is overridden.
**
@@ -6509,7 +6509,7 @@ SQLITE_API int sqlite3_autovacuum_pages(
** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
-** is not invoked when conflicting rows are deleted because of an
+** is not invoked when conflicting rows are deleted because of an
** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
** invoked when rows are deleted using the [truncate optimization].
** The exceptions defined in this paragraph might change in a future
@@ -6527,10 +6527,10 @@ SQLITE_API int sqlite3_autovacuum_pages(
** on the same [database connection] D, or NULL for
** the first call on D.
**
-** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
-** and [sqlite3_preupdate_hook()] interfaces.
+** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
+** and [sqlite3_preupdate_hook()] interfaces.
*/
-SQLITE_API void *sqlite3_update_hook(
+SQLITE_API void *sqlite3_update_hook(
sqlite3*,
void(*)(void *,int ,char const *,char const *,sqlite3_int64),
void*
@@ -6546,7 +6546,7 @@ SQLITE_API void *sqlite3_update_hook(
**
** ^Cache sharing is enabled and disabled for an entire process.
** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]).
-** In prior versions of SQLite,
+** In prior versions of SQLite,
** sharing was enabled or disabled for each thread separately.
**
** ^(The cache sharing mode set by this interface effects all subsequent
@@ -6575,7 +6575,7 @@ SQLITE_API void *sqlite3_update_hook(
**
** See Also: [SQLite Shared-Cache Mode]
*/
-SQLITE_API int sqlite3_enable_shared_cache(int);
+SQLITE_API int sqlite3_enable_shared_cache(int);
/*
** CAPI3REF: Attempt To Free Heap Memory
@@ -6591,7 +6591,7 @@ SQLITE_API int sqlite3_enable_shared_cache(int);
**
** See also: [sqlite3_db_release_memory()]
*/
-SQLITE_API int sqlite3_release_memory(int);
+SQLITE_API int sqlite3_release_memory(int);
/*
** CAPI3REF: Free Memory Used By A Database Connection
@@ -6605,7 +6605,7 @@ SQLITE_API int sqlite3_release_memory(int);
**
** See also: [sqlite3_release_memory()]
*/
-SQLITE_API int sqlite3_db_release_memory(sqlite3*);
+SQLITE_API int sqlite3_db_release_memory(sqlite3*);
/*
** CAPI3REF: Impose A Limit On Heap Size
@@ -6671,7 +6671,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
** The circumstances under which SQLite will enforce the heap limits may
** changes in future releases of SQLite.
*/
-SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
+SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N);
/*
@@ -6683,7 +6683,7 @@ SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N);
** only. All new applications should use the
** [sqlite3_soft_heap_limit64()] interface rather than this one.
*/
-SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
+SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
/*
@@ -6698,11 +6698,11 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
** column exists. ^The sqlite3_table_column_metadata() interface returns
** SQLITE_ERROR if the specified column does not exist.
** ^If the column-name parameter to sqlite3_table_column_metadata() is a
-** NULL pointer, then this routine simply checks for the existence of the
+** NULL pointer, then this routine simply checks for the existence of the
** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
-** does not. If the table name parameter T in a call to
-** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is
-** undefined behavior.
+** does not. If the table name parameter T in a call to
+** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is
+** undefined behavior.
**
** ^The column is identified by the second, third and fourth parameters to
** this function. ^(The second parameter is either the name of the database
@@ -6755,7 +6755,7 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
** parsed, if that has not already been done, and returns an error if
** any errors are encountered while loading the schema.
*/
-SQLITE_API int sqlite3_table_column_metadata(
+SQLITE_API int sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
@@ -6797,21 +6797,21 @@ SQLITE_API int sqlite3_table_column_metadata(
** should free this memory by calling [sqlite3_free()].
**
** ^Extension loading must be enabled using
-** [sqlite3_enable_load_extension()] or
-** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
-** prior to calling this API,
+** [sqlite3_enable_load_extension()] or
+** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
+** prior to calling this API,
** otherwise an error will be returned.
**
** <b>Security warning:</b> It is recommended that the
-** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
-** interface. The use of the [sqlite3_enable_load_extension()] interface
-** should be avoided. This will keep the SQL function [load_extension()]
-** disabled and prevent SQL injections from giving attackers
-** access to extension loading capabilities.
-**
+** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
+** interface. The use of the [sqlite3_enable_load_extension()] interface
+** should be avoided. This will keep the SQL function [load_extension()]
+** disabled and prevent SQL injections from giving attackers
+** access to extension loading capabilities.
+**
** See also the [load_extension() SQL function].
*/
-SQLITE_API int sqlite3_load_extension(
+SQLITE_API int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Derived from zFile if 0 */
@@ -6831,19 +6831,19 @@ SQLITE_API int sqlite3_load_extension(
** ^Call the sqlite3_enable_load_extension() routine with onoff==1
** to turn extension loading on and call it with onoff==0 to turn
** it back off again.
-**
-** ^This interface enables or disables both the C-API
-** [sqlite3_load_extension()] and the SQL function [load_extension()].
-** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
-** to enable or disable only the C-API.)^
-**
-** <b>Security warning:</b> It is recommended that extension loading
+**
+** ^This interface enables or disables both the C-API
+** [sqlite3_load_extension()] and the SQL function [load_extension()].
+** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
+** to enable or disable only the C-API.)^
+**
+** <b>Security warning:</b> It is recommended that extension loading
** be enabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
-** rather than this interface, so the [load_extension()] SQL function
-** remains disabled. This will prevent SQL injections from giving attackers
-** access to extension loading capabilities.
+** rather than this interface, so the [load_extension()] SQL function
+** remains disabled. This will prevent SQL injections from giving attackers
+** access to extension loading capabilities.
*/
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
+SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
/*
** CAPI3REF: Automatically Load Statically Linked Extensions
@@ -6855,7 +6855,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
**
** ^(Even though the function prototype shows that xEntryPoint() takes
** no arguments and returns void, SQLite invokes xEntryPoint() with three
-** arguments and expects an integer result as if the signature of the
+** arguments and expects an integer result as if the signature of the
** entry point where as follows:
**
** <blockquote><pre>
@@ -6881,7 +6881,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** See also: [sqlite3_reset_auto_extension()]
** and [sqlite3_cancel_auto_extension()]
*/
-SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void));
+SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void));
/*
** CAPI3REF: Cancel Automatic Extension Loading
@@ -6893,7 +6893,7 @@ SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void));
** unregistered and it returns 0 if X was not on the list of initialization
** routines.
*/
-SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
+SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
/*
** CAPI3REF: Reset Automatic Extension Loading
@@ -6901,7 +6901,7 @@ SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
** ^This interface disables all automatic extensions previously
** registered using [sqlite3_auto_extension()].
*/
-SQLITE_API void sqlite3_reset_auto_extension(void);
+SQLITE_API void sqlite3_reset_auto_extension(void);
/*
** The interface to the virtual-table mechanism is currently considered
@@ -7006,17 +7006,17 @@ struct sqlite3_module {
** ^Information about the ORDER BY clause is stored in aOrderBy[].
** ^Each term of aOrderBy records a column of the ORDER BY clause.
**
-** The colUsed field indicates which columns of the virtual table may be
-** required by the current scan. Virtual table columns are numbered from
-** zero in the order in which they appear within the CREATE TABLE statement
-** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
-** the corresponding bit is set within the colUsed mask if the column may be
-** required by SQLite. If the table has at least 64 columns and any column
-** to the right of the first 63 is required, then bit 63 of colUsed is also
-** set. In other words, column iCol may be required if the expression
+** The colUsed field indicates which columns of the virtual table may be
+** required by the current scan. Virtual table columns are numbered from
+** zero in the order in which they appear within the CREATE TABLE statement
+** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
+** the corresponding bit is set within the colUsed mask if the column may be
+** required by SQLite. If the table has at least 64 columns and any column
+** to the right of the first 63 is required, then bit 63 of colUsed is also
+** set. In other words, column iCol may be required if the expression
** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to
-** non-zero.
-**
+** non-zero.
+**
** The [xBestIndex] method must fill aConstraintUsage[] with information
** about what parameters to pass to xFilter. ^If argvIndex>0 then
** the right-hand side of the corresponding aConstraint[] is evaluated
@@ -7049,38 +7049,38 @@ struct sqlite3_module {
** will be returned by the strategy.
**
** The xBestIndex method may optionally populate the idxFlags field with a
-** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
-** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
+** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
+** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
** assumes that the strategy may visit at most one row.
-**
-** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
-** SQLite also assumes that if a call to the xUpdate() method is made as
-** part of the same statement to delete or update a virtual table row and the
-** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
-** any database changes. In other words, if the xUpdate() returns
-** SQLITE_CONSTRAINT, the database contents must be exactly as they were
-** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
-** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
-** the xUpdate method are automatically rolled back by SQLite.
-**
+**
+** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
+** SQLite also assumes that if a call to the xUpdate() method is made as
+** part of the same statement to delete or update a virtual table row and the
+** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
+** any database changes. In other words, if the xUpdate() returns
+** SQLITE_CONSTRAINT, the database contents must be exactly as they were
+** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
+** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
+** the xUpdate method are automatically rolled back by SQLite.
+**
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
** structure for SQLite [version 3.8.2] ([dateof:3.8.2]).
-** If a virtual table extension is
+** If a virtual table extension is
** used with an SQLite version earlier than 3.8.2, the results of attempting
** to read or write the estimatedRows field are undefined (but are likely
** to include crashing the application). The estimatedRows field should
** therefore only be used if [sqlite3_libversion_number()] returns a
-** value greater than or equal to 3008002. Similarly, the idxFlags field
+** value greater than or equal to 3008002. Similarly, the idxFlags field
** was added for [version 3.9.0] ([dateof:3.9.0]).
-** It may therefore only be used if
-** sqlite3_libversion_number() returns a value greater than or equal to
-** 3009000.
+** It may therefore only be used if
+** sqlite3_libversion_number() returns a value greater than or equal to
+** 3009000.
*/
struct sqlite3_index_info {
/* Inputs */
int nConstraint; /* Number of entries in aConstraint */
struct sqlite3_index_constraint {
- int iColumn; /* Column constrained. -1 for ROWID */
+ int iColumn; /* Column constrained. -1 for ROWID */
unsigned char op; /* Constraint operator */
unsigned char usable; /* True if this constraint is usable */
int iTermOffset; /* Used internally - xBestIndex should ignore */
@@ -7102,22 +7102,22 @@ struct sqlite3_index_info {
double estimatedCost; /* Estimated cost of using this index */
/* Fields below are only available in SQLite 3.8.2 and later */
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
- /* Fields below are only available in SQLite 3.9.0 and later */
- int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
- /* Fields below are only available in SQLite 3.10.0 and later */
- sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */
+ /* Fields below are only available in SQLite 3.9.0 and later */
+ int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
+ /* Fields below are only available in SQLite 3.10.0 and later */
+ sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */
};
/*
-** CAPI3REF: Virtual Table Scan Flags
+** CAPI3REF: Virtual Table Scan Flags
**
** Virtual table implementations are allowed to set the
** [sqlite3_index_info].idxFlags field to some combination of
** these bits.
-*/
-#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
-
-/*
+*/
+#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
+
+/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
** These macros define the allowed values for the
@@ -7125,20 +7125,20 @@ struct sqlite3_index_info {
** an operator that is part of a constraint term in the wHERE clause of
** a query that uses a [virtual table].
*/
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
-#define SQLITE_INDEX_CONSTRAINT_GT 4
-#define SQLITE_INDEX_CONSTRAINT_LE 8
-#define SQLITE_INDEX_CONSTRAINT_LT 16
-#define SQLITE_INDEX_CONSTRAINT_GE 32
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
-#define SQLITE_INDEX_CONSTRAINT_LIKE 65
-#define SQLITE_INDEX_CONSTRAINT_GLOB 66
-#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
-#define SQLITE_INDEX_CONSTRAINT_NE 68
-#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
-#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
-#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
-#define SQLITE_INDEX_CONSTRAINT_IS 72
+#define SQLITE_INDEX_CONSTRAINT_EQ 2
+#define SQLITE_INDEX_CONSTRAINT_GT 4
+#define SQLITE_INDEX_CONSTRAINT_LE 8
+#define SQLITE_INDEX_CONSTRAINT_LT 16
+#define SQLITE_INDEX_CONSTRAINT_GE 32
+#define SQLITE_INDEX_CONSTRAINT_MATCH 64
+#define SQLITE_INDEX_CONSTRAINT_LIKE 65
+#define SQLITE_INDEX_CONSTRAINT_GLOB 66
+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
+#define SQLITE_INDEX_CONSTRAINT_NE 68
+#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
+#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
+#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
+#define SQLITE_INDEX_CONSTRAINT_IS 72
#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
/*
@@ -7173,13 +7173,13 @@ struct sqlite3_index_info {
**
** See also: [sqlite3_drop_modules()]
*/
-SQLITE_API int sqlite3_create_module(
+SQLITE_API int sqlite3_create_module(
sqlite3 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite3_module *p, /* Methods for the module */
void *pClientData /* Client data for xCreate/xConnect */
);
-SQLITE_API int sqlite3_create_module_v2(
+SQLITE_API int sqlite3_create_module_v2(
sqlite3 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite3_module *p, /* Methods for the module */
@@ -7259,7 +7259,7 @@ struct sqlite3_vtab_cursor {
** to declare the format (the names and datatypes of the columns) of
** the virtual tables they implement.
*/
-SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
/*
** CAPI3REF: Overload A Function For A Virtual Table
@@ -7278,7 +7278,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
** purpose is to be a placeholder function that can be overloaded
** by a [virtual table].
*/
-SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
/*
** The interface to the virtual-table mechanism defined above (back up
@@ -7353,12 +7353,12 @@ typedef struct sqlite3_blob sqlite3_blob;
** [database connection] error code and message accessible via
** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
**
-** A BLOB referenced by sqlite3_blob_open() may be read using the
-** [sqlite3_blob_read()] interface and modified by using
-** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a
-** different row of the same table using the [sqlite3_blob_reopen()]
-** interface. However, the column, table, or database of a [BLOB handle]
-** cannot be changed after the [BLOB handle] is opened.
+** A BLOB referenced by sqlite3_blob_open() may be read using the
+** [sqlite3_blob_read()] interface and modified by using
+** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a
+** different row of the same table using the [sqlite3_blob_reopen()]
+** interface. However, the column, table, or database of a [BLOB handle]
+** cannot be changed after the [BLOB handle] is opened.
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
@@ -7382,12 +7382,12 @@ typedef struct sqlite3_blob sqlite3_blob;
**
** To avoid a resource leak, every open [BLOB handle] should eventually
** be released by a call to [sqlite3_blob_close()].
-**
-** See also: [sqlite3_blob_close()],
-** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
-** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
+**
+** See also: [sqlite3_blob_close()],
+** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
+** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
*/
-SQLITE_API int sqlite3_blob_open(
+SQLITE_API int sqlite3_blob_open(
sqlite3*,
const char *zDb,
const char *zTable,
@@ -7401,11 +7401,11 @@ SQLITE_API int sqlite3_blob_open(
** CAPI3REF: Move a BLOB Handle to a New Row
** METHOD: sqlite3_blob
**
-** ^This function is used to move an existing [BLOB handle] so that it points
+** ^This function is used to move an existing [BLOB handle] so that it points
** to a different row of the same database table. ^The new row is identified
** by the rowid value passed as the second argument. Only the row can be
** changed. ^The database, table and column on which the blob handle is open
-** remain the same. Moving an existing [BLOB handle] to a new row is
+** remain the same. Moving an existing [BLOB handle] to a new row is
** faster than closing the existing handle and opening a new one.
**
** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
@@ -7420,7 +7420,7 @@ SQLITE_API int sqlite3_blob_open(
**
** ^This function sets the database handle error code and message.
*/
-SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
/*
** CAPI3REF: Close A BLOB Handle
@@ -7443,7 +7443,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
** is passed a valid open blob handle, the values returned by the
** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
+SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
/*
** CAPI3REF: Return The Size Of An Open BLOB
@@ -7459,7 +7459,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
*/
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
+SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
/*
** CAPI3REF: Read Data From A BLOB Incrementally
@@ -7488,7 +7488,7 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
**
** See also: [sqlite3_blob_write()].
*/
-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
@@ -7530,7 +7530,7 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
**
** See also: [sqlite3_blob_read()].
*/
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
/*
** CAPI3REF: Virtual File System Objects
@@ -7561,9 +7561,9 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOff
** ^(If the default VFS is unregistered, another VFS is chosen as
** the default. The choice for the new VFS is arbitrary.)^
*/
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
+SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
+SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
/*
** CAPI3REF: Mutexes
@@ -7616,9 +7616,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** <li> SQLITE_MUTEX_STATIC_APP1
** <li> SQLITE_MUTEX_STATIC_APP2
** <li> SQLITE_MUTEX_STATIC_APP3
-** <li> SQLITE_MUTEX_STATIC_VFS1
-** <li> SQLITE_MUTEX_STATIC_VFS2
-** <li> SQLITE_MUTEX_STATIC_VFS3
+** <li> SQLITE_MUTEX_STATIC_VFS1
+** <li> SQLITE_MUTEX_STATIC_VFS2
+** <li> SQLITE_MUTEX_STATIC_VFS3
** </ul>
**
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
@@ -7679,11 +7679,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
+SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
+SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
/*
** CAPI3REF: Mutex Methods Object
@@ -7793,8 +7793,8 @@ struct sqlite3_mutex_methods {
** interface should also return 1 when given a NULL pointer.
*/
#ifndef NDEBUG
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#endif
/*
@@ -7813,7 +7813,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
-#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */
+#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */
#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
@@ -7838,7 +7838,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
** ^If the [threading mode] is Single-thread or Multi-thread then this
** routine returns a NULL pointer.
*/
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
+SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
/*
** CAPI3REF: Low-Level Control Of Database Files
@@ -7861,7 +7861,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** A few opcodes for [sqlite3_file_control()] are handled directly
** by the SQLite core and never invoke the
** sqlite3_io_methods.xFileControl method.
-** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
+** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
** a pointer to the underlying [sqlite3_file] object to be written into
** the space pointed to by the 4th parameter. The
** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
@@ -7879,9 +7879,9 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** an incorrect zDbName and an SQLITE_ERROR return from the underlying
** xFileControl method.
**
-** See also: [file control opcodes]
+** See also: [file control opcodes]
*/
-SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
/*
** CAPI3REF: Testing Interface
@@ -7900,7 +7900,7 @@ SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*
** Unlike most of the SQLite API, this function is not guaranteed to
** operate consistently from one release to the next.
*/
-SQLITE_API int sqlite3_test_control(int op, ...);
+SQLITE_API int sqlite3_test_control(int op, ...);
/*
** CAPI3REF: Testing Interface Operation Codes
@@ -7926,18 +7926,18 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
-#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
+#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
-#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
+#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
#define SQLITE_TESTCTRL_BYTEORDER 22
#define SQLITE_TESTCTRL_ISINIT 23
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
-#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
+#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
#define SQLITE_TESTCTRL_RESULT_INTREAL 27
#define SQLITE_TESTCTRL_PRNG_SEED 28
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
@@ -8155,8 +8155,8 @@ SQLITE_API char *sqlite3_str_value(sqlite3_str*);
**
** See also: [sqlite3_db_status()]
*/
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
-SQLITE_API int sqlite3_status64(
+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int sqlite3_status64(
int op,
sqlite3_int64 *pCurrent,
sqlite3_int64 *pHighwater,
@@ -8176,7 +8176,7 @@ SQLITE_API int sqlite3_status64(
** <dd>This parameter is the current amount of memory checked out
** using [sqlite3_malloc()], either directly or indirectly. The
** figure includes calls made to [sqlite3_malloc()] by the application
-** and internal memory usage by the SQLite library. Auxiliary page-cache
+** and internal memory usage by the SQLite library. Auxiliary page-cache
** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
** this parameter. The amount returned is the sum of the allocation
** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
@@ -8214,18 +8214,18 @@ SQLITE_API int sqlite3_status64(
** *pHighwater parameter to [sqlite3_status()] is of interest.
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
-** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt>
-** <dd>No longer used.</dd>
+** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt>
+** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
-** <dd>No longer used.</dd>
+** <dd>No longer used.</dd>
**
-** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
-** <dd>No longer used.</dd>
+** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
+** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
** <dd>The *pHighwater parameter records the deepest parser stack.
-** The *pCurrent value is undefined. The *pHighwater value is only
+** The *pCurrent value is undefined. The *pHighwater value is only
** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
** </dl>
**
@@ -8234,12 +8234,12 @@ SQLITE_API int sqlite3_status64(
#define SQLITE_STATUS_MEMORY_USED 0
#define SQLITE_STATUS_PAGECACHE_USED 1
#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2
-#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */
-#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */
+#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */
+#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */
#define SQLITE_STATUS_MALLOC_SIZE 5
#define SQLITE_STATUS_PARSER_STACK 6
#define SQLITE_STATUS_PAGECACHE_SIZE 7
-#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */
+#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */
#define SQLITE_STATUS_MALLOC_COUNT 9
/*
@@ -8265,7 +8265,7 @@ SQLITE_API int sqlite3_status64(
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
-SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
@@ -8312,17 +8312,17 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
**
** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]]
-** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt>
-** <dd>This parameter is similar to DBSTATUS_CACHE_USED, except that if a
-** pager cache is shared between two or more connections the bytes of heap
-** memory used by that pager cache is divided evenly between the attached
-** connections.)^ In other words, if none of the pager caches associated
-** with the database connection are shared, this request returns the same
-** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are
-** shared, the value returned by this call will be smaller than that returned
-** by DBSTATUS_CACHE_USED. ^The highwater mark associated with
-** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.
-**
+** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt>
+** <dd>This parameter is similar to DBSTATUS_CACHE_USED, except that if a
+** pager cache is shared between two or more connections the bytes of heap
+** memory used by that pager cache is divided evenly between the attached
+** connections.)^ In other words, if none of the pager caches associated
+** with the database connection are shared, this request returns the same
+** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are
+** shared, the value returned by this call will be smaller than that returned
+** by DBSTATUS_CACHE_USED. ^The highwater mark associated with
+** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.
+**
** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
** <dd>This parameter returns the approximate number of bytes of heap
** memory used to store the schema for all databases associated
@@ -8389,7 +8389,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
#define SQLITE_DBSTATUS_CACHE_MISS 8
#define SQLITE_DBSTATUS_CACHE_WRITE 9
#define SQLITE_DBSTATUS_DEFERRED_FKS 10
-#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11
+#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11
#define SQLITE_DBSTATUS_CACHE_SPILL 12
#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */
@@ -8418,7 +8418,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
**
** See also: [sqlite3_status()] and [sqlite3_db_status()].
*/
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
/*
** CAPI3REF: Status Parameters for prepared statements
@@ -8454,24 +8454,24 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
** used as a proxy for the total work done by the prepared statement.
** If the number of virtual machine operations exceeds 2147483647
** then the value returned by this statement status code is undefined.
-**
-** [[SQLITE_STMTSTATUS_REPREPARE]] <dt>SQLITE_STMTSTATUS_REPREPARE</dt>
-** <dd>^This is the number of times that the prepare statement has been
+**
+** [[SQLITE_STMTSTATUS_REPREPARE]] <dt>SQLITE_STMTSTATUS_REPREPARE</dt>
+** <dd>^This is the number of times that the prepare statement has been
** automatically regenerated due to schema changes or changes to
-** [bound parameters] that might affect the query plan.
-**
-** [[SQLITE_STMTSTATUS_RUN]] <dt>SQLITE_STMTSTATUS_RUN</dt>
-** <dd>^This is the number of times that the prepared statement has
-** been run. A single "run" for the purposes of this counter is one
-** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
-** The counter is incremented on the first [sqlite3_step()] call of each
-** cycle.
-**
-** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
-** <dd>^This is the approximate number of bytes of heap memory
-** used to store the prepared statement. ^This value is not actually
-** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
-** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
+** [bound parameters] that might affect the query plan.
+**
+** [[SQLITE_STMTSTATUS_RUN]] <dt>SQLITE_STMTSTATUS_RUN</dt>
+** <dd>^This is the number of times that the prepared statement has
+** been run. A single "run" for the purposes of this counter is one
+** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
+** The counter is incremented on the first [sqlite3_step()] call of each
+** cycle.
+**
+** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
+** <dd>^This is the approximate number of bytes of heap memory
+** used to store the prepared statement. ^This value is not actually
+** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
+** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
** </dd>
** </dl>
*/
@@ -8479,9 +8479,9 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
#define SQLITE_STMTSTATUS_VM_STEP 4
-#define SQLITE_STMTSTATUS_REPREPARE 5
-#define SQLITE_STMTSTATUS_RUN 6
-#define SQLITE_STMTSTATUS_MEMUSED 99
+#define SQLITE_STMTSTATUS_REPREPARE 5
+#define SQLITE_STMTSTATUS_RUN 6
+#define SQLITE_STMTSTATUS_MEMUSED 99
/*
** CAPI3REF: Custom Page Cache Object
@@ -8908,16 +8908,16 @@ typedef struct sqlite3_backup sqlite3_backup;
** same time as another thread is invoking sqlite3_backup_step() it is
** possible that they return invalid values.
*/
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
+SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3 *pDest, /* Destination database handle */
const char *zDestName, /* Destination database name */
sqlite3 *pSource, /* Source database handle */
const char *zSourceName /* Source database name */
);
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
+SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
/*
** CAPI3REF: Unlock Notification
@@ -9034,7 +9034,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
** the special "DROP TABLE/INDEX" case, the extended error code is just
** SQLITE_LOCKED.)^
*/
-SQLITE_API int sqlite3_unlock_notify(
+SQLITE_API int sqlite3_unlock_notify(
sqlite3 *pBlocked, /* Waiting connection */
void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
void *pNotifyArg /* Argument to pass to xNotify */
@@ -9049,50 +9049,50 @@ SQLITE_API int sqlite3_unlock_notify(
** strings in a case-independent fashion, using the same definition of "case
** independence" that SQLite uses internally when comparing identifiers.
*/
-SQLITE_API int sqlite3_stricmp(const char *, const char *);
-SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
+SQLITE_API int sqlite3_stricmp(const char *, const char *);
+SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
/*
** CAPI3REF: String Globbing
*
-** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
-** string X matches the [GLOB] pattern P.
-** ^The definition of [GLOB] pattern matching used in
+** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
+** string X matches the [GLOB] pattern P.
+** ^The definition of [GLOB] pattern matching used in
** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
-** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function
-** is case sensitive.
+** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function
+** is case sensitive.
+**
+** Note that this routine returns zero on a match and non-zero if the strings
+** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
+**
+** See also: [sqlite3_strlike()].
+*/
+SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
+
+/*
+** CAPI3REF: String LIKE Matching
+*
+** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
+** string X matches the [LIKE] pattern P with escape character E.
+** ^The definition of [LIKE] pattern matching used in
+** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
+** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without
+** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
+** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
+** insensitive - equivalent upper and lower case ASCII characters match
+** one another.
+**
+** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
+** only ASCII characters are case folded.
**
** Note that this routine returns zero on a match and non-zero if the strings
** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
-**
-** See also: [sqlite3_strlike()].
-*/
-SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
-
-/*
-** CAPI3REF: String LIKE Matching
-*
-** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
-** string X matches the [LIKE] pattern P with escape character E.
-** ^The definition of [LIKE] pattern matching used in
-** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
-** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without
-** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
-** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
-** insensitive - equivalent upper and lower case ASCII characters match
-** one another.
-**
-** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
-** only ASCII characters are case folded.
-**
-** Note that this routine returns zero on a match and non-zero if the strings
-** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
-**
-** See also: [sqlite3_strglob()].
-*/
-SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
-
-/*
+**
+** See also: [sqlite3_strglob()].
+*/
+SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
+
+/*
** CAPI3REF: Error Logging Interface
**
** ^The [sqlite3_log()] interface writes a message into the [error log]
@@ -9113,7 +9113,7 @@ SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int
** a few hundred characters, it will be truncated to the length of the
** buffer.
*/
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
+SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
/*
** CAPI3REF: Write-Ahead Log Commit Hook
@@ -9148,9 +9148,9 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
** a copy of the third parameter from the previous call, if any, or 0.
** ^Note that the [sqlite3_wal_autocheckpoint()] interface and the
** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
-** overwrite any prior [sqlite3_wal_hook()] settings.
+** overwrite any prior [sqlite3_wal_hook()] settings.
*/
-SQLITE_API void *sqlite3_wal_hook(
+SQLITE_API void *sqlite3_wal_hook(
sqlite3*,
int(*)(void *,sqlite3*,const char*,int),
void*
@@ -9185,7 +9185,7 @@ SQLITE_API void *sqlite3_wal_hook(
** is only necessary if the default setting is found to be suboptimal
** for a particular application.
*/
-SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
+SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
/*
** CAPI3REF: Checkpoint a database
@@ -9207,7 +9207,7 @@ SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
** start a callback but which do not need the full power (and corresponding
** complication) of [sqlite3_wal_checkpoint_v2()].
*/
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
/*
** CAPI3REF: Checkpoint a database
@@ -9301,7 +9301,7 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
** from SQL.
*/
-SQLITE_API int sqlite3_wal_checkpoint_v2(
+SQLITE_API int sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -9341,7 +9341,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
** of parameters after C depend on which [virtual table configuration option]
** is used.
*/
-SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Virtual Table Configuration Options
@@ -9419,50 +9419,50 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
-SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
+SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/*
-** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
-**
-** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
+** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
+**
+** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
** method of a [virtual table], then it might return true if the
-** column is being fetched as part of an UPDATE operation during which the
+** column is being fetched as part of an UPDATE operation during which the
** column value will not change. The virtual table implementation can use
** this hint as permission to substitute a return value that is less
** expensive to compute and that the corresponding
** [xUpdate] method understands as a "no-change" value.
-**
-** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
+**
+** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
** the column is not changed by the UPDATE statement, then the xColumn
-** method can optionally return without setting a result, without calling
-** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
-** In that case, [sqlite3_value_nochange(X)] will return true for the
-** same column in the [xUpdate] method.
+** method can optionally return without setting a result, without calling
+** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
+** In that case, [sqlite3_value_nochange(X)] will return true for the
+** same column in the [xUpdate] method.
**
** The sqlite3_vtab_nochange() routine is an optimization. Virtual table
** implementations should continue to give a correct answer even if the
** sqlite3_vtab_nochange() interface were to always return false. In the
** current implementation, the sqlite3_vtab_nochange() interface does always
** returns false for the enhanced [UPDATE FROM] statement.
-*/
-SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
-
-/*
-** CAPI3REF: Determine The Collation For a Virtual Table Constraint
-**
-** This function may only be called from within a call to the [xBestIndex]
+*/
+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
+
+/*
+** CAPI3REF: Determine The Collation For a Virtual Table Constraint
+**
+** This function may only be called from within a call to the [xBestIndex]
** method of a [virtual table].
-**
-** The first argument must be the sqlite3_index_info object that is the
-** first parameter to the xBestIndex() method. The second argument must be
-** an index into the aConstraint[] array belonging to the sqlite3_index_info
+**
+** The first argument must be the sqlite3_index_info object that is the
+** first parameter to the xBestIndex() method. The second argument must be
+** an index into the aConstraint[] array belonging to the sqlite3_index_info
** structure passed to xBestIndex. This function returns a pointer to a buffer
-** containing the name of the collation sequence for the corresponding
-** constraint.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
-
-/*
+** containing the name of the collation sequence for the corresponding
+** constraint.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
+
+/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
@@ -9565,7 +9565,7 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_
**
** See also: [sqlite3_stmt_scanstatus_reset()]
*/
-SQLITE_API int sqlite3_stmt_scanstatus(
+SQLITE_API int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
@@ -9581,122 +9581,122 @@ SQLITE_API int sqlite3_stmt_scanstatus(
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
-SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
+SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
-/*
-** CAPI3REF: Flush caches to disk mid-transaction
+/*
+** CAPI3REF: Flush caches to disk mid-transaction
** METHOD: sqlite3
-**
-** ^If a write-transaction is open on [database connection] D when the
-** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
+**
+** ^If a write-transaction is open on [database connection] D when the
+** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
** pages in the pager-cache that are not currently in use are written out
-** to disk. A dirty page may be in use if a database cursor created by an
-** active SQL statement is reading from it, or if it is page 1 of a database
-** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)]
-** interface flushes caches for all schemas - "main", "temp", and
-** any [attached] databases.
-**
+** to disk. A dirty page may be in use if a database cursor created by an
+** active SQL statement is reading from it, or if it is page 1 of a database
+** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)]
+** interface flushes caches for all schemas - "main", "temp", and
+** any [attached] databases.
+**
** ^If this function needs to obtain extra database locks before dirty pages
** can be flushed to disk, it does so. ^If those locks cannot be obtained
-** immediately and there is a busy-handler callback configured, it is invoked
-** in the usual manner. ^If the required lock still cannot be obtained, then
-** the database is skipped and an attempt made to flush any dirty pages
-** belonging to the next (if any) database. ^If any databases are skipped
-** because locks cannot be obtained, but no other error occurs, this
-** function returns SQLITE_BUSY.
-**
-** ^If any other error occurs while flushing dirty pages to disk (for
-** example an IO error or out-of-memory condition), then processing is
-** abandoned and an SQLite [error code] is returned to the caller immediately.
-**
-** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
-**
-** ^This function does not set the database handle error code or message
-** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
-*/
-SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
-
-/*
-** CAPI3REF: The pre-update hook.
+** immediately and there is a busy-handler callback configured, it is invoked
+** in the usual manner. ^If the required lock still cannot be obtained, then
+** the database is skipped and an attempt made to flush any dirty pages
+** belonging to the next (if any) database. ^If any databases are skipped
+** because locks cannot be obtained, but no other error occurs, this
+** function returns SQLITE_BUSY.
+**
+** ^If any other error occurs while flushing dirty pages to disk (for
+** example an IO error or out-of-memory condition), then processing is
+** abandoned and an SQLite [error code] is returned to the caller immediately.
+**
+** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
+**
+** ^This function does not set the database handle error code or message
+** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
+*/
+SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
+
+/*
+** CAPI3REF: The pre-update hook.
** METHOD: sqlite3
-**
-** ^These interfaces are only available if SQLite is compiled using the
-** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
-**
-** ^The [sqlite3_preupdate_hook()] interface registers a callback function
-** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
-** on a database table.
-** ^At most one preupdate hook may be registered at a time on a single
-** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
-** the previous setting.
-** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()]
-** with a NULL pointer as the second parameter.
-** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
-** the first parameter to callbacks.
-**
-** ^The preupdate hook only fires for changes to real database tables; the
-** preupdate hook is not invoked for changes to [virtual tables] or to
+**
+** ^These interfaces are only available if SQLite is compiled using the
+** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
+**
+** ^The [sqlite3_preupdate_hook()] interface registers a callback function
+** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
+** on a database table.
+** ^At most one preupdate hook may be registered at a time on a single
+** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
+** the previous setting.
+** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()]
+** with a NULL pointer as the second parameter.
+** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
+** the first parameter to callbacks.
+**
+** ^The preupdate hook only fires for changes to real database tables; the
+** preupdate hook is not invoked for changes to [virtual tables] or to
** system tables like sqlite_sequence or sqlite_stat1.
-**
-** ^The second parameter to the preupdate callback is a pointer to
-** the [database connection] that registered the preupdate hook.
-** ^The third parameter to the preupdate callback is one of the constants
-** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the
-** kind of update operation that is about to occur.
-** ^(The fourth parameter to the preupdate callback is the name of the
-** database within the database connection that is being modified. This
+**
+** ^The second parameter to the preupdate callback is a pointer to
+** the [database connection] that registered the preupdate hook.
+** ^The third parameter to the preupdate callback is one of the constants
+** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the
+** kind of update operation that is about to occur.
+** ^(The fourth parameter to the preupdate callback is the name of the
+** database within the database connection that is being modified. This
** will be "main" for the main database or "temp" for TEMP tables or
-** the name given after the AS keyword in the [ATTACH] statement for attached
-** databases.)^
-** ^The fifth parameter to the preupdate callback is the name of the
-** table that is being modified.
-**
-** For an UPDATE or DELETE operation on a [rowid table], the sixth
+** the name given after the AS keyword in the [ATTACH] statement for attached
+** databases.)^
+** ^The fifth parameter to the preupdate callback is the name of the
+** table that is being modified.
+**
+** For an UPDATE or DELETE operation on a [rowid table], the sixth
** parameter passed to the preupdate callback is the initial [rowid] of the
-** row being modified or deleted. For an INSERT operation on a rowid table,
+** row being modified or deleted. For an INSERT operation on a rowid table,
** or any operation on a WITHOUT ROWID table, the value of the sixth
-** parameter is undefined. For an INSERT or UPDATE on a rowid table the
-** seventh parameter is the final rowid value of the row being inserted
-** or updated. The value of the seventh parameter passed to the callback
-** function is not defined for operations on WITHOUT ROWID tables, or for
+** parameter is undefined. For an INSERT or UPDATE on a rowid table the
+** seventh parameter is the final rowid value of the row being inserted
+** or updated. The value of the seventh parameter passed to the callback
+** function is not defined for operations on WITHOUT ROWID tables, or for
** DELETE operations on rowid tables.
-**
-** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
-** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
-** provide additional information about a preupdate event. These routines
-** may only be called from within a preupdate callback. Invoking any of
-** these routines from outside of a preupdate callback or with a
-** [database connection] pointer that is different from the one supplied
-** to the preupdate callback results in undefined and probably undesirable
-** behavior.
-**
-** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns
-** in the row that is being inserted, updated, or deleted.
-**
-** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to
-** a [protected sqlite3_value] that contains the value of the Nth column of
-** the table row before it is updated. The N parameter must be between 0
-** and one less than the number of columns or the behavior will be
-** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE
-** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the
-** behavior is undefined. The [sqlite3_value] that P points to
-** will be destroyed when the preupdate callback returns.
-**
-** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to
-** a [protected sqlite3_value] that contains the value of the Nth column of
-** the table row after it is updated. The N parameter must be between 0
-** and one less than the number of columns or the behavior will be
-** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE
-** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the
-** behavior is undefined. The [sqlite3_value] that P points to
-** will be destroyed when the preupdate callback returns.
-**
-** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate
-** callback was invoked as a result of a direct insert, update, or delete
+**
+** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
+** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
+** provide additional information about a preupdate event. These routines
+** may only be called from within a preupdate callback. Invoking any of
+** these routines from outside of a preupdate callback or with a
+** [database connection] pointer that is different from the one supplied
+** to the preupdate callback results in undefined and probably undesirable
+** behavior.
+**
+** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns
+** in the row that is being inserted, updated, or deleted.
+**
+** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to
+** a [protected sqlite3_value] that contains the value of the Nth column of
+** the table row before it is updated. The N parameter must be between 0
+** and one less than the number of columns or the behavior will be
+** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE
+** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the
+** behavior is undefined. The [sqlite3_value] that P points to
+** will be destroyed when the preupdate callback returns.
+**
+** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to
+** a [protected sqlite3_value] that contains the value of the Nth column of
+** the table row after it is updated. The N parameter must be between 0
+** and one less than the number of columns or the behavior will be
+** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE
+** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the
+** behavior is undefined. The [sqlite3_value] that P points to
+** will be destroyed when the preupdate callback returns.
+**
+** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate
+** callback was invoked as a result of a direct insert, update, or delete
** operation; or 1 for inserts, updates, or deletes invoked by top-level
-** triggers; or 2 for changes resulting from triggers called by top-level
-** triggers; and so forth.
-**
+** triggers; or 2 for changes resulting from triggers called by top-level
+** triggers; and so forth.
+**
** When the [sqlite3_blob_write()] API is used to update a blob column,
** the pre-update hook is invoked with SQLITE_DELETE. This is because the
** in this case the new values are not available. In this case, when a
@@ -9706,126 +9706,126 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
** pre-update hook is being invoked for some other reason, including a
** regular DELETE, sqlite3_preupdate_blobwrite() returns -1.
**
-** See also: [sqlite3_update_hook()]
-*/
-#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
-SQLITE_API void *sqlite3_preupdate_hook(
- sqlite3 *db,
- void(*xPreUpdate)(
- void *pCtx, /* Copy of third arg to preupdate_hook() */
- sqlite3 *db, /* Database handle */
- int op, /* SQLITE_UPDATE, DELETE or INSERT */
- char const *zDb, /* Database name */
- char const *zName, /* Table name */
- sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */
- sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */
- ),
- void*
-);
-SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
-SQLITE_API int sqlite3_preupdate_count(sqlite3 *);
-SQLITE_API int sqlite3_preupdate_depth(sqlite3 *);
-SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
+** See also: [sqlite3_update_hook()]
+*/
+#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+SQLITE_API void *sqlite3_preupdate_hook(
+ sqlite3 *db,
+ void(*xPreUpdate)(
+ void *pCtx, /* Copy of third arg to preupdate_hook() */
+ sqlite3 *db, /* Database handle */
+ int op, /* SQLITE_UPDATE, DELETE or INSERT */
+ char const *zDb, /* Database name */
+ char const *zName, /* Table name */
+ sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */
+ sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */
+ ),
+ void*
+);
+SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
+SQLITE_API int sqlite3_preupdate_count(sqlite3 *);
+SQLITE_API int sqlite3_preupdate_depth(sqlite3 *);
+SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *);
-#endif
-
-/*
-** CAPI3REF: Low-level system error code
+#endif
+
+/*
+** CAPI3REF: Low-level system error code
** METHOD: sqlite3
-**
-** ^Attempt to return the underlying operating system error code or error
-** number that caused the most recent I/O error or failure to open a file.
-** The return value is OS-dependent. For example, on unix systems, after
-** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
-** called to get back the underlying "errno" that caused the problem, such
+**
+** ^Attempt to return the underlying operating system error code or error
+** number that caused the most recent I/O error or failure to open a file.
+** The return value is OS-dependent. For example, on unix systems, after
+** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
+** called to get back the underlying "errno" that caused the problem, such
** as ENOSPC, EAUTH, EISDIR, and so forth.
-*/
-SQLITE_API int sqlite3_system_errno(sqlite3*);
-
-/*
-** CAPI3REF: Database Snapshot
-** KEYWORDS: {snapshot} {sqlite3_snapshot}
-**
-** An instance of the snapshot object records the state of a [WAL mode]
-** database for some specific point in history.
-**
-** In [WAL mode], multiple [database connections] that are open on the
-** same database file can each be reading a different historical version
-** of the database file. When a [database connection] begins a read
-** transaction, that connection sees an unchanging copy of the database
-** as it existed for the point in time when the transaction first started.
-** Subsequent changes to the database from other connections are not seen
-** by the reader until a new read transaction is started.
-**
-** The sqlite3_snapshot object records state information about an historical
-** version of the database file so that it is possible to later open a new read
-** transaction that sees that historical version of the database rather than
-** the most recent version.
-*/
-typedef struct sqlite3_snapshot {
- unsigned char hidden[48];
-} sqlite3_snapshot;
-
-/*
-** CAPI3REF: Record A Database Snapshot
+*/
+SQLITE_API int sqlite3_system_errno(sqlite3*);
+
+/*
+** CAPI3REF: Database Snapshot
+** KEYWORDS: {snapshot} {sqlite3_snapshot}
+**
+** An instance of the snapshot object records the state of a [WAL mode]
+** database for some specific point in history.
+**
+** In [WAL mode], multiple [database connections] that are open on the
+** same database file can each be reading a different historical version
+** of the database file. When a [database connection] begins a read
+** transaction, that connection sees an unchanging copy of the database
+** as it existed for the point in time when the transaction first started.
+** Subsequent changes to the database from other connections are not seen
+** by the reader until a new read transaction is started.
+**
+** The sqlite3_snapshot object records state information about an historical
+** version of the database file so that it is possible to later open a new read
+** transaction that sees that historical version of the database rather than
+** the most recent version.
+*/
+typedef struct sqlite3_snapshot {
+ unsigned char hidden[48];
+} sqlite3_snapshot;
+
+/*
+** CAPI3REF: Record A Database Snapshot
** CONSTRUCTOR: sqlite3_snapshot
-**
-** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
-** new [sqlite3_snapshot] object that records the current state of
-** schema S in database connection D. ^On success, the
-** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
-** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
-** If there is not already a read-transaction open on schema S when
+**
+** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
+** new [sqlite3_snapshot] object that records the current state of
+** schema S in database connection D. ^On success, the
+** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
+** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
+** If there is not already a read-transaction open on schema S when
** this function is called, one is opened automatically.
-**
-** The following must be true for this function to succeed. If any of
-** the following statements are false when sqlite3_snapshot_get() is
-** called, SQLITE_ERROR is returned. The final value of *P is undefined
+**
+** The following must be true for this function to succeed. If any of
+** the following statements are false when sqlite3_snapshot_get() is
+** called, SQLITE_ERROR is returned. The final value of *P is undefined
** in this case.
-**
-** <ul>
+**
+** <ul>
** <li> The database handle must not be in [autocommit mode].
-**
-** <li> Schema S of [database connection] D must be a [WAL mode] database.
-**
-** <li> There must not be a write transaction open on schema S of database
-** connection D.
-**
-** <li> One or more transactions must have been written to the current wal
-** file since it was created on disk (by any connection). This means
+**
+** <li> Schema S of [database connection] D must be a [WAL mode] database.
+**
+** <li> There must not be a write transaction open on schema S of database
+** connection D.
+**
+** <li> One or more transactions must have been written to the current wal
+** file since it was created on disk (by any connection). This means
** that a snapshot cannot be taken on a wal mode database with no wal
-** file immediately after it is first opened. At least one transaction
-** must be written to it first.
-** </ul>
-**
-** This function may also return SQLITE_NOMEM. If it is called with the
+** file immediately after it is first opened. At least one transaction
+** must be written to it first.
+** </ul>
+**
+** This function may also return SQLITE_NOMEM. If it is called with the
** database handle in autocommit mode but fails for some other reason,
-** whether or not a read transaction is opened on schema S is undefined.
-**
-** The [sqlite3_snapshot] object returned from a successful call to
-** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
-** to avoid a memory leak.
-**
-** The [sqlite3_snapshot_get()] interface is only available when the
+** whether or not a read transaction is opened on schema S is undefined.
+**
+** The [sqlite3_snapshot] object returned from a successful call to
+** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
+** to avoid a memory leak.
+**
+** The [sqlite3_snapshot_get()] interface is only available when the
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
- sqlite3 *db,
- const char *zSchema,
- sqlite3_snapshot **ppSnapshot
-);
-
-/*
-** CAPI3REF: Start a read transaction on an historical snapshot
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
+ sqlite3 *db,
+ const char *zSchema,
+ sqlite3_snapshot **ppSnapshot
+);
+
+/*
+** CAPI3REF: Start a read transaction on an historical snapshot
** METHOD: sqlite3_snapshot
-**
+**
** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read
** transaction or upgrades an existing one for schema S of
** [database connection] D such that the read transaction refers to
** historical [snapshot] P, rather than the most recent change to the
** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK
** on success or an appropriate [error code] if it fails.
-**
+**
** ^In order to succeed, the database connection must not be in
** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
** is already a read transaction open on schema S, then the database handle
@@ -9846,71 +9846,71 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
** read transaction is undefined. If SQLITE_OK is returned, then the
** read transaction is now open on database snapshot P.
**
-** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
-** database connection D does not know that the database file for
-** schema S is in [WAL mode]. A database connection might not know
-** that the database file is in [WAL mode] if there has been no prior
+** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
+** database connection D does not know that the database file for
+** schema S is in [WAL mode]. A database connection might not know
+** that the database file is in [WAL mode] if there has been no prior
** I/O on that database connection, or if the database entered [WAL mode]
-** after the most recent I/O on the database connection.)^
-** (Hint: Run "[PRAGMA application_id]" against a newly opened
-** database connection in order to make it ready to use snapshots.)
-**
-** The [sqlite3_snapshot_open()] interface is only available when the
+** after the most recent I/O on the database connection.)^
+** (Hint: Run "[PRAGMA application_id]" against a newly opened
+** database connection in order to make it ready to use snapshots.)
+**
+** The [sqlite3_snapshot_open()] interface is only available when the
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
- sqlite3 *db,
- const char *zSchema,
- sqlite3_snapshot *pSnapshot
-);
-
-/*
-** CAPI3REF: Destroy a snapshot
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
+ sqlite3 *db,
+ const char *zSchema,
+ sqlite3_snapshot *pSnapshot
+);
+
+/*
+** CAPI3REF: Destroy a snapshot
** DESTRUCTOR: sqlite3_snapshot
-**
-** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
-** The application must eventually free every [sqlite3_snapshot] object
-** using this routine to avoid a memory leak.
-**
-** The [sqlite3_snapshot_free()] interface is only available when the
+**
+** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
+** The application must eventually free every [sqlite3_snapshot] object
+** using this routine to avoid a memory leak.
+**
+** The [sqlite3_snapshot_free()] interface is only available when the
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
-
-/*
-** CAPI3REF: Compare the ages of two snapshot handles.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
+
+/*
+** CAPI3REF: Compare the ages of two snapshot handles.
** METHOD: sqlite3_snapshot
-**
-** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
+**
+** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
** of two valid snapshot handles.
-**
+**
** If the two snapshot handles are not associated with the same database
** file, the result of the comparison is undefined.
-**
-** Additionally, the result of the comparison is only valid if both of the
-** snapshot handles were obtained by calling sqlite3_snapshot_get() since the
-** last time the wal file was deleted. The wal file is deleted when the
-** database is changed back to rollback mode or when the number of database
+**
+** Additionally, the result of the comparison is only valid if both of the
+** snapshot handles were obtained by calling sqlite3_snapshot_get() since the
+** last time the wal file was deleted. The wal file is deleted when the
+** database is changed back to rollback mode or when the number of database
** clients drops to zero. If either snapshot handle was obtained before the
** wal file was last deleted, the value returned by this function
-** is undefined.
-**
-** Otherwise, this API returns a negative value if P1 refers to an older
-** snapshot than P2, zero if the two handles refer to the same database
-** snapshot, and a positive value if P1 is a newer snapshot than P2.
+** is undefined.
+**
+** Otherwise, this API returns a negative value if P1 refers to an older
+** snapshot than P2, zero if the two handles refer to the same database
+** snapshot, and a positive value if P1 is a newer snapshot than P2.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_SNAPSHOT] option.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
- sqlite3_snapshot *p1,
- sqlite3_snapshot *p2
-);
-
-/*
-** CAPI3REF: Recover snapshots from a wal file
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
+ sqlite3_snapshot *p1,
+ sqlite3_snapshot *p2
+);
+
+/*
+** CAPI3REF: Recover snapshots from a wal file
** METHOD: sqlite3_snapshot
-**
+**
** If a [WAL file] remains on disk after all database connections close
** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
** or because the last process to have the database opened exited without
@@ -9918,21 +9918,21 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
** on that database and [WAL file], the [sqlite3_snapshot_open()] interface
** will only be able to open the last transaction added to the WAL file
** even though the WAL file contains other valid transactions.
-**
+**
** This function attempts to scan the WAL file associated with database zDb
-** of database handle db and make all valid snapshots available to
-** sqlite3_snapshot_open(). It is an error if there is already a read
+** of database handle db and make all valid snapshots available to
+** sqlite3_snapshot_open(). It is an error if there is already a read
** transaction open on the database, or if the database is not a WAL mode
-** database.
-**
-** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+** database.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_SNAPSHOT] option.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
-
-/*
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
+
+/*
** CAPI3REF: Serialize a database
**
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
@@ -10069,9 +10069,9 @@ SQLITE_API int sqlite3_deserialize(
#ifdef __cplusplus
} /* End of the 'extern "C"' block */
#endif
-#endif /* SQLITE3_H */
+#endif /* SQLITE3_H */
-/******** Begin file sqlite3rtree.h *********/
+/******** Begin file sqlite3rtree.h *********/
/*
** 2010 August 30
**
@@ -10111,7 +10111,7 @@ typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
*/
-SQLITE_API int sqlite3_rtree_geometry_callback(
+SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db,
const char *zGeom,
int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
@@ -10137,7 +10137,7 @@ struct sqlite3_rtree_geometry {
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
*/
-SQLITE_API int sqlite3_rtree_query_callback(
+SQLITE_API int sqlite3_rtree_query_callback(
sqlite3 *db,
const char *zQueryFunc,
int (*xQueryFunc)(sqlite3_rtree_query_info*),
@@ -10189,88 +10189,88 @@ struct sqlite3_rtree_query_info {
#endif /* ifndef _SQLITE3RTREE_H_ */
-/******** End of sqlite3rtree.h *********/
-/******** Begin file sqlite3session.h *********/
-
-#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION)
-#define __SQLITESESSION_H_ 1
-
-/*
-** Make sure we can call this stuff from C++.
-*/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
-** CAPI3REF: Session Object Handle
+/******** End of sqlite3rtree.h *********/
+/******** Begin file sqlite3session.h *********/
+
+#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION)
+#define __SQLITESESSION_H_ 1
+
+/*
+** Make sure we can call this stuff from C++.
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+** CAPI3REF: Session Object Handle
**
** An instance of this object is a [session] that can be used to
** record changes to a database.
-*/
-typedef struct sqlite3_session sqlite3_session;
-
-/*
-** CAPI3REF: Changeset Iterator Handle
+*/
+typedef struct sqlite3_session sqlite3_session;
+
+/*
+** CAPI3REF: Changeset Iterator Handle
**
** An instance of this object acts as a cursor for iterating
** over the elements of a [changeset] or [patchset].
-*/
-typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
-
-/*
-** CAPI3REF: Create A New Session Object
+*/
+typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
+
+/*
+** CAPI3REF: Create A New Session Object
** CONSTRUCTOR: sqlite3_session
-**
-** Create a new session object attached to database handle db. If successful,
-** a pointer to the new object is written to *ppSession and SQLITE_OK is
-** returned. If an error occurs, *ppSession is set to NULL and an SQLite
-** error code (e.g. SQLITE_NOMEM) is returned.
-**
-** It is possible to create multiple session objects attached to a single
-** database handle.
-**
-** Session objects created using this function should be deleted using the
-** [sqlite3session_delete()] function before the database handle that they
-** are attached to is itself closed. If the database handle is closed before
-** the session object is deleted, then the results of calling any session
-** module function, including [sqlite3session_delete()] on the session object
-** are undefined.
-**
-** Because the session module uses the [sqlite3_preupdate_hook()] API, it
-** is not possible for an application to register a pre-update hook on a
-** database handle that has one or more session objects attached. Nor is
-** it possible to create a session object attached to a database handle for
+**
+** Create a new session object attached to database handle db. If successful,
+** a pointer to the new object is written to *ppSession and SQLITE_OK is
+** returned. If an error occurs, *ppSession is set to NULL and an SQLite
+** error code (e.g. SQLITE_NOMEM) is returned.
+**
+** It is possible to create multiple session objects attached to a single
+** database handle.
+**
+** Session objects created using this function should be deleted using the
+** [sqlite3session_delete()] function before the database handle that they
+** are attached to is itself closed. If the database handle is closed before
+** the session object is deleted, then the results of calling any session
+** module function, including [sqlite3session_delete()] on the session object
+** are undefined.
+**
+** Because the session module uses the [sqlite3_preupdate_hook()] API, it
+** is not possible for an application to register a pre-update hook on a
+** database handle that has one or more session objects attached. Nor is
+** it possible to create a session object attached to a database handle for
** which a pre-update hook is already defined. The results of attempting
-** either of these things are undefined.
-**
-** The session object will be used to create changesets for tables in
-** database zDb, where zDb is either "main", or "temp", or the name of an
-** attached database. It is not an error if database zDb is not attached
-** to the database when the session object is created.
-*/
-SQLITE_API int sqlite3session_create(
- sqlite3 *db, /* Database handle */
- const char *zDb, /* Name of db (e.g. "main") */
- sqlite3_session **ppSession /* OUT: New session object */
-);
-
-/*
-** CAPI3REF: Delete A Session Object
+** either of these things are undefined.
+**
+** The session object will be used to create changesets for tables in
+** database zDb, where zDb is either "main", or "temp", or the name of an
+** attached database. It is not an error if database zDb is not attached
+** to the database when the session object is created.
+*/
+SQLITE_API int sqlite3session_create(
+ sqlite3 *db, /* Database handle */
+ const char *zDb, /* Name of db (e.g. "main") */
+ sqlite3_session **ppSession /* OUT: New session object */
+);
+
+/*
+** CAPI3REF: Delete A Session Object
** DESTRUCTOR: sqlite3_session
-**
+**
** Delete a session object previously allocated using
-** [sqlite3session_create()]. Once a session object has been deleted, the
-** results of attempting to use pSession with any other session module
-** function are undefined.
-**
-** Session objects must be deleted before the database handle to which they
+** [sqlite3session_create()]. Once a session object has been deleted, the
+** results of attempting to use pSession with any other session module
+** function are undefined.
+**
+** Session objects must be deleted before the database handle to which they
** are attached is closed. Refer to the documentation for
-** [sqlite3session_create()] for details.
-*/
-SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
-
+** [sqlite3session_create()] for details.
+*/
+SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
+
/*
** CAPIREF: Conigure a Session Object
** METHOD: sqlite3_session
@@ -10299,255 +10299,255 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
** the first table has been attached to the session object.
*/
SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
-
-/*
+
+/*
*/
#define SQLITE_SESSION_OBJCONFIG_SIZE 1
/*
-** CAPI3REF: Enable Or Disable A Session Object
+** CAPI3REF: Enable Or Disable A Session Object
** METHOD: sqlite3_session
-**
-** Enable or disable the recording of changes by a session object. When
-** enabled, a session object records changes made to the database. When
-** disabled - it does not. A newly created session object is enabled.
-** Refer to the documentation for [sqlite3session_changeset()] for further
-** details regarding how enabling and disabling a session object affects
-** the eventual changesets.
-**
-** Passing zero to this function disables the session. Passing a value
+**
+** Enable or disable the recording of changes by a session object. When
+** enabled, a session object records changes made to the database. When
+** disabled - it does not. A newly created session object is enabled.
+** Refer to the documentation for [sqlite3session_changeset()] for further
+** details regarding how enabling and disabling a session object affects
+** the eventual changesets.
+**
+** Passing zero to this function disables the session. Passing a value
** greater than zero enables it. Passing a value less than zero is a
-** no-op, and may be used to query the current state of the session.
-**
+** no-op, and may be used to query the current state of the session.
+**
** The return value indicates the final state of the session object: 0 if
-** the session is disabled, or 1 if it is enabled.
-*/
-SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
-
-/*
-** CAPI3REF: Set Or Clear the Indirect Change Flag
+** the session is disabled, or 1 if it is enabled.
+*/
+SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
+
+/*
+** CAPI3REF: Set Or Clear the Indirect Change Flag
** METHOD: sqlite3_session
-**
-** Each change recorded by a session object is marked as either direct or
-** indirect. A change is marked as indirect if either:
-**
-** <ul>
-** <li> The session object "indirect" flag is set when the change is
-** made, or
+**
+** Each change recorded by a session object is marked as either direct or
+** indirect. A change is marked as indirect if either:
+**
+** <ul>
+** <li> The session object "indirect" flag is set when the change is
+** made, or
** <li> The change is made by an SQL trigger or foreign key action
-** instead of directly as a result of a users SQL statement.
-** </ul>
-**
-** If a single row is affected by more than one operation within a session,
-** then the change is considered indirect if all operations meet the criteria
-** for an indirect change above, or direct otherwise.
-**
-** This function is used to set, clear or query the session object indirect
-** flag. If the second argument passed to this function is zero, then the
-** indirect flag is cleared. If it is greater than zero, the indirect flag
-** is set. Passing a value less than zero does not modify the current value
+** instead of directly as a result of a users SQL statement.
+** </ul>
+**
+** If a single row is affected by more than one operation within a session,
+** then the change is considered indirect if all operations meet the criteria
+** for an indirect change above, or direct otherwise.
+**
+** This function is used to set, clear or query the session object indirect
+** flag. If the second argument passed to this function is zero, then the
+** indirect flag is cleared. If it is greater than zero, the indirect flag
+** is set. Passing a value less than zero does not modify the current value
** of the indirect flag, and may be used to query the current state of the
-** indirect flag for the specified session object.
-**
+** indirect flag for the specified session object.
+**
** The return value indicates the final state of the indirect flag: 0 if
-** it is clear, or 1 if it is set.
-*/
-SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
-
-/*
-** CAPI3REF: Attach A Table To A Session Object
+** it is clear, or 1 if it is set.
+*/
+SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
+
+/*
+** CAPI3REF: Attach A Table To A Session Object
** METHOD: sqlite3_session
-**
-** If argument zTab is not NULL, then it is the name of a table to attach
+**
+** If argument zTab is not NULL, then it is the name of a table to attach
** to the session object passed as the first argument. All subsequent changes
** made to the table while the session object is enabled will be recorded. See
-** documentation for [sqlite3session_changeset()] for further details.
-**
-** Or, if argument zTab is NULL, then changes are recorded for all tables
+** documentation for [sqlite3session_changeset()] for further details.
+**
+** Or, if argument zTab is NULL, then changes are recorded for all tables
** in the database. If additional tables are added to the database (by
** executing "CREATE TABLE" statements) after this call is made, changes for
-** the new tables are also recorded.
-**
-** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
+** the new tables are also recorded.
+**
+** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
** defined as part of their CREATE TABLE statement. It does not matter if the
-** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY
-** KEY may consist of a single column, or may be a composite key.
-**
-** It is not an error if the named table does not exist in the database. Nor
-** is it an error if the named table does not have a PRIMARY KEY. However,
-** no changes will be recorded in either of these scenarios.
-**
-** Changes are not recorded for individual rows that have NULL values stored
-** in one or more of their PRIMARY KEY columns.
-**
+** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY
+** KEY may consist of a single column, or may be a composite key.
+**
+** It is not an error if the named table does not exist in the database. Nor
+** is it an error if the named table does not have a PRIMARY KEY. However,
+** no changes will be recorded in either of these scenarios.
+**
+** Changes are not recorded for individual rows that have NULL values stored
+** in one or more of their PRIMARY KEY columns.
+**
** SQLITE_OK is returned if the call completes without error. Or, if an error
-** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
-**
-** <h3>Special sqlite_stat1 Handling</h3>
-**
+** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
+**
+** <h3>Special sqlite_stat1 Handling</h3>
+**
** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to
-** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
-** <pre>
+** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
+** <pre>
** &nbsp; CREATE TABLE sqlite_stat1(tbl,idx,stat)
-** </pre>
-**
+** </pre>
+**
** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are
** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes
-** are recorded for rows for which (idx IS NULL) is true. However, for such
-** rows a zero-length blob (SQL value X'') is stored in the changeset or
-** patchset instead of a NULL value. This allows such changesets to be
-** manipulated by legacy implementations of sqlite3changeset_invert(),
-** concat() and similar.
-**
+** are recorded for rows for which (idx IS NULL) is true. However, for such
+** rows a zero-length blob (SQL value X'') is stored in the changeset or
+** patchset instead of a NULL value. This allows such changesets to be
+** manipulated by legacy implementations of sqlite3changeset_invert(),
+** concat() and similar.
+**
** The sqlite3changeset_apply() function automatically converts the
-** zero-length blob back to a NULL value when updating the sqlite_stat1
-** table. However, if the application calls sqlite3changeset_new(),
+** zero-length blob back to a NULL value when updating the sqlite_stat1
+** table. However, if the application calls sqlite3changeset_new(),
** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset
-** iterator directly (including on a changeset iterator passed to a
-** conflict-handler callback) then the X'' value is returned. The application
-** must translate X'' to NULL itself if required.
-**
-** Legacy (older than 3.22.0) versions of the sessions module cannot capture
-** changes made to the sqlite_stat1 table. Legacy versions of the
-** sqlite3changeset_apply() function silently ignore any modifications to the
-** sqlite_stat1 table that are part of a changeset or patchset.
-*/
-SQLITE_API int sqlite3session_attach(
- sqlite3_session *pSession, /* Session object */
- const char *zTab /* Table name */
-);
-
-/*
-** CAPI3REF: Set a table filter on a Session Object.
+** iterator directly (including on a changeset iterator passed to a
+** conflict-handler callback) then the X'' value is returned. The application
+** must translate X'' to NULL itself if required.
+**
+** Legacy (older than 3.22.0) versions of the sessions module cannot capture
+** changes made to the sqlite_stat1 table. Legacy versions of the
+** sqlite3changeset_apply() function silently ignore any modifications to the
+** sqlite_stat1 table that are part of a changeset or patchset.
+*/
+SQLITE_API int sqlite3session_attach(
+ sqlite3_session *pSession, /* Session object */
+ const char *zTab /* Table name */
+);
+
+/*
+** CAPI3REF: Set a table filter on a Session Object.
** METHOD: sqlite3_session
-**
+**
** The second argument (xFilter) is the "filter callback". For changes to rows
-** in tables that are not attached to the Session object, the filter is called
+** in tables that are not attached to the Session object, the filter is called
** to determine whether changes to the table's rows should be tracked or not.
** If xFilter returns 0, changes are not tracked. Note that once a table is
-** attached, xFilter will not be called again.
-*/
-SQLITE_API void sqlite3session_table_filter(
- sqlite3_session *pSession, /* Session object */
- int(*xFilter)(
- void *pCtx, /* Copy of third arg to _filter_table() */
- const char *zTab /* Table name */
- ),
- void *pCtx /* First argument passed to xFilter */
-);
-
-/*
-** CAPI3REF: Generate A Changeset From A Session Object
+** attached, xFilter will not be called again.
+*/
+SQLITE_API void sqlite3session_table_filter(
+ sqlite3_session *pSession, /* Session object */
+ int(*xFilter)(
+ void *pCtx, /* Copy of third arg to _filter_table() */
+ const char *zTab /* Table name */
+ ),
+ void *pCtx /* First argument passed to xFilter */
+);
+
+/*
+** CAPI3REF: Generate A Changeset From A Session Object
** METHOD: sqlite3_session
-**
+**
** Obtain a changeset containing changes to the tables attached to the
** session object passed as the first argument. If successful,
** set *ppChangeset to point to a buffer containing the changeset
-** and *pnChangeset to the size of the changeset in bytes before returning
-** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to
-** zero and return an SQLite error code.
-**
-** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes,
-** each representing a change to a single row of an attached table. An INSERT
-** change contains the values of each field of a new database row. A DELETE
-** contains the original values of each field of a deleted database row. An
-** UPDATE change contains the original values of each field of an updated
-** database row along with the updated values for each updated non-primary-key
-** column. It is not possible for an UPDATE change to represent a change that
-** modifies the values of primary key columns. If such a change is made, it
-** is represented in a changeset as a DELETE followed by an INSERT.
-**
+** and *pnChangeset to the size of the changeset in bytes before returning
+** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to
+** zero and return an SQLite error code.
+**
+** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes,
+** each representing a change to a single row of an attached table. An INSERT
+** change contains the values of each field of a new database row. A DELETE
+** contains the original values of each field of a deleted database row. An
+** UPDATE change contains the original values of each field of an updated
+** database row along with the updated values for each updated non-primary-key
+** column. It is not possible for an UPDATE change to represent a change that
+** modifies the values of primary key columns. If such a change is made, it
+** is represented in a changeset as a DELETE followed by an INSERT.
+**
** Changes are not recorded for rows that have NULL values stored in one or
-** more of their PRIMARY KEY columns. If such a row is inserted or deleted,
-** no corresponding change is present in the changesets returned by this
-** function. If an existing row with one or more NULL values stored in
-** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL,
-** only an INSERT is appears in the changeset. Similarly, if an existing row
-** with non-NULL PRIMARY KEY values is updated so that one or more of its
-** PRIMARY KEY columns are set to NULL, the resulting changeset contains a
-** DELETE change only.
-**
-** The contents of a changeset may be traversed using an iterator created
-** using the [sqlite3changeset_start()] API. A changeset may be applied to
-** a database with a compatible schema using the [sqlite3changeset_apply()]
-** API.
-**
-** Within a changeset generated by this function, all changes related to a
-** single table are grouped together. In other words, when iterating through
-** a changeset or when applying a changeset to a database, all changes related
-** to a single table are processed before moving on to the next table. Tables
-** are sorted in the same order in which they were attached (or auto-attached)
-** to the sqlite3_session object. The order in which the changes related to
-** a single table are stored is undefined.
-**
-** Following a successful call to this function, it is the responsibility of
-** the caller to eventually free the buffer that *ppChangeset points to using
-** [sqlite3_free()].
-**
-** <h3>Changeset Generation</h3>
-**
-** Once a table has been attached to a session object, the session object
-** records the primary key values of all new rows inserted into the table.
-** It also records the original primary key and other column values of any
-** deleted or updated rows. For each unique primary key value, data is only
-** recorded once - the first time a row with said primary key is inserted,
-** updated or deleted in the lifetime of the session.
-**
-** There is one exception to the previous paragraph: when a row is inserted,
-** updated or deleted, if one or more of its primary key columns contain a
-** NULL value, no record of the change is made.
-**
-** The session object therefore accumulates two types of records - those
-** that consist of primary key values only (created when the user inserts
-** a new record) and those that consist of the primary key values and the
-** original values of other table columns (created when the users deletes
-** or updates a record).
-**
-** When this function is called, the requested changeset is created using
-** both the accumulated records and the current contents of the database
-** file. Specifically:
-**
-** <ul>
-** <li> For each record generated by an insert, the database is queried
-** for a row with a matching primary key. If one is found, an INSERT
+** more of their PRIMARY KEY columns. If such a row is inserted or deleted,
+** no corresponding change is present in the changesets returned by this
+** function. If an existing row with one or more NULL values stored in
+** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL,
+** only an INSERT is appears in the changeset. Similarly, if an existing row
+** with non-NULL PRIMARY KEY values is updated so that one or more of its
+** PRIMARY KEY columns are set to NULL, the resulting changeset contains a
+** DELETE change only.
+**
+** The contents of a changeset may be traversed using an iterator created
+** using the [sqlite3changeset_start()] API. A changeset may be applied to
+** a database with a compatible schema using the [sqlite3changeset_apply()]
+** API.
+**
+** Within a changeset generated by this function, all changes related to a
+** single table are grouped together. In other words, when iterating through
+** a changeset or when applying a changeset to a database, all changes related
+** to a single table are processed before moving on to the next table. Tables
+** are sorted in the same order in which they were attached (or auto-attached)
+** to the sqlite3_session object. The order in which the changes related to
+** a single table are stored is undefined.
+**
+** Following a successful call to this function, it is the responsibility of
+** the caller to eventually free the buffer that *ppChangeset points to using
+** [sqlite3_free()].
+**
+** <h3>Changeset Generation</h3>
+**
+** Once a table has been attached to a session object, the session object
+** records the primary key values of all new rows inserted into the table.
+** It also records the original primary key and other column values of any
+** deleted or updated rows. For each unique primary key value, data is only
+** recorded once - the first time a row with said primary key is inserted,
+** updated or deleted in the lifetime of the session.
+**
+** There is one exception to the previous paragraph: when a row is inserted,
+** updated or deleted, if one or more of its primary key columns contain a
+** NULL value, no record of the change is made.
+**
+** The session object therefore accumulates two types of records - those
+** that consist of primary key values only (created when the user inserts
+** a new record) and those that consist of the primary key values and the
+** original values of other table columns (created when the users deletes
+** or updates a record).
+**
+** When this function is called, the requested changeset is created using
+** both the accumulated records and the current contents of the database
+** file. Specifically:
+**
+** <ul>
+** <li> For each record generated by an insert, the database is queried
+** for a row with a matching primary key. If one is found, an INSERT
** change is added to the changeset. If no such row is found, no change
-** is added to the changeset.
-**
+** is added to the changeset.
+**
** <li> For each record generated by an update or delete, the database is
-** queried for a row with a matching primary key. If such a row is
-** found and one or more of the non-primary key fields have been
+** queried for a row with a matching primary key. If such a row is
+** found and one or more of the non-primary key fields have been
** modified from their original values, an UPDATE change is added to
** the changeset. Or, if no such row is found in the table, a DELETE
-** change is added to the changeset. If there is a row with a matching
-** primary key in the database, but all fields contain their original
-** values, no change is added to the changeset.
-** </ul>
-**
-** This means, amongst other things, that if a row is inserted and then later
-** deleted while a session object is active, neither the insert nor the delete
+** change is added to the changeset. If there is a row with a matching
+** primary key in the database, but all fields contain their original
+** values, no change is added to the changeset.
+** </ul>
+**
+** This means, amongst other things, that if a row is inserted and then later
+** deleted while a session object is active, neither the insert nor the delete
** will be present in the changeset. Or if a row is deleted and then later a
-** row with the same primary key values inserted while a session object is
-** active, the resulting changeset will contain an UPDATE change instead of
-** a DELETE and an INSERT.
-**
-** When a session object is disabled (see the [sqlite3session_enable()] API),
-** it does not accumulate records when rows are inserted, updated or deleted.
-** This may appear to have some counter-intuitive effects if a single row
-** is written to more than once during a session. For example, if a row
+** row with the same primary key values inserted while a session object is
+** active, the resulting changeset will contain an UPDATE change instead of
+** a DELETE and an INSERT.
+**
+** When a session object is disabled (see the [sqlite3session_enable()] API),
+** it does not accumulate records when rows are inserted, updated or deleted.
+** This may appear to have some counter-intuitive effects if a single row
+** is written to more than once during a session. For example, if a row
** is inserted while a session object is enabled, then later deleted while
-** the same session object is disabled, no INSERT record will appear in the
-** changeset, even though the delete took place while the session was disabled.
+** the same session object is disabled, no INSERT record will appear in the
+** changeset, even though the delete took place while the session was disabled.
** Or, if one field of a row is updated while a session is disabled, and
-** another field of the same row is updated while the session is enabled, the
-** resulting changeset will contain an UPDATE change that updates both fields.
-*/
-SQLITE_API int sqlite3session_changeset(
- sqlite3_session *pSession, /* Session object */
- int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
- void **ppChangeset /* OUT: Buffer containing changeset */
-);
-
-/*
+** another field of the same row is updated while the session is enabled, the
+** resulting changeset will contain an UPDATE change that updates both fields.
+*/
+SQLITE_API int sqlite3session_changeset(
+ sqlite3_session *pSession, /* Session object */
+ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
+ void **ppChangeset /* OUT: Buffer containing changeset */
+);
+
+/*
** CAPI3REF: Return An Upper-limit For The Size Of The Changeset
** METHOD: sqlite3_session
**
@@ -10566,121 +10566,121 @@ SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession
/*
** CAPI3REF: Load The Difference Between Tables Into A Session
** METHOD: sqlite3_session
-**
-** If it is not already attached to the session object passed as the first
-** argument, this function attaches table zTbl in the same manner as the
-** [sqlite3session_attach()] function. If zTbl does not exist, or if it
-** does not have a primary key, this function is a no-op (but does not return
-** an error).
-**
-** Argument zFromDb must be the name of a database ("main", "temp" etc.)
+**
+** If it is not already attached to the session object passed as the first
+** argument, this function attaches table zTbl in the same manner as the
+** [sqlite3session_attach()] function. If zTbl does not exist, or if it
+** does not have a primary key, this function is a no-op (but does not return
+** an error).
+**
+** Argument zFromDb must be the name of a database ("main", "temp" etc.)
** attached to the same database handle as the session object that contains
-** a table compatible with the table attached to the session by this function.
-** A table is considered compatible if it:
-**
-** <ul>
-** <li> Has the same name,
-** <li> Has the same set of columns declared in the same order, and
-** <li> Has the same PRIMARY KEY definition.
-** </ul>
-**
-** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables
-** are compatible but do not have any PRIMARY KEY columns, it is not an error
-** but no changes are added to the session object. As with other session
-** APIs, tables without PRIMARY KEYs are simply ignored.
-**
-** This function adds a set of changes to the session object that could be
+** a table compatible with the table attached to the session by this function.
+** A table is considered compatible if it:
+**
+** <ul>
+** <li> Has the same name,
+** <li> Has the same set of columns declared in the same order, and
+** <li> Has the same PRIMARY KEY definition.
+** </ul>
+**
+** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables
+** are compatible but do not have any PRIMARY KEY columns, it is not an error
+** but no changes are added to the session object. As with other session
+** APIs, tables without PRIMARY KEYs are simply ignored.
+**
+** This function adds a set of changes to the session object that could be
** used to update the table in database zFrom (call this the "from-table")
** so that its content is the same as the table attached to the session
-** object (call this the "to-table"). Specifically:
-**
-** <ul>
+** object (call this the "to-table"). Specifically:
+**
+** <ul>
** <li> For each row (primary key) that exists in the to-table but not in
-** the from-table, an INSERT record is added to the session object.
-**
+** the from-table, an INSERT record is added to the session object.
+**
** <li> For each row (primary key) that exists in the to-table but not in
-** the from-table, a DELETE record is added to the session object.
-**
+** the from-table, a DELETE record is added to the session object.
+**
** <li> For each row (primary key) that exists in both tables, but features
-** different non-PK values in each, an UPDATE record is added to the
+** different non-PK values in each, an UPDATE record is added to the
** session.
-** </ul>
-**
-** To clarify, if this function is called and then a changeset constructed
+** </ul>
+**
+** To clarify, if this function is called and then a changeset constructed
** using [sqlite3session_changeset()], then after applying that changeset to
** database zFrom the contents of the two compatible tables would be
-** identical.
-**
-** It an error if database zFrom does not exist or does not contain the
-** required compatible table.
-**
+** identical.
+**
+** It an error if database zFrom does not exist or does not contain the
+** required compatible table.
+**
** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite
-** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
+** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
** may be set to point to a buffer containing an English language error
-** message. It is the responsibility of the caller to free this buffer using
-** sqlite3_free().
-*/
-SQLITE_API int sqlite3session_diff(
- sqlite3_session *pSession,
- const char *zFromDb,
- const char *zTbl,
- char **pzErrMsg
-);
-
-
-/*
-** CAPI3REF: Generate A Patchset From A Session Object
+** message. It is the responsibility of the caller to free this buffer using
+** sqlite3_free().
+*/
+SQLITE_API int sqlite3session_diff(
+ sqlite3_session *pSession,
+ const char *zFromDb,
+ const char *zTbl,
+ char **pzErrMsg
+);
+
+
+/*
+** CAPI3REF: Generate A Patchset From A Session Object
** METHOD: sqlite3_session
-**
-** The differences between a patchset and a changeset are that:
-**
-** <ul>
+**
+** The differences between a patchset and a changeset are that:
+**
+** <ul>
** <li> DELETE records consist of the primary key fields only. The
-** original values of other fields are omitted.
+** original values of other fields are omitted.
** <li> The original values of any modified fields are omitted from
-** UPDATE records.
-** </ul>
-**
+** UPDATE records.
+** </ul>
+**
** A patchset blob may be used with up to date versions of all
** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(),
-** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly,
-** attempting to use a patchset blob with old versions of the
+** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly,
+** attempting to use a patchset blob with old versions of the
** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error.
-**
+**
** Because the non-primary key "old.*" fields are omitted, no
-** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset
-** is passed to the sqlite3changeset_apply() API. Other conflict types work
-** in the same way as for changesets.
-**
-** Changes within a patchset are ordered in the same way as for changesets
-** generated by the sqlite3session_changeset() function (i.e. all changes for
-** a single table are grouped together, tables appear in the order in which
-** they were attached to the session object).
-*/
-SQLITE_API int sqlite3session_patchset(
- sqlite3_session *pSession, /* Session object */
- int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */
- void **ppPatchset /* OUT: Buffer containing patchset */
-);
-
-/*
-** CAPI3REF: Test if a changeset has recorded any changes.
-**
+** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset
+** is passed to the sqlite3changeset_apply() API. Other conflict types work
+** in the same way as for changesets.
+**
+** Changes within a patchset are ordered in the same way as for changesets
+** generated by the sqlite3session_changeset() function (i.e. all changes for
+** a single table are grouped together, tables appear in the order in which
+** they were attached to the session object).
+*/
+SQLITE_API int sqlite3session_patchset(
+ sqlite3_session *pSession, /* Session object */
+ int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */
+ void **ppPatchset /* OUT: Buffer containing patchset */
+);
+
+/*
+** CAPI3REF: Test if a changeset has recorded any changes.
+**
** Return non-zero if no changes to attached tables have been recorded by
** the session object passed as the first argument. Otherwise, if one or
-** more changes have been recorded, return zero.
-**
-** Even if this function returns zero, it is possible that calling
-** [sqlite3session_changeset()] on the session handle may still return a
+** more changes have been recorded, return zero.
+**
+** Even if this function returns zero, it is possible that calling
+** [sqlite3session_changeset()] on the session handle may still return a
** changeset that contains no changes. This can happen when a row in
** an attached table is modified and then later on the original values
-** are restored. However, if this function returns non-zero, then it is
+** are restored. However, if this function returns non-zero, then it is
** guaranteed that a call to sqlite3session_changeset() will return a
-** changeset containing zero changes.
-*/
-SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
-
-/*
+** changeset containing zero changes.
+*/
+SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
+
+/*
** CAPI3REF: Query for the amount of heap memory used by a session object.
**
** This API returns the total amount of heap memory in bytes currently
@@ -10691,36 +10691,36 @@ SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession);
/*
** CAPI3REF: Create An Iterator To Traverse A Changeset
** CONSTRUCTOR: sqlite3_changeset_iter
-**
-** Create an iterator used to iterate through the contents of a changeset.
-** If successful, *pp is set to point to the iterator handle and SQLITE_OK
-** is returned. Otherwise, if an error occurs, *pp is set to zero and an
-** SQLite error code is returned.
-**
+**
+** Create an iterator used to iterate through the contents of a changeset.
+** If successful, *pp is set to point to the iterator handle and SQLITE_OK
+** is returned. Otherwise, if an error occurs, *pp is set to zero and an
+** SQLite error code is returned.
+**
** The following functions can be used to advance and query a changeset
-** iterator created by this function:
-**
-** <ul>
-** <li> [sqlite3changeset_next()]
-** <li> [sqlite3changeset_op()]
-** <li> [sqlite3changeset_new()]
-** <li> [sqlite3changeset_old()]
-** </ul>
-**
-** It is the responsibility of the caller to eventually destroy the iterator
-** by passing it to [sqlite3changeset_finalize()]. The buffer containing the
-** changeset (pChangeset) must remain valid until after the iterator is
-** destroyed.
-**
-** Assuming the changeset blob was created by one of the
-** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
+** iterator created by this function:
+**
+** <ul>
+** <li> [sqlite3changeset_next()]
+** <li> [sqlite3changeset_op()]
+** <li> [sqlite3changeset_new()]
+** <li> [sqlite3changeset_old()]
+** </ul>
+**
+** It is the responsibility of the caller to eventually destroy the iterator
+** by passing it to [sqlite3changeset_finalize()]. The buffer containing the
+** changeset (pChangeset) must remain valid until after the iterator is
+** destroyed.
+**
+** Assuming the changeset blob was created by one of the
+** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
** [sqlite3changeset_invert()] functions, all changes within the changeset
** that apply to a single table are grouped together. This means that when
** an application iterates through a changeset using an iterator created by
** this function, all changes that relate to a single table are visited
** consecutively. There is no chance that the iterator will visit a change
** the applies to table X, then one for table Y, and then later on visit
-** another change for table X.
+** another change for table X.
**
** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
** may be modified by passing a combination of
@@ -10728,19 +10728,19 @@ SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession);
**
** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
** and therefore subject to change.
-*/
-SQLITE_API int sqlite3changeset_start(
- sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
- int nChangeset, /* Size of changeset blob in bytes */
- void *pChangeset /* Pointer to blob containing changeset */
-);
+*/
+SQLITE_API int sqlite3changeset_start(
+ sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
+ int nChangeset, /* Size of changeset blob in bytes */
+ void *pChangeset /* Pointer to blob containing changeset */
+);
SQLITE_API int sqlite3changeset_start_v2(
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
int nChangeset, /* Size of changeset blob in bytes */
void *pChangeset, /* Pointer to blob containing changeset */
int flags /* SESSION_CHANGESETSTART_* flags */
);
-
+
/*
** CAPI3REF: Flags for sqlite3changeset_start_v2
**
@@ -10753,43 +10753,43 @@ SQLITE_API int sqlite3changeset_start_v2(
** It is an error to specify this flag with a patchset.
*/
#define SQLITE_CHANGESETSTART_INVERT 0x0002
-
-/*
-** CAPI3REF: Advance A Changeset Iterator
+
+/*
+** CAPI3REF: Advance A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
+**
** This function may only be used with iterators created by the function
-** [sqlite3changeset_start()]. If it is called on an iterator passed to
-** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
-** is returned and the call has no effect.
-**
-** Immediately after an iterator is created by sqlite3changeset_start(), it
-** does not point to any change in the changeset. Assuming the changeset
-** is not empty, the first call to this function advances the iterator to
-** point to the first change in the changeset. Each subsequent call advances
-** the iterator to point to the next change in the changeset (if any). If
-** no error occurs and the iterator points to a valid change after a call
+** [sqlite3changeset_start()]. If it is called on an iterator passed to
+** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
+** is returned and the call has no effect.
+**
+** Immediately after an iterator is created by sqlite3changeset_start(), it
+** does not point to any change in the changeset. Assuming the changeset
+** is not empty, the first call to this function advances the iterator to
+** point to the first change in the changeset. Each subsequent call advances
+** the iterator to point to the next change in the changeset (if any). If
+** no error occurs and the iterator points to a valid change after a call
** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned.
-** Otherwise, if all changes in the changeset have already been visited,
-** SQLITE_DONE is returned.
-**
+** Otherwise, if all changes in the changeset have already been visited,
+** SQLITE_DONE is returned.
+**
** If an error occurs, an SQLite error code is returned. Possible error
** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or
-** SQLITE_NOMEM.
-*/
-SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
-
-/*
-** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
+** SQLITE_NOMEM.
+*/
+SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
+
+/*
+** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
-** The pIter argument passed to this function may either be an iterator
-** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
-** created by [sqlite3changeset_start()]. In the latter case, the most recent
-** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this
-** is not the case, this function returns [SQLITE_MISUSE].
-**
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this
+** is not the case, this function returns [SQLITE_MISUSE].
+**
** Arguments pOp, pnCol and pzTab may not be NULL. Upon return, three
** outputs are set through these pointers:
**
@@ -10804,566 +10804,566 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
** or until the conflict-handler function returns.
**
** If pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
-** is an indirect change, or false (0) otherwise. See the documentation for
-** [sqlite3session_indirect()] for a description of direct and indirect
+** is an indirect change, or false (0) otherwise. See the documentation for
+** [sqlite3session_indirect()] for a description of direct and indirect
** changes.
-**
-** If no error occurs, SQLITE_OK is returned. If an error does occur, an
-** SQLite error code is returned. The values of the output variables may not
-** be trusted in this case.
-*/
-SQLITE_API int sqlite3changeset_op(
- sqlite3_changeset_iter *pIter, /* Iterator object */
- const char **pzTab, /* OUT: Pointer to table name */
- int *pnCol, /* OUT: Number of columns in table */
- int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */
- int *pbIndirect /* OUT: True for an 'indirect' change */
-);
-
-/*
-** CAPI3REF: Obtain The Primary Key Definition Of A Table
+**
+** If no error occurs, SQLITE_OK is returned. If an error does occur, an
+** SQLite error code is returned. The values of the output variables may not
+** be trusted in this case.
+*/
+SQLITE_API int sqlite3changeset_op(
+ sqlite3_changeset_iter *pIter, /* Iterator object */
+ const char **pzTab, /* OUT: Pointer to table name */
+ int *pnCol, /* OUT: Number of columns in table */
+ int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */
+ int *pbIndirect /* OUT: True for an 'indirect' change */
+);
+
+/*
+** CAPI3REF: Obtain The Primary Key Definition Of A Table
** METHOD: sqlite3_changeset_iter
-**
-** For each modified table, a changeset includes the following:
-**
-** <ul>
-** <li> The number of columns in the table, and
-** <li> Which of those columns make up the tables PRIMARY KEY.
-** </ul>
-**
-** This function is used to find which columns comprise the PRIMARY KEY of
-** the table modified by the change that iterator pIter currently points to.
-** If successful, *pabPK is set to point to an array of nCol entries, where
-** nCol is the number of columns in the table. Elements of *pabPK are set to
-** 0x01 if the corresponding column is part of the tables primary key, or
-** 0x00 if it is not.
-**
-** If argument pnCol is not NULL, then *pnCol is set to the number of columns
-** in the table.
-**
-** If this function is called when the iterator does not point to a valid
-** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
-** SQLITE_OK is returned and the output variables populated as described
-** above.
-*/
-SQLITE_API int sqlite3changeset_pk(
- sqlite3_changeset_iter *pIter, /* Iterator object */
- unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
- int *pnCol /* OUT: Number of entries in output array */
-);
-
-/*
-** CAPI3REF: Obtain old.* Values From A Changeset Iterator
+**
+** For each modified table, a changeset includes the following:
+**
+** <ul>
+** <li> The number of columns in the table, and
+** <li> Which of those columns make up the tables PRIMARY KEY.
+** </ul>
+**
+** This function is used to find which columns comprise the PRIMARY KEY of
+** the table modified by the change that iterator pIter currently points to.
+** If successful, *pabPK is set to point to an array of nCol entries, where
+** nCol is the number of columns in the table. Elements of *pabPK are set to
+** 0x01 if the corresponding column is part of the tables primary key, or
+** 0x00 if it is not.
+**
+** If argument pnCol is not NULL, then *pnCol is set to the number of columns
+** in the table.
+**
+** If this function is called when the iterator does not point to a valid
+** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
+** SQLITE_OK is returned and the output variables populated as described
+** above.
+*/
+SQLITE_API int sqlite3changeset_pk(
+ sqlite3_changeset_iter *pIter, /* Iterator object */
+ unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
+ int *pnCol /* OUT: Number of entries in output array */
+);
+
+/*
+** CAPI3REF: Obtain old.* Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
-** The pIter argument passed to this function may either be an iterator
-** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
-** created by [sqlite3changeset_start()]. In the latter case, the most recent
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
** call to [sqlite3changeset_next()] must have returned SQLITE_ROW.
-** Furthermore, it may only be called if the type of change that the iterator
-** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise,
-** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
-**
-** Argument iVal must be greater than or equal to 0, and less than the number
-** of columns in the table affected by the current change. Otherwise,
-** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
-**
-** If successful, this function sets *ppValue to point to a protected
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise,
+** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
** sqlite3_value object containing the iVal'th value from the vector of
-** original row values stored as part of the UPDATE or DELETE change and
+** original row values stored as part of the UPDATE or DELETE change and
** returns SQLITE_OK. The name of the function comes from the fact that this
-** is similar to the "old.*" columns available to update or delete triggers.
-**
-** If some other error occurs (e.g. an OOM condition), an SQLite error code
-** is returned and *ppValue is set to NULL.
-*/
-SQLITE_API int sqlite3changeset_old(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int iVal, /* Column number */
- sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
-);
-
-/*
-** CAPI3REF: Obtain new.* Values From A Changeset Iterator
+** is similar to the "old.*" columns available to update or delete triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+SQLITE_API int sqlite3changeset_old(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int iVal, /* Column number */
+ sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
+);
+
+/*
+** CAPI3REF: Obtain new.* Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
-** The pIter argument passed to this function may either be an iterator
-** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
-** created by [sqlite3changeset_start()]. In the latter case, the most recent
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
** call to [sqlite3changeset_next()] must have returned SQLITE_ROW.
-** Furthermore, it may only be called if the type of change that the iterator
-** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise,
-** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
-**
-** Argument iVal must be greater than or equal to 0, and less than the number
-** of columns in the table affected by the current change. Otherwise,
-** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
-**
-** If successful, this function sets *ppValue to point to a protected
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise,
+** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
** sqlite3_value object containing the iVal'th value from the vector of
-** new row values stored as part of the UPDATE or INSERT change and
-** returns SQLITE_OK. If the change is an UPDATE and does not include
+** new row values stored as part of the UPDATE or INSERT change and
+** returns SQLITE_OK. If the change is an UPDATE and does not include
** a new value for the requested column, *ppValue is set to NULL and
** SQLITE_OK returned. The name of the function comes from the fact that
** this is similar to the "new.*" columns available to update or delete
-** triggers.
-**
-** If some other error occurs (e.g. an OOM condition), an SQLite error code
-** is returned and *ppValue is set to NULL.
-*/
-SQLITE_API int sqlite3changeset_new(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int iVal, /* Column number */
- sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
-);
-
-/*
-** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
+** triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+SQLITE_API int sqlite3changeset_new(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int iVal, /* Column number */
+ sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
+);
+
+/*
+** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
-** This function should only be used with iterator objects passed to a
-** conflict-handler callback by [sqlite3changeset_apply()] with either
-** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function
-** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue
-** is set to NULL.
-**
-** Argument iVal must be greater than or equal to 0, and less than the number
-** of columns in the table affected by the current change. Otherwise,
-** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
-**
-** If successful, this function sets *ppValue to point to a protected
+**
+** This function should only be used with iterator objects passed to a
+** conflict-handler callback by [sqlite3changeset_apply()] with either
+** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function
+** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue
+** is set to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
** sqlite3_value object containing the iVal'th value from the
-** "conflicting row" associated with the current conflict-handler callback
-** and returns SQLITE_OK.
-**
-** If some other error occurs (e.g. an OOM condition), an SQLite error code
-** is returned and *ppValue is set to NULL.
-*/
-SQLITE_API int sqlite3changeset_conflict(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int iVal, /* Column number */
- sqlite3_value **ppValue /* OUT: Value from conflicting row */
-);
-
-/*
-** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
+** "conflicting row" associated with the current conflict-handler callback
+** and returns SQLITE_OK.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+SQLITE_API int sqlite3changeset_conflict(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int iVal, /* Column number */
+ sqlite3_value **ppValue /* OUT: Value from conflicting row */
+);
+
+/*
+** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
** METHOD: sqlite3_changeset_iter
-**
-** This function may only be called with an iterator passed to an
-** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
-** it sets the output variable to the total number of known foreign key
-** violations in the destination database and returns SQLITE_OK.
-**
-** In all other cases this function returns SQLITE_MISUSE.
-*/
-SQLITE_API int sqlite3changeset_fk_conflicts(
- sqlite3_changeset_iter *pIter, /* Changeset iterator */
- int *pnOut /* OUT: Number of FK violations */
-);
-
-
-/*
-** CAPI3REF: Finalize A Changeset Iterator
+**
+** This function may only be called with an iterator passed to an
+** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
+** it sets the output variable to the total number of known foreign key
+** violations in the destination database and returns SQLITE_OK.
+**
+** In all other cases this function returns SQLITE_MISUSE.
+*/
+SQLITE_API int sqlite3changeset_fk_conflicts(
+ sqlite3_changeset_iter *pIter, /* Changeset iterator */
+ int *pnOut /* OUT: Number of FK violations */
+);
+
+
+/*
+** CAPI3REF: Finalize A Changeset Iterator
** METHOD: sqlite3_changeset_iter
-**
-** This function is used to finalize an iterator allocated with
-** [sqlite3changeset_start()].
-**
-** This function should only be called on iterators created using the
-** [sqlite3changeset_start()] function. If an application calls this
-** function with an iterator passed to a conflict-handler by
-** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the
-** call has no effect.
-**
-** If an error was encountered within a call to an sqlite3changeset_xxx()
+**
+** This function is used to finalize an iterator allocated with
+** [sqlite3changeset_start()].
+**
+** This function should only be called on iterators created using the
+** [sqlite3changeset_start()] function. If an application calls this
+** function with an iterator passed to a conflict-handler by
+** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the
+** call has no effect.
+**
+** If an error was encountered within a call to an sqlite3changeset_xxx()
** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an
-** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding
-** to that error is returned by this function. Otherwise, SQLITE_OK is
-** returned. This is to allow the following pattern (pseudo-code):
-**
+** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding
+** to that error is returned by this function. Otherwise, SQLITE_OK is
+** returned. This is to allow the following pattern (pseudo-code):
+**
** <pre>
-** sqlite3changeset_start();
-** while( SQLITE_ROW==sqlite3changeset_next() ){
-** // Do something with change.
-** }
-** rc = sqlite3changeset_finalize();
-** if( rc!=SQLITE_OK ){
+** sqlite3changeset_start();
+** while( SQLITE_ROW==sqlite3changeset_next() ){
+** // Do something with change.
+** }
+** rc = sqlite3changeset_finalize();
+** if( rc!=SQLITE_OK ){
** // An error has occurred
-** }
+** }
** </pre>
-*/
-SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
-
-/*
-** CAPI3REF: Invert A Changeset
-**
-** This function is used to "invert" a changeset object. Applying an inverted
-** changeset to a database reverses the effects of applying the uninverted
-** changeset. Specifically:
-**
-** <ul>
-** <li> Each DELETE change is changed to an INSERT, and
-** <li> Each INSERT change is changed to a DELETE, and
-** <li> For each UPDATE change, the old.* and new.* values are exchanged.
-** </ul>
-**
-** This function does not change the order in which changes appear within
-** the changeset. It merely reverses the sense of each individual change.
-**
-** If successful, a pointer to a buffer containing the inverted changeset
-** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and
-** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are
-** zeroed and an SQLite error code returned.
-**
-** It is the responsibility of the caller to eventually call sqlite3_free()
+*/
+SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
+
+/*
+** CAPI3REF: Invert A Changeset
+**
+** This function is used to "invert" a changeset object. Applying an inverted
+** changeset to a database reverses the effects of applying the uninverted
+** changeset. Specifically:
+**
+** <ul>
+** <li> Each DELETE change is changed to an INSERT, and
+** <li> Each INSERT change is changed to a DELETE, and
+** <li> For each UPDATE change, the old.* and new.* values are exchanged.
+** </ul>
+**
+** This function does not change the order in which changes appear within
+** the changeset. It merely reverses the sense of each individual change.
+**
+** If successful, a pointer to a buffer containing the inverted changeset
+** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and
+** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are
+** zeroed and an SQLite error code returned.
+**
+** It is the responsibility of the caller to eventually call sqlite3_free()
** on the *ppOut pointer to free the buffer allocation following a successful
-** call to this function.
-**
-** WARNING/TODO: This function currently assumes that the input is a valid
-** changeset. If it is not, the results are undefined.
-*/
-SQLITE_API int sqlite3changeset_invert(
- int nIn, const void *pIn, /* Input changeset */
- int *pnOut, void **ppOut /* OUT: Inverse of input */
-);
-
-/*
-** CAPI3REF: Concatenate Two Changeset Objects
-**
+** call to this function.
+**
+** WARNING/TODO: This function currently assumes that the input is a valid
+** changeset. If it is not, the results are undefined.
+*/
+SQLITE_API int sqlite3changeset_invert(
+ int nIn, const void *pIn, /* Input changeset */
+ int *pnOut, void **ppOut /* OUT: Inverse of input */
+);
+
+/*
+** CAPI3REF: Concatenate Two Changeset Objects
+**
** This function is used to concatenate two changesets, A and B, into a
-** single changeset. The result is a changeset equivalent to applying
+** single changeset. The result is a changeset equivalent to applying
** changeset A followed by changeset B.
-**
+**
** This function combines the two input changesets using an
-** sqlite3_changegroup object. Calling it produces similar results as the
-** following code fragment:
-**
+** sqlite3_changegroup object. Calling it produces similar results as the
+** following code fragment:
+**
** <pre>
-** sqlite3_changegroup *pGrp;
-** rc = sqlite3_changegroup_new(&pGrp);
-** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
-** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
-** if( rc==SQLITE_OK ){
-** rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
-** }else{
-** *ppOut = 0;
-** *pnOut = 0;
-** }
+** sqlite3_changegroup *pGrp;
+** rc = sqlite3_changegroup_new(&pGrp);
+** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
+** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
+** if( rc==SQLITE_OK ){
+** rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
+** }else{
+** *ppOut = 0;
+** *pnOut = 0;
+** }
** </pre>
-**
-** Refer to the sqlite3_changegroup documentation below for details.
-*/
-SQLITE_API int sqlite3changeset_concat(
- int nA, /* Number of bytes in buffer pA */
- void *pA, /* Pointer to buffer containing changeset A */
- int nB, /* Number of bytes in buffer pB */
- void *pB, /* Pointer to buffer containing changeset B */
- int *pnOut, /* OUT: Number of bytes in output changeset */
- void **ppOut /* OUT: Buffer containing output changeset */
-);
-
-
-/*
-** CAPI3REF: Changegroup Handle
+**
+** Refer to the sqlite3_changegroup documentation below for details.
+*/
+SQLITE_API int sqlite3changeset_concat(
+ int nA, /* Number of bytes in buffer pA */
+ void *pA, /* Pointer to buffer containing changeset A */
+ int nB, /* Number of bytes in buffer pB */
+ void *pB, /* Pointer to buffer containing changeset B */
+ int *pnOut, /* OUT: Number of bytes in output changeset */
+ void **ppOut /* OUT: Buffer containing output changeset */
+);
+
+
+/*
+** CAPI3REF: Changegroup Handle
**
** A changegroup is an object used to combine two or more
** [changesets] or [patchsets]
-*/
-typedef struct sqlite3_changegroup sqlite3_changegroup;
-
-/*
-** CAPI3REF: Create A New Changegroup Object
+*/
+typedef struct sqlite3_changegroup sqlite3_changegroup;
+
+/*
+** CAPI3REF: Create A New Changegroup Object
** CONSTRUCTOR: sqlite3_changegroup
-**
-** An sqlite3_changegroup object is used to combine two or more changesets
-** (or patchsets) into a single changeset (or patchset). A single changegroup
-** object may combine changesets or patchsets, but not both. The output is
-** always in the same format as the input.
-**
-** If successful, this function returns SQLITE_OK and populates (*pp) with
-** a pointer to a new sqlite3_changegroup object before returning. The caller
+**
+** An sqlite3_changegroup object is used to combine two or more changesets
+** (or patchsets) into a single changeset (or patchset). A single changegroup
+** object may combine changesets or patchsets, but not both. The output is
+** always in the same format as the input.
+**
+** If successful, this function returns SQLITE_OK and populates (*pp) with
+** a pointer to a new sqlite3_changegroup object before returning. The caller
** should eventually free the returned object using a call to
-** sqlite3changegroup_delete(). If an error occurs, an SQLite error code
-** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL.
-**
-** The usual usage pattern for an sqlite3_changegroup object is as follows:
-**
-** <ul>
-** <li> It is created using a call to sqlite3changegroup_new().
-**
-** <li> Zero or more changesets (or patchsets) are added to the object
-** by calling sqlite3changegroup_add().
-**
+** sqlite3changegroup_delete(). If an error occurs, an SQLite error code
+** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL.
+**
+** The usual usage pattern for an sqlite3_changegroup object is as follows:
+**
+** <ul>
+** <li> It is created using a call to sqlite3changegroup_new().
+**
+** <li> Zero or more changesets (or patchsets) are added to the object
+** by calling sqlite3changegroup_add().
+**
** <li> The result of combining all input changesets together is obtained
-** by the application via a call to sqlite3changegroup_output().
-**
-** <li> The object is deleted using a call to sqlite3changegroup_delete().
-** </ul>
-**
-** Any number of calls to add() and output() may be made between the calls to
-** new() and delete(), and in any order.
-**
+** by the application via a call to sqlite3changegroup_output().
+**
+** <li> The object is deleted using a call to sqlite3changegroup_delete().
+** </ul>
+**
+** Any number of calls to add() and output() may be made between the calls to
+** new() and delete(), and in any order.
+**
** As well as the regular sqlite3changegroup_add() and
-** sqlite3changegroup_output() functions, also available are the streaming
-** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
-*/
-SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
-
-/*
-** CAPI3REF: Add A Changeset To A Changegroup
+** sqlite3changegroup_output() functions, also available are the streaming
+** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
+*/
+SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
+
+/*
+** CAPI3REF: Add A Changeset To A Changegroup
** METHOD: sqlite3_changegroup
-**
-** Add all changes within the changeset (or patchset) in buffer pData (size
+**
+** Add all changes within the changeset (or patchset) in buffer pData (size
** nData bytes) to the changegroup.
-**
-** If the buffer contains a patchset, then all prior calls to this function
-** on the same changegroup object must also have specified patchsets. Or, if
-** the buffer contains a changeset, so must have the earlier calls to this
-** function. Otherwise, SQLITE_ERROR is returned and no changes are added
-** to the changegroup.
-**
-** Rows within the changeset and changegroup are identified by the values in
-** their PRIMARY KEY columns. A change in the changeset is considered to
-** apply to the same row as a change already present in the changegroup if
-** the two rows have the same primary key.
-**
-** Changes to rows that do not already appear in the changegroup are
-** simply copied into it. Or, if both the new changeset and the changegroup
-** contain changes that apply to a single row, the final contents of the
-** changegroup depends on the type of each change, as follows:
-**
-** <table border=1 style="margin-left:8ex;margin-right:8ex">
-** <tr><th style="white-space:pre">Existing Change </th>
-** <th style="white-space:pre">New Change </th>
-** <th>Output Change
-** <tr><td>INSERT <td>INSERT <td>
-** The new change is ignored. This case does not occur if the new
-** changeset was recorded immediately after the changesets already
-** added to the changegroup.
-** <tr><td>INSERT <td>UPDATE <td>
+**
+** If the buffer contains a patchset, then all prior calls to this function
+** on the same changegroup object must also have specified patchsets. Or, if
+** the buffer contains a changeset, so must have the earlier calls to this
+** function. Otherwise, SQLITE_ERROR is returned and no changes are added
+** to the changegroup.
+**
+** Rows within the changeset and changegroup are identified by the values in
+** their PRIMARY KEY columns. A change in the changeset is considered to
+** apply to the same row as a change already present in the changegroup if
+** the two rows have the same primary key.
+**
+** Changes to rows that do not already appear in the changegroup are
+** simply copied into it. Or, if both the new changeset and the changegroup
+** contain changes that apply to a single row, the final contents of the
+** changegroup depends on the type of each change, as follows:
+**
+** <table border=1 style="margin-left:8ex;margin-right:8ex">
+** <tr><th style="white-space:pre">Existing Change </th>
+** <th style="white-space:pre">New Change </th>
+** <th>Output Change
+** <tr><td>INSERT <td>INSERT <td>
+** The new change is ignored. This case does not occur if the new
+** changeset was recorded immediately after the changesets already
+** added to the changegroup.
+** <tr><td>INSERT <td>UPDATE <td>
** The INSERT change remains in the changegroup. The values in the
-** INSERT change are modified as if the row was inserted by the
-** existing change and then updated according to the new change.
-** <tr><td>INSERT <td>DELETE <td>
-** The existing INSERT is removed from the changegroup. The DELETE is
-** not added.
-** <tr><td>UPDATE <td>INSERT <td>
-** The new change is ignored. This case does not occur if the new
-** changeset was recorded immediately after the changesets already
-** added to the changegroup.
-** <tr><td>UPDATE <td>UPDATE <td>
+** INSERT change are modified as if the row was inserted by the
+** existing change and then updated according to the new change.
+** <tr><td>INSERT <td>DELETE <td>
+** The existing INSERT is removed from the changegroup. The DELETE is
+** not added.
+** <tr><td>UPDATE <td>INSERT <td>
+** The new change is ignored. This case does not occur if the new
+** changeset was recorded immediately after the changesets already
+** added to the changegroup.
+** <tr><td>UPDATE <td>UPDATE <td>
** The existing UPDATE remains within the changegroup. It is amended
** so that the accompanying values are as if the row was updated once
-** by the existing change and then again by the new change.
-** <tr><td>UPDATE <td>DELETE <td>
-** The existing UPDATE is replaced by the new DELETE within the
-** changegroup.
-** <tr><td>DELETE <td>INSERT <td>
-** If one or more of the column values in the row inserted by the
+** by the existing change and then again by the new change.
+** <tr><td>UPDATE <td>DELETE <td>
+** The existing UPDATE is replaced by the new DELETE within the
+** changegroup.
+** <tr><td>DELETE <td>INSERT <td>
+** If one or more of the column values in the row inserted by the
** new change differ from those in the row deleted by the existing
-** change, the existing DELETE is replaced by an UPDATE within the
+** change, the existing DELETE is replaced by an UPDATE within the
** changegroup. Otherwise, if the inserted row is exactly the same
-** as the deleted row, the existing DELETE is simply discarded.
-** <tr><td>DELETE <td>UPDATE <td>
-** The new change is ignored. This case does not occur if the new
-** changeset was recorded immediately after the changesets already
-** added to the changegroup.
-** <tr><td>DELETE <td>DELETE <td>
-** The new change is ignored. This case does not occur if the new
-** changeset was recorded immediately after the changesets already
-** added to the changegroup.
-** </table>
-**
-** If the new changeset contains changes to a table that is already present
-** in the changegroup, then the number of columns and the position of the
-** primary key columns for the table must be consistent. If this is not the
-** case, this function fails with SQLITE_SCHEMA. If the input changeset
-** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
-** returned. Or, if an out-of-memory condition occurs during processing, this
+** as the deleted row, the existing DELETE is simply discarded.
+** <tr><td>DELETE <td>UPDATE <td>
+** The new change is ignored. This case does not occur if the new
+** changeset was recorded immediately after the changesets already
+** added to the changegroup.
+** <tr><td>DELETE <td>DELETE <td>
+** The new change is ignored. This case does not occur if the new
+** changeset was recorded immediately after the changesets already
+** added to the changegroup.
+** </table>
+**
+** If the new changeset contains changes to a table that is already present
+** in the changegroup, then the number of columns and the position of the
+** primary key columns for the table must be consistent. If this is not the
+** case, this function fails with SQLITE_SCHEMA. If the input changeset
+** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
+** returned. Or, if an out-of-memory condition occurs during processing, this
** function returns SQLITE_NOMEM. In all cases, if an error occurs the state
** of the final contents of the changegroup is undefined.
-**
-** If no error occurs, SQLITE_OK is returned.
-*/
-SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
-
-/*
-** CAPI3REF: Obtain A Composite Changeset From A Changegroup
+**
+** If no error occurs, SQLITE_OK is returned.
+*/
+SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+
+/*
+** CAPI3REF: Obtain A Composite Changeset From A Changegroup
** METHOD: sqlite3_changegroup
-**
-** Obtain a buffer containing a changeset (or patchset) representing the
-** current contents of the changegroup. If the inputs to the changegroup
-** were themselves changesets, the output is a changeset. Or, if the
-** inputs were patchsets, the output is also a patchset.
-**
-** As with the output of the sqlite3session_changeset() and
-** sqlite3session_patchset() functions, all changes related to a single
-** table are grouped together in the output of this function. Tables appear
-** in the same order as for the very first changeset added to the changegroup.
-** If the second or subsequent changesets added to the changegroup contain
-** changes for tables that do not appear in the first changeset, they are
-** appended onto the end of the output changeset, again in the order in
-** which they are first encountered.
-**
-** If an error occurs, an SQLite error code is returned and the output
-** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK
+**
+** Obtain a buffer containing a changeset (or patchset) representing the
+** current contents of the changegroup. If the inputs to the changegroup
+** were themselves changesets, the output is a changeset. Or, if the
+** inputs were patchsets, the output is also a patchset.
+**
+** As with the output of the sqlite3session_changeset() and
+** sqlite3session_patchset() functions, all changes related to a single
+** table are grouped together in the output of this function. Tables appear
+** in the same order as for the very first changeset added to the changegroup.
+** If the second or subsequent changesets added to the changegroup contain
+** changes for tables that do not appear in the first changeset, they are
+** appended onto the end of the output changeset, again in the order in
+** which they are first encountered.
+**
+** If an error occurs, an SQLite error code is returned and the output
+** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK
** is returned and the output variables are set to the size of and a
-** pointer to the output buffer, respectively. In this case it is the
-** responsibility of the caller to eventually free the buffer using a
-** call to sqlite3_free().
-*/
-SQLITE_API int sqlite3changegroup_output(
- sqlite3_changegroup*,
- int *pnData, /* OUT: Size of output buffer in bytes */
- void **ppData /* OUT: Pointer to output buffer */
-);
-
-/*
-** CAPI3REF: Delete A Changegroup Object
+** pointer to the output buffer, respectively. In this case it is the
+** responsibility of the caller to eventually free the buffer using a
+** call to sqlite3_free().
+*/
+SQLITE_API int sqlite3changegroup_output(
+ sqlite3_changegroup*,
+ int *pnData, /* OUT: Size of output buffer in bytes */
+ void **ppData /* OUT: Pointer to output buffer */
+);
+
+/*
+** CAPI3REF: Delete A Changegroup Object
** DESTRUCTOR: sqlite3_changegroup
-*/
-SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
-
-/*
-** CAPI3REF: Apply A Changeset To A Database
-**
+*/
+SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
+
+/*
+** CAPI3REF: Apply A Changeset To A Database
+**
** Apply a changeset or patchset to a database. These functions attempt to
** update the "main" database attached to handle db with the changes found in
** the changeset passed via the second and third arguments.
-**
+**
** The fourth argument (xFilter) passed to these functions is the "filter
-** callback". If it is not NULL, then for each table affected by at least one
-** change in the changeset, the filter callback is invoked with
-** the table name as the second argument, and a copy of the context pointer
+** callback". If it is not NULL, then for each table affected by at least one
+** change in the changeset, the filter callback is invoked with
+** the table name as the second argument, and a copy of the context pointer
** passed as the sixth argument as the first. If the "filter callback"
** returns zero, then no attempt is made to apply any changes to the table.
** Otherwise, if the return value is non-zero or the xFilter argument to
** is NULL, all changes related to the table are attempted.
-**
+**
** For each table that is not excluded by the filter callback, this function
** tests that the target database contains a compatible table. A table is
-** considered compatible if all of the following are true:
-**
-** <ul>
+** considered compatible if all of the following are true:
+**
+** <ul>
** <li> The table has the same name as the name recorded in the
-** changeset, and
+** changeset, and
** <li> The table has at least as many columns as recorded in the
-** changeset, and
+** changeset, and
** <li> The table has primary key columns in the same position as
-** recorded in the changeset.
-** </ul>
-**
-** If there is no compatible table, it is not an error, but none of the
-** changes associated with the table are applied. A warning message is issued
-** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most
-** one such warning is issued for each table in the changeset.
-**
+** recorded in the changeset.
+** </ul>
+**
+** If there is no compatible table, it is not an error, but none of the
+** changes associated with the table are applied. A warning message is issued
+** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most
+** one such warning is issued for each table in the changeset.
+**
** For each change for which there is a compatible table, an attempt is made
** to modify the table contents according to the UPDATE, INSERT or DELETE
** change. If a change cannot be applied cleanly, the conflict handler
** function passed as the fifth argument to sqlite3changeset_apply() may be
** invoked. A description of exactly when the conflict handler is invoked for
-** each type of change is below.
-**
-** Unlike the xFilter argument, xConflict may not be passed NULL. The results
-** of passing anything other than a valid function pointer as the xConflict
-** argument are undefined.
-**
-** Each time the conflict handler function is invoked, it must return one
+** each type of change is below.
+**
+** Unlike the xFilter argument, xConflict may not be passed NULL. The results
+** of passing anything other than a valid function pointer as the xConflict
+** argument are undefined.
+**
+** Each time the conflict handler function is invoked, it must return one
** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or
-** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned
-** if the second argument passed to the conflict handler is either
-** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler
-** returns an illegal value, any changes already made are rolled back and
+** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned
+** if the second argument passed to the conflict handler is either
+** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler
+** returns an illegal value, any changes already made are rolled back and
** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different
-** actions are taken by sqlite3changeset_apply() depending on the value
-** returned by each invocation of the conflict-handler function. Refer to
+** actions are taken by sqlite3changeset_apply() depending on the value
+** returned by each invocation of the conflict-handler function. Refer to
** the documentation for the three
-** [SQLITE_CHANGESET_OMIT|available return values] for details.
-**
-** <dl>
-** <dt>DELETE Changes<dd>
+** [SQLITE_CHANGESET_OMIT|available return values] for details.
+**
+** <dl>
+** <dt>DELETE Changes<dd>
** For each DELETE change, the function checks if the target database
** contains a row with the same primary key value (or values) as the
** original row values stored in the changeset. If it does, and the values
** stored in all non-primary key columns also match the values stored in
-** the changeset the row is deleted from the target database.
-**
-** If a row with matching primary key values is found, but one or more of
-** the non-primary key fields contains a value different from the original
-** row value stored in the changeset, the conflict-handler function is
-** invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the
-** database table has more columns than are recorded in the changeset,
-** only the values of those non-primary key fields are compared against
-** the current database contents - any trailing database table columns
-** are ignored.
-**
-** If no row with matching primary key values is found in the database,
-** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
-** passed as the second argument.
-**
-** If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT
-** (which can only happen if a foreign key constraint is violated), the
-** conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT]
-** passed as the second argument. This includes the case where the DELETE
-** operation is attempted because an earlier call to the conflict handler
-** function returned [SQLITE_CHANGESET_REPLACE].
-**
-** <dt>INSERT Changes<dd>
-** For each INSERT change, an attempt is made to insert the new row into
-** the database. If the changeset row contains fewer fields than the
-** database table, the trailing fields are populated with their default
-** values.
-**
+** the changeset the row is deleted from the target database.
+**
+** If a row with matching primary key values is found, but one or more of
+** the non-primary key fields contains a value different from the original
+** row value stored in the changeset, the conflict-handler function is
+** invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the
+** database table has more columns than are recorded in the changeset,
+** only the values of those non-primary key fields are compared against
+** the current database contents - any trailing database table columns
+** are ignored.
+**
+** If no row with matching primary key values is found in the database,
+** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
+** passed as the second argument.
+**
+** If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT
+** (which can only happen if a foreign key constraint is violated), the
+** conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT]
+** passed as the second argument. This includes the case where the DELETE
+** operation is attempted because an earlier call to the conflict handler
+** function returned [SQLITE_CHANGESET_REPLACE].
+**
+** <dt>INSERT Changes<dd>
+** For each INSERT change, an attempt is made to insert the new row into
+** the database. If the changeset row contains fewer fields than the
+** database table, the trailing fields are populated with their default
+** values.
+**
** If the attempt to insert the row fails because the database already
-** contains a row with the same primary key values, the conflict handler
+** contains a row with the same primary key values, the conflict handler
** function is invoked with the second argument set to
-** [SQLITE_CHANGESET_CONFLICT].
-**
-** If the attempt to insert the row fails because of some other constraint
+** [SQLITE_CHANGESET_CONFLICT].
+**
+** If the attempt to insert the row fails because of some other constraint
** violation (e.g. NOT NULL or UNIQUE), the conflict handler function is
-** invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT].
+** invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT].
** This includes the case where the INSERT operation is re-attempted because
** an earlier call to the conflict handler function returned
-** [SQLITE_CHANGESET_REPLACE].
-**
-** <dt>UPDATE Changes<dd>
+** [SQLITE_CHANGESET_REPLACE].
+**
+** <dt>UPDATE Changes<dd>
** For each UPDATE change, the function checks if the target database
** contains a row with the same primary key value (or values) as the
** original row values stored in the changeset. If it does, and the values
-** stored in all modified non-primary key columns also match the values
-** stored in the changeset the row is updated within the target database.
-**
-** If a row with matching primary key values is found, but one or more of
-** the modified non-primary key fields contains a value different from an
-** original row value stored in the changeset, the conflict-handler function
-** is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
-** UPDATE changes only contain values for non-primary key fields that are
-** to be modified, only those fields need to match the original values to
-** avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
-**
-** If no row with matching primary key values is found in the database,
-** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
-** passed as the second argument.
-**
+** stored in all modified non-primary key columns also match the values
+** stored in the changeset the row is updated within the target database.
+**
+** If a row with matching primary key values is found, but one or more of
+** the modified non-primary key fields contains a value different from an
+** original row value stored in the changeset, the conflict-handler function
+** is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
+** UPDATE changes only contain values for non-primary key fields that are
+** to be modified, only those fields need to match the original values to
+** avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
+**
+** If no row with matching primary key values is found in the database,
+** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
+** passed as the second argument.
+**
** If the UPDATE operation is attempted, but SQLite returns
** SQLITE_CONSTRAINT, the conflict-handler function is invoked with
-** [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument.
+** [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument.
** This includes the case where the UPDATE operation is attempted after
-** an earlier call to the conflict handler function returned
+** an earlier call to the conflict handler function returned
** [SQLITE_CHANGESET_REPLACE].
-** </dl>
-**
-** It is safe to execute SQL statements, including those that write to the
-** table that the callback related to, from within the xConflict callback.
+** </dl>
+**
+** It is safe to execute SQL statements, including those that write to the
+** table that the callback related to, from within the xConflict callback.
** This can be used to further customize the application's conflict
-** resolution strategy.
-**
+** resolution strategy.
+**
** All changes made by these functions are enclosed in a savepoint transaction.
-** If any other error (aside from a constraint failure when attempting to
-** write to the target database) occurs, then the savepoint transaction is
+** If any other error (aside from a constraint failure when attempting to
+** write to the target database) occurs, then the savepoint transaction is
** rolled back, restoring the target database to its original state, and an
-** SQLite error code returned.
+** SQLite error code returned.
**
** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
@@ -11381,22 +11381,22 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
**
** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b>
** and therefore subject to change.
-*/
-SQLITE_API int sqlite3changeset_apply(
- sqlite3 *db, /* Apply change to "main" db of this handle */
- int nChangeset, /* Size of changeset in bytes */
- void *pChangeset, /* Changeset blob */
- int(*xFilter)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- const char *zTab /* Table name */
- ),
- int(*xConflict)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
- sqlite3_changeset_iter *p /* Handle describing change and conflict */
- ),
- void *pCtx /* First argument passed to xConflict */
-);
+*/
+SQLITE_API int sqlite3changeset_apply(
+ sqlite3 *db, /* Apply change to "main" db of this handle */
+ int nChangeset, /* Size of changeset in bytes */
+ void *pChangeset, /* Changeset blob */
+ int(*xFilter)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ const char *zTab /* Table name */
+ ),
+ int(*xConflict)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
+ sqlite3_changeset_iter *p /* Handle describing change and conflict */
+ ),
+ void *pCtx /* First argument passed to xConflict */
+);
SQLITE_API int sqlite3changeset_apply_v2(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
@@ -11414,7 +11414,7 @@ SQLITE_API int sqlite3changeset_apply_v2(
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
int flags /* SESSION_CHANGESETAPPLY_* flags */
);
-
+
/*
** CAPI3REF: Flags for sqlite3changeset_apply_v2
**
@@ -11440,101 +11440,101 @@ SQLITE_API int sqlite3changeset_apply_v2(
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
/*
-** CAPI3REF: Constants Passed To The Conflict Handler
-**
-** Values that may be passed as the second argument to a conflict-handler.
-**
-** <dl>
-** <dt>SQLITE_CHANGESET_DATA<dd>
-** The conflict handler is invoked with CHANGESET_DATA as the second argument
-** when processing a DELETE or UPDATE change if a row with the required
+** CAPI3REF: Constants Passed To The Conflict Handler
+**
+** Values that may be passed as the second argument to a conflict-handler.
+**
+** <dl>
+** <dt>SQLITE_CHANGESET_DATA<dd>
+** The conflict handler is invoked with CHANGESET_DATA as the second argument
+** when processing a DELETE or UPDATE change if a row with the required
** PRIMARY KEY fields is present in the database, but one or more other
** (non primary-key) fields modified by the update do not contain the
-** expected "before" values.
+** expected "before" values.
**
-** The conflicting row, in this case, is the database row with the matching
-** primary key.
+** The conflicting row, in this case, is the database row with the matching
+** primary key.
**
-** <dt>SQLITE_CHANGESET_NOTFOUND<dd>
-** The conflict handler is invoked with CHANGESET_NOTFOUND as the second
-** argument when processing a DELETE or UPDATE change if a row with the
-** required PRIMARY KEY fields is not present in the database.
+** <dt>SQLITE_CHANGESET_NOTFOUND<dd>
+** The conflict handler is invoked with CHANGESET_NOTFOUND as the second
+** argument when processing a DELETE or UPDATE change if a row with the
+** required PRIMARY KEY fields is not present in the database.
**
-** There is no conflicting row in this case. The results of invoking the
-** sqlite3changeset_conflict() API are undefined.
+** There is no conflicting row in this case. The results of invoking the
+** sqlite3changeset_conflict() API are undefined.
**
-** <dt>SQLITE_CHANGESET_CONFLICT<dd>
-** CHANGESET_CONFLICT is passed as the second argument to the conflict
+** <dt>SQLITE_CHANGESET_CONFLICT<dd>
+** CHANGESET_CONFLICT is passed as the second argument to the conflict
** handler while processing an INSERT change if the operation would result
-** in duplicate primary key values.
+** in duplicate primary key values.
**
-** The conflicting row in this case is the database row with the matching
-** primary key.
-**
-** <dt>SQLITE_CHANGESET_FOREIGN_KEY<dd>
-** If foreign key handling is enabled, and applying a changeset leaves the
+** The conflicting row in this case is the database row with the matching
+** primary key.
+**
+** <dt>SQLITE_CHANGESET_FOREIGN_KEY<dd>
+** If foreign key handling is enabled, and applying a changeset leaves the
** database in a state containing foreign key violations, the conflict
-** handler is invoked with CHANGESET_FOREIGN_KEY as the second argument
-** exactly once before the changeset is committed. If the conflict handler
-** returns CHANGESET_OMIT, the changes, including those that caused the
-** foreign key constraint violation, are committed. Or, if it returns
-** CHANGESET_ABORT, the changeset is rolled back.
-**
-** No current or conflicting row information is provided. The only function
-** it is possible to call on the supplied sqlite3_changeset_iter handle
-** is sqlite3changeset_fk_conflicts().
-**
-** <dt>SQLITE_CHANGESET_CONSTRAINT<dd>
+** handler is invoked with CHANGESET_FOREIGN_KEY as the second argument
+** exactly once before the changeset is committed. If the conflict handler
+** returns CHANGESET_OMIT, the changes, including those that caused the
+** foreign key constraint violation, are committed. Or, if it returns
+** CHANGESET_ABORT, the changeset is rolled back.
+**
+** No current or conflicting row information is provided. The only function
+** it is possible to call on the supplied sqlite3_changeset_iter handle
+** is sqlite3changeset_fk_conflicts().
+**
+** <dt>SQLITE_CHANGESET_CONSTRAINT<dd>
** If any other constraint violation occurs while applying a change (i.e.
** a UNIQUE, CHECK or NOT NULL constraint), the conflict handler is
-** invoked with CHANGESET_CONSTRAINT as the second argument.
-**
-** There is no conflicting row in this case. The results of invoking the
-** sqlite3changeset_conflict() API are undefined.
-**
-** </dl>
-*/
-#define SQLITE_CHANGESET_DATA 1
-#define SQLITE_CHANGESET_NOTFOUND 2
-#define SQLITE_CHANGESET_CONFLICT 3
-#define SQLITE_CHANGESET_CONSTRAINT 4
-#define SQLITE_CHANGESET_FOREIGN_KEY 5
-
-/*
-** CAPI3REF: Constants Returned By The Conflict Handler
-**
-** A conflict handler callback must return one of the following three values.
-**
-** <dl>
-** <dt>SQLITE_CHANGESET_OMIT<dd>
-** If a conflict handler returns this value no special action is taken. The
+** invoked with CHANGESET_CONSTRAINT as the second argument.
+**
+** There is no conflicting row in this case. The results of invoking the
+** sqlite3changeset_conflict() API are undefined.
+**
+** </dl>
+*/
+#define SQLITE_CHANGESET_DATA 1
+#define SQLITE_CHANGESET_NOTFOUND 2
+#define SQLITE_CHANGESET_CONFLICT 3
+#define SQLITE_CHANGESET_CONSTRAINT 4
+#define SQLITE_CHANGESET_FOREIGN_KEY 5
+
+/*
+** CAPI3REF: Constants Returned By The Conflict Handler
+**
+** A conflict handler callback must return one of the following three values.
+**
+** <dl>
+** <dt>SQLITE_CHANGESET_OMIT<dd>
+** If a conflict handler returns this value no special action is taken. The
** change that caused the conflict is not applied. The session module
-** continues to the next change in the changeset.
-**
-** <dt>SQLITE_CHANGESET_REPLACE<dd>
-** This value may only be returned if the second argument to the conflict
-** handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this
+** continues to the next change in the changeset.
+**
+** <dt>SQLITE_CHANGESET_REPLACE<dd>
+** This value may only be returned if the second argument to the conflict
+** handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this
** is not the case, any changes applied so far are rolled back and the
-** call to sqlite3changeset_apply() returns SQLITE_MISUSE.
-**
-** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict
-** handler, then the conflicting row is either updated or deleted, depending
-** on the type of change.
-**
-** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict
-** handler, then the conflicting row is removed from the database and a
-** second attempt to apply the change is made. If this second attempt fails,
-** the original row is restored to the database before continuing.
-**
-** <dt>SQLITE_CHANGESET_ABORT<dd>
+** call to sqlite3changeset_apply() returns SQLITE_MISUSE.
+**
+** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict
+** handler, then the conflicting row is either updated or deleted, depending
+** on the type of change.
+**
+** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict
+** handler, then the conflicting row is removed from the database and a
+** second attempt to apply the change is made. If this second attempt fails,
+** the original row is restored to the database before continuing.
+**
+** <dt>SQLITE_CHANGESET_ABORT<dd>
** If this value is returned, any changes applied so far are rolled back
-** and the call to sqlite3changeset_apply() returns SQLITE_ABORT.
-** </dl>
-*/
-#define SQLITE_CHANGESET_OMIT 0
-#define SQLITE_CHANGESET_REPLACE 1
-#define SQLITE_CHANGESET_ABORT 2
-
+** and the call to sqlite3changeset_apply() returns SQLITE_ABORT.
+** </dl>
+*/
+#define SQLITE_CHANGESET_OMIT 0
+#define SQLITE_CHANGESET_REPLACE 1
+#define SQLITE_CHANGESET_ABORT 2
+
/*
** CAPI3REF: Rebasing changesets
** EXPERIMENTAL
@@ -11635,7 +11635,7 @@ SQLITE_API int sqlite3changeset_apply_v2(
*/
typedef struct sqlite3_rebaser sqlite3_rebaser;
-/*
+/*
** CAPI3REF: Create a changeset rebaser object.
** EXPERIMENTAL
**
@@ -11691,13 +11691,13 @@ SQLITE_API int sqlite3rebaser_rebase(
SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p);
/*
-** CAPI3REF: Streaming Versions of API functions.
-**
+** CAPI3REF: Streaming Versions of API functions.
+**
** The six streaming API xxx_strm() functions serve similar purposes to the
-** corresponding non-streaming API functions:
-**
-** <table border=1 style="margin-left:8ex;margin-right:8ex">
-** <tr><th>Streaming function<th>Non-streaming equivalent</th>
+** corresponding non-streaming API functions:
+**
+** <table border=1 style="margin-left:8ex;margin-right:8ex">
+** <tr><th>Streaming function<th>Non-streaming equivalent</th>
** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply]
** <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2]
** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat]
@@ -11705,96 +11705,96 @@ SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p);
** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start]
** <tr><td>sqlite3session_changeset_strm<td>[sqlite3session_changeset]
** <tr><td>sqlite3session_patchset_strm<td>[sqlite3session_patchset]
-** </table>
-**
-** Non-streaming functions that accept changesets (or patchsets) as input
+** </table>
+**
+** Non-streaming functions that accept changesets (or patchsets) as input
** require that the entire changeset be stored in a single buffer in memory.
** Similarly, those that return a changeset or patchset do so by returning
** a pointer to a single large buffer allocated using sqlite3_malloc().
** Normally this is convenient. However, if an application running in a
-** low-memory environment is required to handle very large changesets, the
-** large contiguous memory allocations required can become onerous.
-**
-** In order to avoid this problem, instead of a single large buffer, input
-** is passed to a streaming API functions by way of a callback function that
-** the sessions module invokes to incrementally request input data as it is
-** required. In all cases, a pair of API function parameters such as
-**
-** <pre>
-** &nbsp; int nChangeset,
-** &nbsp; void *pChangeset,
-** </pre>
-**
-** Is replaced by:
-**
-** <pre>
-** &nbsp; int (*xInput)(void *pIn, void *pData, int *pnData),
-** &nbsp; void *pIn,
-** </pre>
-**
-** Each time the xInput callback is invoked by the sessions module, the first
+** low-memory environment is required to handle very large changesets, the
+** large contiguous memory allocations required can become onerous.
+**
+** In order to avoid this problem, instead of a single large buffer, input
+** is passed to a streaming API functions by way of a callback function that
+** the sessions module invokes to incrementally request input data as it is
+** required. In all cases, a pair of API function parameters such as
+**
+** <pre>
+** &nbsp; int nChangeset,
+** &nbsp; void *pChangeset,
+** </pre>
+**
+** Is replaced by:
+**
+** <pre>
+** &nbsp; int (*xInput)(void *pIn, void *pData, int *pnData),
+** &nbsp; void *pIn,
+** </pre>
+**
+** Each time the xInput callback is invoked by the sessions module, the first
** argument passed is a copy of the supplied pIn context pointer. The second
** argument, pData, points to a buffer (*pnData) bytes in size. Assuming no
** error occurs the xInput method should copy up to (*pnData) bytes of data
** into the buffer and set (*pnData) to the actual number of bytes copied
** before returning SQLITE_OK. If the input is completely exhausted, (*pnData)
** should be set to zero to indicate this. Or, if an error occurs, an SQLite
-** error code should be returned. In all cases, if an xInput callback returns
-** an error, all processing is abandoned and the streaming API function
-** returns a copy of the error code to the caller.
-**
-** In the case of sqlite3changeset_start_strm(), the xInput callback may be
-** invoked by the sessions module at any point during the lifetime of the
-** iterator. If such an xInput callback returns an error, the iterator enters
+** error code should be returned. In all cases, if an xInput callback returns
+** an error, all processing is abandoned and the streaming API function
+** returns a copy of the error code to the caller.
+**
+** In the case of sqlite3changeset_start_strm(), the xInput callback may be
+** invoked by the sessions module at any point during the lifetime of the
+** iterator. If such an xInput callback returns an error, the iterator enters
** an error state, whereby all subsequent calls to iterator functions
-** immediately fail with the same error code as returned by xInput.
-**
-** Similarly, streaming API functions that return changesets (or patchsets)
-** return them in chunks by way of a callback function instead of via a
-** pointer to a single large buffer. In this case, a pair of parameters such
-** as:
-**
-** <pre>
-** &nbsp; int *pnChangeset,
-** &nbsp; void **ppChangeset,
-** </pre>
-**
-** Is replaced by:
-**
-** <pre>
-** &nbsp; int (*xOutput)(void *pOut, const void *pData, int nData),
-** &nbsp; void *pOut
-** </pre>
-**
-** The xOutput callback is invoked zero or more times to return data to
-** the application. The first parameter passed to each call is a copy of the
-** pOut pointer supplied by the application. The second parameter, pData,
-** points to a buffer nData bytes in size containing the chunk of output
-** data being returned. If the xOutput callback successfully processes the
-** supplied data, it should return SQLITE_OK to indicate success. Otherwise,
-** it should return some other SQLite error code. In this case processing
-** is immediately abandoned and the streaming API function returns a copy
-** of the xOutput error code to the application.
-**
+** immediately fail with the same error code as returned by xInput.
+**
+** Similarly, streaming API functions that return changesets (or patchsets)
+** return them in chunks by way of a callback function instead of via a
+** pointer to a single large buffer. In this case, a pair of parameters such
+** as:
+**
+** <pre>
+** &nbsp; int *pnChangeset,
+** &nbsp; void **ppChangeset,
+** </pre>
+**
+** Is replaced by:
+**
+** <pre>
+** &nbsp; int (*xOutput)(void *pOut, const void *pData, int nData),
+** &nbsp; void *pOut
+** </pre>
+**
+** The xOutput callback is invoked zero or more times to return data to
+** the application. The first parameter passed to each call is a copy of the
+** pOut pointer supplied by the application. The second parameter, pData,
+** points to a buffer nData bytes in size containing the chunk of output
+** data being returned. If the xOutput callback successfully processes the
+** supplied data, it should return SQLITE_OK to indicate success. Otherwise,
+** it should return some other SQLite error code. In this case processing
+** is immediately abandoned and the streaming API function returns a copy
+** of the xOutput error code to the application.
+**
** The sessions module never invokes an xOutput callback with the third
-** parameter set to a value less than or equal to zero. Other than this,
-** no guarantees are made as to the size of the chunks of data returned.
-*/
-SQLITE_API int sqlite3changeset_apply_strm(
- sqlite3 *db, /* Apply change to "main" db of this handle */
- int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
- void *pIn, /* First arg for xInput */
- int(*xFilter)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- const char *zTab /* Table name */
- ),
- int(*xConflict)(
- void *pCtx, /* Copy of sixth arg to _apply() */
- int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
- sqlite3_changeset_iter *p /* Handle describing change and conflict */
- ),
- void *pCtx /* First argument passed to xConflict */
-);
+** parameter set to a value less than or equal to zero. Other than this,
+** no guarantees are made as to the size of the chunks of data returned.
+*/
+SQLITE_API int sqlite3changeset_apply_strm(
+ sqlite3 *db, /* Apply change to "main" db of this handle */
+ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
+ void *pIn, /* First arg for xInput */
+ int(*xFilter)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ const char *zTab /* Table name */
+ ),
+ int(*xConflict)(
+ void *pCtx, /* Copy of sixth arg to _apply() */
+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
+ sqlite3_changeset_iter *p /* Handle describing change and conflict */
+ ),
+ void *pCtx /* First argument passed to xConflict */
+);
SQLITE_API int sqlite3changeset_apply_v2_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
@@ -11812,49 +11812,49 @@ SQLITE_API int sqlite3changeset_apply_v2_strm(
void **ppRebase, int *pnRebase,
int flags
);
-SQLITE_API int sqlite3changeset_concat_strm(
- int (*xInputA)(void *pIn, void *pData, int *pnData),
- void *pInA,
- int (*xInputB)(void *pIn, void *pData, int *pnData),
- void *pInB,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-);
-SQLITE_API int sqlite3changeset_invert_strm(
- int (*xInput)(void *pIn, void *pData, int *pnData),
- void *pIn,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-);
-SQLITE_API int sqlite3changeset_start_strm(
- sqlite3_changeset_iter **pp,
- int (*xInput)(void *pIn, void *pData, int *pnData),
- void *pIn
-);
+SQLITE_API int sqlite3changeset_concat_strm(
+ int (*xInputA)(void *pIn, void *pData, int *pnData),
+ void *pInA,
+ int (*xInputB)(void *pIn, void *pData, int *pnData),
+ void *pInB,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+);
+SQLITE_API int sqlite3changeset_invert_strm(
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+);
+SQLITE_API int sqlite3changeset_start_strm(
+ sqlite3_changeset_iter **pp,
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn
+);
SQLITE_API int sqlite3changeset_start_v2_strm(
sqlite3_changeset_iter **pp,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn,
int flags
);
-SQLITE_API int sqlite3session_changeset_strm(
- sqlite3_session *pSession,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-);
-SQLITE_API int sqlite3session_patchset_strm(
- sqlite3_session *pSession,
- int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-);
+SQLITE_API int sqlite3session_changeset_strm(
+ sqlite3_session *pSession,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+);
+SQLITE_API int sqlite3session_patchset_strm(
+ sqlite3_session *pSession,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+);
SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*,
- int (*xInput)(void *pIn, void *pData, int *pnData),
- void *pIn
-);
-SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn
+);
+SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
int (*xOutput)(void *pOut, const void *pData, int nData),
- void *pOut
-);
+ void *pOut
+);
SQLITE_API int sqlite3rebaser_rebase_strm(
sqlite3_rebaser *pRebaser,
int (*xInput)(void *pIn, void *pData, int *pnData),
@@ -11862,7 +11862,7 @@ SQLITE_API int sqlite3rebaser_rebase_strm(
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-
+
/*
** CAPI3REF: Configure global parameters
**
@@ -11897,596 +11897,596 @@ SQLITE_API int sqlite3rebaser_rebase_strm(
** otherwise.
*/
SQLITE_API int sqlite3session_config(int op, void *pArg);
-
-/*
+
+/*
** CAPI3REF: Values for sqlite3session_config().
*/
#define SQLITE_SESSION_CONFIG_STRMSIZE 1
/*
-** Make sure we can call this stuff from C++.
-*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */
-
-/******** End of sqlite3session.h *********/
-/******** Begin file fts5.h *********/
-/*
-** 2014 May 31
-**
-** 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.
-**
-******************************************************************************
-**
+** Make sure we can call this stuff from C++.
+*/
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */
+
+/******** End of sqlite3session.h *********/
+/******** Begin file fts5.h *********/
+/*
+** 2014 May 31
+**
+** 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.
+**
+******************************************************************************
+**
** Interfaces to extend FTS5. Using the interfaces defined in this file,
-** FTS5 may be extended with:
-**
-** * custom tokenizers, and
-** * custom auxiliary functions.
-*/
-
-
-#ifndef _FTS5_H
-#define _FTS5_H
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*************************************************************************
-** CUSTOM AUXILIARY FUNCTIONS
-**
-** Virtual table implementations may overload SQL functions by implementing
-** the sqlite3_module.xFindFunction() method.
-*/
-
-typedef struct Fts5ExtensionApi Fts5ExtensionApi;
-typedef struct Fts5Context Fts5Context;
-typedef struct Fts5PhraseIter Fts5PhraseIter;
-
-typedef void (*fts5_extension_function)(
- const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
- Fts5Context *pFts, /* First arg to pass to pApi functions */
- sqlite3_context *pCtx, /* Context for returning result/error */
- int nVal, /* Number of values in apVal[] array */
- sqlite3_value **apVal /* Array of trailing arguments */
-);
-
-struct Fts5PhraseIter {
- const unsigned char *a;
- const unsigned char *b;
-};
-
-/*
-** EXTENSION API FUNCTIONS
-**
-** xUserData(pFts):
+** FTS5 may be extended with:
+**
+** * custom tokenizers, and
+** * custom auxiliary functions.
+*/
+
+
+#ifndef _FTS5_H
+#define _FTS5_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*************************************************************************
+** CUSTOM AUXILIARY FUNCTIONS
+**
+** Virtual table implementations may overload SQL functions by implementing
+** the sqlite3_module.xFindFunction() method.
+*/
+
+typedef struct Fts5ExtensionApi Fts5ExtensionApi;
+typedef struct Fts5Context Fts5Context;
+typedef struct Fts5PhraseIter Fts5PhraseIter;
+
+typedef void (*fts5_extension_function)(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+);
+
+struct Fts5PhraseIter {
+ const unsigned char *a;
+ const unsigned char *b;
+};
+
+/*
+** EXTENSION API FUNCTIONS
+**
+** xUserData(pFts):
** Return a copy of the context pointer the extension function was
-** registered with.
-**
-** xColumnTotalSize(pFts, iCol, pnToken):
-** If parameter iCol is less than zero, set output variable *pnToken
-** to the total number of tokens in the FTS5 table. Or, if iCol is
-** non-negative but less than the number of columns in the table, return
+** registered with.
+**
+** xColumnTotalSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the FTS5 table. Or, if iCol is
+** non-negative but less than the number of columns in the table, return
** the total number of tokens in column iCol, considering all rows in
-** the FTS5 table.
-**
-** If parameter iCol is greater than or equal to the number of columns
-** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** the FTS5 table.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
** an OOM condition or IO error), an appropriate SQLite error code is
-** returned.
-**
-** xColumnCount(pFts):
-** Return the number of columns in the table.
-**
-** xColumnSize(pFts, iCol, pnToken):
-** If parameter iCol is less than zero, set output variable *pnToken
-** to the total number of tokens in the current row. Or, if iCol is
-** non-negative but less than the number of columns in the table, set
-** *pnToken to the number of tokens in column iCol of the current row.
-**
-** If parameter iCol is greater than or equal to the number of columns
-** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** returned.
+**
+** xColumnCount(pFts):
+** Return the number of columns in the table.
+**
+** xColumnSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the current row. Or, if iCol is
+** non-negative but less than the number of columns in the table, set
+** *pnToken to the number of tokens in column iCol of the current row.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
** an OOM condition or IO error), an appropriate SQLite error code is
-** returned.
-**
-** This function may be quite inefficient if used with an FTS5 table
-** created with the "columnsize=0" option.
-**
-** xColumnText:
-** This function attempts to retrieve the text of column iCol of the
-** current document. If successful, (*pz) is set to point to a buffer
-** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
-** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
-** if an error occurs, an SQLite error code is returned and the final values
-** of (*pz) and (*pn) are undefined.
-**
-** xPhraseCount:
-** Returns the number of phrases in the current query expression.
-**
-** xPhraseSize:
-** Returns the number of tokens in phrase iPhrase of the query. Phrases
-** are numbered starting from zero.
-**
-** xInstCount:
-** Set *pnInst to the total number of occurrences of all phrases within
-** the query within the current row. Return SQLITE_OK if successful, or
-** an error code (i.e. SQLITE_NOMEM) if an error occurs.
-**
-** This API can be quite slow if used with an FTS5 table created with the
+** returned.
+**
+** This function may be quite inefficient if used with an FTS5 table
+** created with the "columnsize=0" option.
+**
+** xColumnText:
+** This function attempts to retrieve the text of column iCol of the
+** current document. If successful, (*pz) is set to point to a buffer
+** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
+** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
+** if an error occurs, an SQLite error code is returned and the final values
+** of (*pz) and (*pn) are undefined.
+**
+** xPhraseCount:
+** Returns the number of phrases in the current query expression.
+**
+** xPhraseSize:
+** Returns the number of tokens in phrase iPhrase of the query. Phrases
+** are numbered starting from zero.
+**
+** xInstCount:
+** Set *pnInst to the total number of occurrences of all phrases within
+** the query within the current row. Return SQLITE_OK if successful, or
+** an error code (i.e. SQLITE_NOMEM) if an error occurs.
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option. If the FTS5 table is created
** with either "detail=none" or "detail=column" and "content=" option
-** (i.e. if it is a contentless table), then this API always returns 0.
-**
-** xInst:
-** Query for the details of phrase match iIdx within the current row.
-** Phrase matches are numbered starting from zero, so the iIdx argument
-** should be greater than or equal to zero and smaller than the value
-** output by xInstCount().
-**
-** Usually, output parameter *piPhrase is set to the phrase number, *piCol
-** to the column in which it occurs and *piOff the token offset of the
+** (i.e. if it is a contentless table), then this API always returns 0.
+**
+** xInst:
+** Query for the details of phrase match iIdx within the current row.
+** Phrase matches are numbered starting from zero, so the iIdx argument
+** should be greater than or equal to zero and smaller than the value
+** output by xInstCount().
+**
+** Usually, output parameter *piPhrase is set to the phrase number, *piCol
+** to the column in which it occurs and *piOff the token offset of the
** first token of the phrase. Returns SQLITE_OK if successful, or an error
** code (i.e. SQLITE_NOMEM) if an error occurs.
-**
-** This API can be quite slow if used with an FTS5 table created with the
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
-**
-** xRowid:
-** Returns the rowid of the current row.
-**
-** xTokenize:
-** Tokenize text using the tokenizer belonging to the FTS5 table.
-**
-** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
-** This API function is used to query the FTS table for phrase iPhrase
-** of the current query. Specifically, a query equivalent to:
-**
-** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
-**
-** with $p set to a phrase equivalent to the phrase iPhrase of the
-** current query is executed. Any column filter that applies to
+**
+** xRowid:
+** Returns the rowid of the current row.
+**
+** xTokenize:
+** Tokenize text using the tokenizer belonging to the FTS5 table.
+**
+** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
+** This API function is used to query the FTS table for phrase iPhrase
+** of the current query. Specifically, a query equivalent to:
+**
+** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
+**
+** with $p set to a phrase equivalent to the phrase iPhrase of the
+** current query is executed. Any column filter that applies to
** phrase iPhrase of the current query is included in $p. For each
** row visited, the callback function passed as the fourth argument
** is invoked. The context and API objects passed to the callback
-** function may be used to access the properties of each matched row.
+** function may be used to access the properties of each matched row.
** Invoking Api.xUserData() returns a copy of the pointer passed as
-** the third argument to pUserData.
-**
-** If the callback function returns any value other than SQLITE_OK, the
-** query is abandoned and the xQueryPhrase function returns immediately.
-** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
-** Otherwise, the error code is propagated upwards.
-**
-** If the query runs to completion without incident, SQLITE_OK is returned.
-** Or, if some error occurs before the query completes or is aborted by
-** the callback, an SQLite error code is returned.
-**
-**
-** xSetAuxdata(pFts5, pAux, xDelete)
-**
+** the third argument to pUserData.
+**
+** If the callback function returns any value other than SQLITE_OK, the
+** query is abandoned and the xQueryPhrase function returns immediately.
+** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
+** Otherwise, the error code is propagated upwards.
+**
+** If the query runs to completion without incident, SQLITE_OK is returned.
+** Or, if some error occurs before the query completes or is aborted by
+** the callback, an SQLite error code is returned.
+**
+**
+** xSetAuxdata(pFts5, pAux, xDelete)
+**
** Save the pointer passed as the second argument as the extension function's
-** "auxiliary data". The pointer may then be retrieved by the current or any
-** future invocation of the same fts5 extension function made as part of
+** "auxiliary data". The pointer may then be retrieved by the current or any
+** future invocation of the same fts5 extension function made as part of
** the same MATCH query using the xGetAuxdata() API.
-**
-** Each extension function is allocated a single auxiliary data slot for
+**
+** Each extension function is allocated a single auxiliary data slot for
** each FTS query (MATCH expression). If the extension function is invoked
** more than once for a single FTS query, then all invocations share a
-** single auxiliary data context.
-**
-** If there is already an auxiliary data pointer when this function is
-** invoked, then it is replaced by the new pointer. If an xDelete callback
-** was specified along with the original pointer, it is invoked at this
-** point.
-**
-** The xDelete callback, if one is specified, is also invoked on the
-** auxiliary data pointer after the FTS5 query has finished.
-**
+** single auxiliary data context.
+**
+** If there is already an auxiliary data pointer when this function is
+** invoked, then it is replaced by the new pointer. If an xDelete callback
+** was specified along with the original pointer, it is invoked at this
+** point.
+**
+** The xDelete callback, if one is specified, is also invoked on the
+** auxiliary data pointer after the FTS5 query has finished.
+**
** If an error (e.g. an OOM condition) occurs within this function,
-** the auxiliary data is set to NULL and an error code returned. If the
-** xDelete parameter was not NULL, it is invoked on the auxiliary data
-** pointer before returning.
-**
-**
-** xGetAuxdata(pFts5, bClear)
-**
+** the auxiliary data is set to NULL and an error code returned. If the
+** xDelete parameter was not NULL, it is invoked on the auxiliary data
+** pointer before returning.
+**
+**
+** xGetAuxdata(pFts5, bClear)
+**
** Returns the current auxiliary data pointer for the fts5 extension
-** function. See the xSetAuxdata() method for details.
-**
-** If the bClear argument is non-zero, then the auxiliary data is cleared
-** (set to NULL) before this function returns. In this case the xDelete,
-** if any, is not invoked.
-**
-**
-** xRowCount(pFts5, pnRow)
-**
-** This function is used to retrieve the total number of rows in the table.
-** In other words, the same value that would be returned by:
-**
-** SELECT count(*) FROM ftstable;
-**
-** xPhraseFirst()
-** This function is used, along with type Fts5PhraseIter and the xPhraseNext
-** method, to iterate through all instances of a single query phrase within
-** the current row. This is the same information as is accessible via the
-** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
+** function. See the xSetAuxdata() method for details.
+**
+** If the bClear argument is non-zero, then the auxiliary data is cleared
+** (set to NULL) before this function returns. In this case the xDelete,
+** if any, is not invoked.
+**
+**
+** xRowCount(pFts5, pnRow)
+**
+** This function is used to retrieve the total number of rows in the table.
+** In other words, the same value that would be returned by:
+**
+** SELECT count(*) FROM ftstable;
+**
+** xPhraseFirst()
+** This function is used, along with type Fts5PhraseIter and the xPhraseNext
+** method, to iterate through all instances of a single query phrase within
+** the current row. This is the same information as is accessible via the
+** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
** to use, this API may be faster under some circumstances. To iterate
-** through instances of phrase iPhrase, use the following code:
-**
-** Fts5PhraseIter iter;
-** int iCol, iOff;
-** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
-** iCol>=0;
-** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
-** ){
-** // An instance of phrase iPhrase at offset iOff of column iCol
-** }
-**
-** The Fts5PhraseIter structure is defined above. Applications should not
-** modify this structure directly - it should only be used as shown above
-** with the xPhraseFirst() and xPhraseNext() API methods (and by
-** xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
-**
-** This API can be quite slow if used with an FTS5 table created with the
+** through instances of phrase iPhrase, use the following code:
+**
+** Fts5PhraseIter iter;
+** int iCol, iOff;
+** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
+** iCol>=0;
+** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
+** ){
+** // An instance of phrase iPhrase at offset iOff of column iCol
+** }
+**
+** The Fts5PhraseIter structure is defined above. Applications should not
+** modify this structure directly - it should only be used as shown above
+** with the xPhraseFirst() and xPhraseNext() API methods (and by
+** xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option. If the FTS5 table is created
** with either "detail=none" or "detail=column" and "content=" option
-** (i.e. if it is a contentless table), then this API always iterates
-** through an empty set (all calls to xPhraseFirst() set iCol to -1).
-**
-** xPhraseNext()
-** See xPhraseFirst above.
-**
-** xPhraseFirstColumn()
-** This function and xPhraseNextColumn() are similar to the xPhraseFirst()
-** and xPhraseNext() APIs described above. The difference is that instead
-** of iterating through all instances of a phrase in the current row, these
-** APIs are used to iterate through the set of columns in the current row
-** that contain one or more instances of a specified phrase. For example:
-**
-** Fts5PhraseIter iter;
-** int iCol;
-** for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
-** iCol>=0;
-** pApi->xPhraseNextColumn(pFts, &iter, &iCol)
-** ){
-** // Column iCol contains at least one instance of phrase iPhrase
-** }
-**
-** This API can be quite slow if used with an FTS5 table created with the
+** (i.e. if it is a contentless table), then this API always iterates
+** through an empty set (all calls to xPhraseFirst() set iCol to -1).
+**
+** xPhraseNext()
+** See xPhraseFirst above.
+**
+** xPhraseFirstColumn()
+** This function and xPhraseNextColumn() are similar to the xPhraseFirst()
+** and xPhraseNext() APIs described above. The difference is that instead
+** of iterating through all instances of a phrase in the current row, these
+** APIs are used to iterate through the set of columns in the current row
+** that contain one or more instances of a specified phrase. For example:
+**
+** Fts5PhraseIter iter;
+** int iCol;
+** for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
+** iCol>=0;
+** pApi->xPhraseNextColumn(pFts, &iter, &iCol)
+** ){
+** // Column iCol contains at least one instance of phrase iPhrase
+** }
+**
+** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" option. If the FTS5 table is created with either
** "detail=none" "content=" option (i.e. if it is a contentless table),
** then this API always iterates through an empty set (all calls to
-** xPhraseFirstColumn() set iCol to -1).
-**
-** The information accessed using this API and its companion
-** xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
-** (or xInst/xInstCount). The chief advantage of this API is that it is
-** significantly more efficient than those alternatives when used with
+** xPhraseFirstColumn() set iCol to -1).
+**
+** The information accessed using this API and its companion
+** xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
+** (or xInst/xInstCount). The chief advantage of this API is that it is
+** significantly more efficient than those alternatives when used with
** "detail=column" tables.
-**
-** xPhraseNextColumn()
-** See xPhraseFirstColumn above.
-*/
-struct Fts5ExtensionApi {
- int iVersion; /* Currently always set to 3 */
-
- void *(*xUserData)(Fts5Context*);
-
- int (*xColumnCount)(Fts5Context*);
- int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
- int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
-
+**
+** xPhraseNextColumn()
+** See xPhraseFirstColumn above.
+*/
+struct Fts5ExtensionApi {
+ int iVersion; /* Currently always set to 3 */
+
+ void *(*xUserData)(Fts5Context*);
+
+ int (*xColumnCount)(Fts5Context*);
+ int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
+ int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
+
int (*xTokenize)(Fts5Context*,
- const char *pText, int nText, /* Text to tokenize */
- void *pCtx, /* Context passed to xToken() */
- int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
- );
-
- int (*xPhraseCount)(Fts5Context*);
- int (*xPhraseSize)(Fts5Context*, int iPhrase);
-
- int (*xInstCount)(Fts5Context*, int *pnInst);
- int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
-
- sqlite3_int64 (*xRowid)(Fts5Context*);
- int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
- int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
-
- int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
- int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
- );
- int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
- void *(*xGetAuxdata)(Fts5Context*, int bClear);
-
- int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
- void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
-
- int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
- void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
-};
-
-/*
-** CUSTOM AUXILIARY FUNCTIONS
-*************************************************************************/
-
-/*************************************************************************
-** CUSTOM TOKENIZERS
-**
+ const char *pText, int nText, /* Text to tokenize */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+ );
+
+ int (*xPhraseCount)(Fts5Context*);
+ int (*xPhraseSize)(Fts5Context*, int iPhrase);
+
+ int (*xInstCount)(Fts5Context*, int *pnInst);
+ int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
+
+ sqlite3_int64 (*xRowid)(Fts5Context*);
+ int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
+ int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
+
+ int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
+ int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
+ );
+ int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
+ void *(*xGetAuxdata)(Fts5Context*, int bClear);
+
+ int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
+ void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
+
+ int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
+ void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
+};
+
+/*
+** CUSTOM AUXILIARY FUNCTIONS
+*************************************************************************/
+
+/*************************************************************************
+** CUSTOM TOKENIZERS
+**
** Applications may also register custom tokenizer types. A tokenizer
** is registered by providing fts5 with a populated instance of the
-** following structure. All structure methods must be defined, setting
-** any member of the fts5_tokenizer struct to NULL leads to undefined
-** behaviour. The structure methods are expected to function as follows:
-**
-** xCreate:
-** This function is used to allocate and initialize a tokenizer instance.
-** A tokenizer instance is required to actually tokenize text.
-**
-** The first argument passed to this function is a copy of the (void*)
-** pointer provided by the application when the fts5_tokenizer object
+** following structure. All structure methods must be defined, setting
+** any member of the fts5_tokenizer struct to NULL leads to undefined
+** behaviour. The structure methods are expected to function as follows:
+**
+** xCreate:
+** This function is used to allocate and initialize a tokenizer instance.
+** A tokenizer instance is required to actually tokenize text.
+**
+** The first argument passed to this function is a copy of the (void*)
+** pointer provided by the application when the fts5_tokenizer object
** was registered with FTS5 (the third argument to xCreateTokenizer()).
-** The second and third arguments are an array of nul-terminated strings
-** containing the tokenizer arguments, if any, specified following the
-** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
-** to create the FTS5 table.
-**
+** The second and third arguments are an array of nul-terminated strings
+** containing the tokenizer arguments, if any, specified following the
+** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
+** to create the FTS5 table.
+**
** The final argument is an output variable. If successful, (*ppOut)
-** should be set to point to the new tokenizer handle and SQLITE_OK
-** returned. If an error occurs, some value other than SQLITE_OK should
+** should be set to point to the new tokenizer handle and SQLITE_OK
+** returned. If an error occurs, some value other than SQLITE_OK should
** be returned. In this case, fts5 assumes that the final value of *ppOut
-** is undefined.
-**
-** xDelete:
-** This function is invoked to delete a tokenizer handle previously
-** allocated using xCreate(). Fts5 guarantees that this function will
-** be invoked exactly once for each successful call to xCreate().
-**
-** xTokenize:
+** is undefined.
+**
+** xDelete:
+** This function is invoked to delete a tokenizer handle previously
+** allocated using xCreate(). Fts5 guarantees that this function will
+** be invoked exactly once for each successful call to xCreate().
+**
+** xTokenize:
** This function is expected to tokenize the nText byte string indicated
-** by argument pText. pText may or may not be nul-terminated. The first
-** argument passed to this function is a pointer to an Fts5Tokenizer object
-** returned by an earlier call to xCreate().
-**
-** The second argument indicates the reason that FTS5 is requesting
-** tokenization of the supplied text. This is always one of the following
-** four values:
-**
-** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
-** or removed from the FTS table. The tokenizer is being invoked to
-** determine the set of tokens to add to (or delete from) the
-** FTS index.
-**
+** by argument pText. pText may or may not be nul-terminated. The first
+** argument passed to this function is a pointer to an Fts5Tokenizer object
+** returned by an earlier call to xCreate().
+**
+** The second argument indicates the reason that FTS5 is requesting
+** tokenization of the supplied text. This is always one of the following
+** four values:
+**
+** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
+** or removed from the FTS table. The tokenizer is being invoked to
+** determine the set of tokens to add to (or delete from) the
+** FTS index.
+**
** <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed
** against the FTS index. The tokenizer is being called to tokenize
-** a bareword or quoted string specified as part of the query.
-**
-** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
-** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
-** followed by a "*" character, indicating that the last token
-** returned by the tokenizer will be treated as a token prefix.
-**
+** a bareword or quoted string specified as part of the query.
+**
+** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
+** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
+** followed by a "*" character, indicating that the last token
+** returned by the tokenizer will be treated as a token prefix.
+**
** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
-** satisfy an fts5_api.xTokenize() request made by an auxiliary
-** function. Or an fts5_api.xColumnSize() request made by the same
+** satisfy an fts5_api.xTokenize() request made by an auxiliary
+** function. Or an fts5_api.xColumnSize() request made by the same
** on a columnsize=0 database.
-** </ul>
-**
-** For each token in the input string, the supplied callback xToken() must
-** be invoked. The first argument to it should be a copy of the pointer
-** passed as the second argument to xTokenize(). The third and fourth
-** arguments are a pointer to a buffer containing the token text, and the
-** size of the token in bytes. The 4th and 5th arguments are the byte offsets
-** of the first byte of and first byte immediately following the text from
-** which the token is derived within the input.
-**
-** The second argument passed to the xToken() callback ("tflags") should
+** </ul>
+**
+** For each token in the input string, the supplied callback xToken() must
+** be invoked. The first argument to it should be a copy of the pointer
+** passed as the second argument to xTokenize(). The third and fourth
+** arguments are a pointer to a buffer containing the token text, and the
+** size of the token in bytes. The 4th and 5th arguments are the byte offsets
+** of the first byte of and first byte immediately following the text from
+** which the token is derived within the input.
+**
+** The second argument passed to the xToken() callback ("tflags") should
** normally be set to 0. The exception is if the tokenizer supports
-** synonyms. In this case see the discussion below for details.
-**
+** synonyms. In this case see the discussion below for details.
+**
** FTS5 assumes the xToken() callback is invoked for each token in the
-** order that they occur within the input text.
-**
-** If an xToken() callback returns any value other than SQLITE_OK, then
-** the tokenization should be abandoned and the xTokenize() method should
-** immediately return a copy of the xToken() return value. Or, if the
-** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
-** if an error occurs with the xTokenize() implementation itself, it
-** may abandon the tokenization and return any error code other than
-** SQLITE_OK or SQLITE_DONE.
-**
-** SYNONYM SUPPORT
-**
-** Custom tokenizers may also support synonyms. Consider a case in which a
+** order that they occur within the input text.
+**
+** If an xToken() callback returns any value other than SQLITE_OK, then
+** the tokenization should be abandoned and the xTokenize() method should
+** immediately return a copy of the xToken() return value. Or, if the
+** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
+** if an error occurs with the xTokenize() implementation itself, it
+** may abandon the tokenization and return any error code other than
+** SQLITE_OK or SQLITE_DONE.
+**
+** SYNONYM SUPPORT
+**
+** Custom tokenizers may also support synonyms. Consider a case in which a
** user wishes to query for a phrase such as "first place". Using the
-** built-in tokenizers, the FTS5 query 'first + place' will match instances
-** of "first place" within the document set, but not alternative forms
-** such as "1st place". In some applications, it would be better to match
-** all instances of "first place" or "1st place" regardless of which form
-** the user specified in the MATCH query text.
-**
-** There are several ways to approach this in FTS5:
-**
+** built-in tokenizers, the FTS5 query 'first + place' will match instances
+** of "first place" within the document set, but not alternative forms
+** such as "1st place". In some applications, it would be better to match
+** all instances of "first place" or "1st place" regardless of which form
+** the user specified in the MATCH query text.
+**
+** There are several ways to approach this in FTS5:
+**
** <ol><li> By mapping all synonyms to a single token. In this case, using
** the above example, this means that the tokenizer returns the
-** same token for inputs "first" and "1st". Say that token is in
-** fact "first", so that when the user inserts the document "I won
-** 1st place" entries are added to the index for tokens "i", "won",
-** "first" and "place". If the user then queries for '1st + place',
-** the tokenizer substitutes "first" for "1st" and the query works
-** as expected.
-**
+** same token for inputs "first" and "1st". Say that token is in
+** fact "first", so that when the user inserts the document "I won
+** 1st place" entries are added to the index for tokens "i", "won",
+** "first" and "place". If the user then queries for '1st + place',
+** the tokenizer substitutes "first" for "1st" and the query works
+** as expected.
+**
** <li> By querying the index for all synonyms of each query term
** separately. In this case, when tokenizing query text, the
** tokenizer may provide multiple synonyms for a single term
** within the document. FTS5 then queries the index for each
** synonym individually. For example, faced with the query:
-**
-** <codeblock>
-** ... MATCH 'first place'</codeblock>
-**
-** the tokenizer offers both "1st" and "first" as synonyms for the
+**
+** <codeblock>
+** ... MATCH 'first place'</codeblock>
+**
+** the tokenizer offers both "1st" and "first" as synonyms for the
** first token in the MATCH query and FTS5 effectively runs a query
-** similar to:
-**
-** <codeblock>
-** ... MATCH '(first OR 1st) place'</codeblock>
-**
-** except that, for the purposes of auxiliary functions, the query
+** similar to:
+**
+** <codeblock>
+** ... MATCH '(first OR 1st) place'</codeblock>
+**
+** except that, for the purposes of auxiliary functions, the query
** still appears to contain just two phrases - "(first OR 1st)"
-** being treated as a single phrase.
-**
-** <li> By adding multiple synonyms for a single term to the FTS index.
-** Using this method, when tokenizing document text, the tokenizer
+** being treated as a single phrase.
+**
+** <li> By adding multiple synonyms for a single term to the FTS index.
+** Using this method, when tokenizing document text, the tokenizer
** provides multiple synonyms for each token. So that when a
-** document such as "I won first place" is tokenized, entries are
-** added to the FTS index for "i", "won", "first", "1st" and
-** "place".
-**
-** This way, even if the tokenizer does not provide synonyms
+** document such as "I won first place" is tokenized, entries are
+** added to the FTS index for "i", "won", "first", "1st" and
+** "place".
+**
+** This way, even if the tokenizer does not provide synonyms
** when tokenizing query text (it should not - to do so would be
** inefficient), it doesn't matter if the user queries for
** 'first + place' or '1st + place', as there are entries in the
-** FTS index corresponding to both forms of the first token.
-** </ol>
-**
-** Whether it is parsing document or query text, any call to xToken that
-** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
-** is considered to supply a synonym for the previous token. For example,
-** when parsing the document "I won first place", a tokenizer that supports
-** synonyms would call xToken() 5 times, as follows:
-**
-** <codeblock>
-** xToken(pCtx, 0, "i", 1, 0, 1);
-** xToken(pCtx, 0, "won", 3, 2, 5);
-** xToken(pCtx, 0, "first", 5, 6, 11);
-** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
-** xToken(pCtx, 0, "place", 5, 12, 17);
-**</codeblock>
-**
-** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
-** xToken() is called. Multiple synonyms may be specified for a single token
+** FTS index corresponding to both forms of the first token.
+** </ol>
+**
+** Whether it is parsing document or query text, any call to xToken that
+** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
+** is considered to supply a synonym for the previous token. For example,
+** when parsing the document "I won first place", a tokenizer that supports
+** synonyms would call xToken() 5 times, as follows:
+**
+** <codeblock>
+** xToken(pCtx, 0, "i", 1, 0, 1);
+** xToken(pCtx, 0, "won", 3, 2, 5);
+** xToken(pCtx, 0, "first", 5, 6, 11);
+** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
+** xToken(pCtx, 0, "place", 5, 12, 17);
+**</codeblock>
+**
+** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
+** xToken() is called. Multiple synonyms may be specified for a single token
** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence.
-** There is no limit to the number of synonyms that may be provided for a
-** single token.
-**
+** There is no limit to the number of synonyms that may be provided for a
+** single token.
+**
** In many cases, method (1) above is the best approach. It does not add
-** extra data to the FTS index or require FTS5 to query for multiple terms,
-** so it is efficient in terms of disk space and query speed. However, it
-** does not support prefix queries very well. If, as suggested above, the
+** extra data to the FTS index or require FTS5 to query for multiple terms,
+** so it is efficient in terms of disk space and query speed. However, it
+** does not support prefix queries very well. If, as suggested above, the
** token "first" is substituted for "1st" by the tokenizer, then the query:
-**
-** <codeblock>
-** ... MATCH '1s*'</codeblock>
-**
-** will not match documents that contain the token "1st" (as the tokenizer
-** will probably not map "1s" to any prefix of "first").
-**
+**
+** <codeblock>
+** ... MATCH '1s*'</codeblock>
+**
+** will not match documents that contain the token "1st" (as the tokenizer
+** will probably not map "1s" to any prefix of "first").
+**
** For full prefix support, method (3) may be preferred. In this case,
-** because the index contains entries for both "first" and "1st", prefix
-** queries such as 'fi*' or '1s*' will match correctly. However, because
-** extra entries are added to the FTS index, this method uses more space
-** within the database.
-**
-** Method (2) offers a midpoint between (1) and (3). Using this method,
+** because the index contains entries for both "first" and "1st", prefix
+** queries such as 'fi*' or '1s*' will match correctly. However, because
+** extra entries are added to the FTS index, this method uses more space
+** within the database.
+**
+** Method (2) offers a midpoint between (1) and (3). Using this method,
** a query such as '1s*' will match documents that contain the literal
-** token "1st", but not "first" (assuming the tokenizer is not able to
-** provide synonyms for prefixes). However, a non-prefix query like '1st'
-** will match against "1st" and "first". This method does not require
+** token "1st", but not "first" (assuming the tokenizer is not able to
+** provide synonyms for prefixes). However, a non-prefix query like '1st'
+** will match against "1st" and "first". This method does not require
** extra disk space, as no extra entries are added to the FTS index.
-** On the other hand, it may require more CPU cycles to run MATCH queries,
-** as separate queries of the FTS index are required for each synonym.
-**
-** When using methods (2) or (3), it is important that the tokenizer only
-** provide synonyms when tokenizing document text (method (2)) or query
-** text (method (3)), not both. Doing so will not cause any errors, but is
-** inefficient.
-*/
-typedef struct Fts5Tokenizer Fts5Tokenizer;
-typedef struct fts5_tokenizer fts5_tokenizer;
-struct fts5_tokenizer {
- int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
- void (*xDelete)(Fts5Tokenizer*);
+** On the other hand, it may require more CPU cycles to run MATCH queries,
+** as separate queries of the FTS index are required for each synonym.
+**
+** When using methods (2) or (3), it is important that the tokenizer only
+** provide synonyms when tokenizing document text (method (2)) or query
+** text (method (3)), not both. Doing so will not cause any errors, but is
+** inefficient.
+*/
+typedef struct Fts5Tokenizer Fts5Tokenizer;
+typedef struct fts5_tokenizer fts5_tokenizer;
+struct fts5_tokenizer {
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
+ void (*xDelete)(Fts5Tokenizer*);
int (*xTokenize)(Fts5Tokenizer*,
- void *pCtx,
- int flags, /* Mask of FTS5_TOKENIZE_* flags */
+ void *pCtx,
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
const char *pText, int nText,
- int (*xToken)(
- void *pCtx, /* Copy of 2nd argument to xTokenize() */
- int tflags, /* Mask of FTS5_TOKEN_* flags */
- const char *pToken, /* Pointer to buffer containing token */
- int nToken, /* Size of token in bytes */
- int iStart, /* Byte offset of token within input text */
- int iEnd /* Byte offset of end of token within input text */
- )
- );
-};
-
-/* Flags that may be passed as the third argument to xTokenize() */
-#define FTS5_TOKENIZE_QUERY 0x0001
-#define FTS5_TOKENIZE_PREFIX 0x0002
-#define FTS5_TOKENIZE_DOCUMENT 0x0004
-#define FTS5_TOKENIZE_AUX 0x0008
-
-/* Flags that may be passed by the tokenizer implementation back to FTS5
-** as the third argument to the supplied xToken callback. */
-#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
-
-/*
-** END OF CUSTOM TOKENIZERS
-*************************************************************************/
-
-/*************************************************************************
-** FTS5 EXTENSION REGISTRATION API
-*/
-typedef struct fts5_api fts5_api;
-struct fts5_api {
- int iVersion; /* Currently always set to 2 */
-
- /* Create a new tokenizer */
- int (*xCreateTokenizer)(
- fts5_api *pApi,
- const char *zName,
- void *pContext,
- fts5_tokenizer *pTokenizer,
- void (*xDestroy)(void*)
- );
-
- /* Find an existing tokenizer */
- int (*xFindTokenizer)(
- fts5_api *pApi,
- const char *zName,
- void **ppContext,
- fts5_tokenizer *pTokenizer
- );
-
- /* Create a new auxiliary function */
- int (*xCreateFunction)(
- fts5_api *pApi,
- const char *zName,
- void *pContext,
- fts5_extension_function xFunction,
- void (*xDestroy)(void*)
- );
-};
-
-/*
-** END OF REGISTRATION API
-*************************************************************************/
-
-#ifdef __cplusplus
-} /* end of the 'extern "C"' block */
-#endif
-
-#endif /* _FTS5_H */
-
-/******** End of fts5.h *********/
+ int (*xToken)(
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Pointer to buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Byte offset of token within input text */
+ int iEnd /* Byte offset of end of token within input text */
+ )
+ );
+};
+
+/* Flags that may be passed as the third argument to xTokenize() */
+#define FTS5_TOKENIZE_QUERY 0x0001
+#define FTS5_TOKENIZE_PREFIX 0x0002
+#define FTS5_TOKENIZE_DOCUMENT 0x0004
+#define FTS5_TOKENIZE_AUX 0x0008
+
+/* Flags that may be passed by the tokenizer implementation back to FTS5
+** as the third argument to the supplied xToken callback. */
+#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
+
+/*
+** END OF CUSTOM TOKENIZERS
+*************************************************************************/
+
+/*************************************************************************
+** FTS5 EXTENSION REGISTRATION API
+*/
+typedef struct fts5_api fts5_api;
+struct fts5_api {
+ int iVersion; /* Currently always set to 2 */
+
+ /* Create a new tokenizer */
+ int (*xCreateTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_tokenizer *pTokenizer,
+ void (*xDestroy)(void*)
+ );
+
+ /* Find an existing tokenizer */
+ int (*xFindTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void **ppContext,
+ fts5_tokenizer *pTokenizer
+ );
+
+ /* Create a new auxiliary function */
+ int (*xCreateFunction)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_extension_function xFunction,
+ void (*xDestroy)(void*)
+ );
+};
+
+/*
+** END OF REGISTRATION API
+*************************************************************************/
+
+#ifdef __cplusplus
+} /* end of the 'extern "C"' block */
+#endif
+
+#endif /* _FTS5_H */
+
+/******** End of fts5.h *********/
diff --git a/contrib/libs/sqlite3/sqlite3ext.h b/contrib/libs/sqlite3/sqlite3ext.h
index 572d3e15b6d..9767daa01da 100644
--- a/contrib/libs/sqlite3/sqlite3ext.h
+++ b/contrib/libs/sqlite3/sqlite3ext.h
@@ -15,8 +15,8 @@
** as extensions by SQLite should #include this file instead of
** sqlite3.h.
*/
-#ifndef SQLITE3EXT_H
-#define SQLITE3EXT_H
+#ifndef SQLITE3EXT_H
+#define SQLITE3EXT_H
#include "sqlite3.h"
/*
@@ -134,7 +134,7 @@ struct sqlite3_api_routines {
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
const char*,const char*),void*);
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
- char * (*xsnprintf)(int,char*,const char*,...);
+ char * (*xsnprintf)(int,char*,const char*,...);
int (*step)(sqlite3_stmt*);
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
char const**,char const**,int*,int*,int*);
@@ -246,7 +246,7 @@ struct sqlite3_api_routines {
int (*uri_boolean)(const char*,const char*,int);
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
const char *(*uri_parameter)(const char*,const char*);
- char *(*xvsnprintf)(int,char*,const char*,va_list);
+ char *(*xvsnprintf)(int,char*,const char*,va_list);
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
/* Version 3.8.7 and later */
int (*auto_extension)(void(*)(void));
@@ -270,31 +270,31 @@ struct sqlite3_api_routines {
void (*value_free)(sqlite3_value*);
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
- /* Version 3.9.0 and later */
- unsigned int (*value_subtype)(sqlite3_value*);
- void (*result_subtype)(sqlite3_context*,unsigned int);
- /* Version 3.10.0 and later */
- int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
- int (*strlike)(const char*,const char*,unsigned int);
- int (*db_cacheflush)(sqlite3*);
- /* Version 3.12.0 and later */
- int (*system_errno)(sqlite3*);
- /* Version 3.14.0 and later */
- int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
- char *(*expanded_sql)(sqlite3_stmt*);
- /* Version 3.18.0 and later */
- void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
- /* Version 3.20.0 and later */
- int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
- sqlite3_stmt**,const char**);
- int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
- sqlite3_stmt**,const void**);
- int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
- void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
- void *(*value_pointer)(sqlite3_value*,const char*);
- int (*vtab_nochange)(sqlite3_context*);
- int (*value_nochange)(sqlite3_value*);
- const char *(*vtab_collation)(sqlite3_index_info*,int);
+ /* Version 3.9.0 and later */
+ unsigned int (*value_subtype)(sqlite3_value*);
+ void (*result_subtype)(sqlite3_context*,unsigned int);
+ /* Version 3.10.0 and later */
+ int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
+ int (*strlike)(const char*,const char*,unsigned int);
+ int (*db_cacheflush)(sqlite3*);
+ /* Version 3.12.0 and later */
+ int (*system_errno)(sqlite3*);
+ /* Version 3.14.0 and later */
+ int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
+ char *(*expanded_sql)(sqlite3_stmt*);
+ /* Version 3.18.0 and later */
+ void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
+ /* Version 3.20.0 and later */
+ int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
+ sqlite3_stmt**,const char**);
+ int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
+ sqlite3_stmt**,const void**);
+ int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
+ void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
+ void *(*value_pointer)(sqlite3_value*,const char*);
+ int (*vtab_nochange)(sqlite3_context*);
+ int (*value_nochange)(sqlite3_value*);
+ const char *(*vtab_collation)(sqlite3_index_info*,int);
/* Version 3.24.0 and later */
int (*keyword_count)(void);
int (*keyword_name)(int,const char**,int*);
@@ -347,16 +347,16 @@ struct sqlite3_api_routines {
};
/*
-** This is the function signature used for all extension entry points. It
-** is also defined in the file "loadext.c".
-*/
-typedef int (*sqlite3_loadext_entry)(
- sqlite3 *db, /* Handle to the database. */
- char **pzErrMsg, /* Used to set error string on failure. */
- const sqlite3_api_routines *pThunk /* Extension API function pointers. */
-);
-
-/*
+** This is the function signature used for all extension entry points. It
+** is also defined in the file "loadext.c".
+*/
+typedef int (*sqlite3_loadext_entry)(
+ sqlite3 *db, /* Handle to the database. */
+ char **pzErrMsg, /* Used to set error string on failure. */
+ const sqlite3_api_routines *pThunk /* Extension API function pointers. */
+);
+
+/*
** The following macros redefine the API routines so that they are
** redirected through the global sqlite3_api structure.
**
@@ -367,7 +367,7 @@ typedef int (*sqlite3_loadext_entry)(
** the API. So the redefinition macros are only valid if the
** SQLITE_CORE macros is undefined.
*/
-#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
@@ -470,7 +470,7 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
-#define sqlite3_snprintf sqlite3_api->xsnprintf
+#define sqlite3_snprintf sqlite3_api->xsnprintf
#define sqlite3_step sqlite3_api->step
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
@@ -494,7 +494,7 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
-#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
+#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
@@ -570,7 +570,7 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
#define sqlite3_uri_int64 sqlite3_api->uri_int64
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
-#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
+#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
/* Version 3.8.7 and later */
#define sqlite3_auto_extension sqlite3_api->auto_extension
@@ -590,28 +590,28 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_value_free sqlite3_api->value_free
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
-/* Version 3.9.0 and later */
-#define sqlite3_value_subtype sqlite3_api->value_subtype
-#define sqlite3_result_subtype sqlite3_api->result_subtype
-/* Version 3.10.0 and later */
-#define sqlite3_status64 sqlite3_api->status64
-#define sqlite3_strlike sqlite3_api->strlike
-#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
-/* Version 3.12.0 and later */
-#define sqlite3_system_errno sqlite3_api->system_errno
-/* Version 3.14.0 and later */
-#define sqlite3_trace_v2 sqlite3_api->trace_v2
-#define sqlite3_expanded_sql sqlite3_api->expanded_sql
-/* Version 3.18.0 and later */
-#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
-/* Version 3.20.0 and later */
-#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
-#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
-#define sqlite3_bind_pointer sqlite3_api->bind_pointer
-#define sqlite3_result_pointer sqlite3_api->result_pointer
-#define sqlite3_value_pointer sqlite3_api->value_pointer
-/* Version 3.22.0 and later */
-#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
+/* Version 3.9.0 and later */
+#define sqlite3_value_subtype sqlite3_api->value_subtype
+#define sqlite3_result_subtype sqlite3_api->result_subtype
+/* Version 3.10.0 and later */
+#define sqlite3_status64 sqlite3_api->status64
+#define sqlite3_strlike sqlite3_api->strlike
+#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
+/* Version 3.12.0 and later */
+#define sqlite3_system_errno sqlite3_api->system_errno
+/* Version 3.14.0 and later */
+#define sqlite3_trace_v2 sqlite3_api->trace_v2
+#define sqlite3_expanded_sql sqlite3_api->expanded_sql
+/* Version 3.18.0 and later */
+#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
+/* Version 3.20.0 and later */
+#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
+#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
+#define sqlite3_bind_pointer sqlite3_api->bind_pointer
+#define sqlite3_result_pointer sqlite3_api->result_pointer
+#define sqlite3_value_pointer sqlite3_api->value_pointer
+/* Version 3.22.0 and later */
+#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
#define sqlite3_value_nochange sqlite3_api->value_nochange
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
/* Version 3.24.0 and later */
@@ -655,9 +655,9 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_total_changes64 sqlite3_api->total_changes64
/* Version 3.37.0 and later */
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
-#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
-#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
/* This case when the file really is being compiled as a loadable
** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
@@ -672,4 +672,4 @@ typedef int (*sqlite3_loadext_entry)(
# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif
-#endif /* SQLITE3EXT_H */
+#endif /* SQLITE3EXT_H */
diff --git a/contrib/libs/sqlite3/test_multiplex.c b/contrib/libs/sqlite3/test_multiplex.c
index 1c88c595436..1e185a95a2e 100644
--- a/contrib/libs/sqlite3/test_multiplex.c
+++ b/contrib/libs/sqlite3/test_multiplex.c
@@ -1,967 +1,967 @@
+/*
+** 2010 October 28
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This file contains a VFS "shim" - a layer that sits in between the
+** pager and the real VFS - that breaks up a very large database file
+** into two or more smaller files on disk. This is useful, for example,
+** in order to support large, multi-gigabyte databases on older filesystems
+** that limit the maximum file size to 2 GiB.
+**
+** USAGE:
+**
+** Compile this source file and link it with your application. Then
+** at start-time, invoke the following procedure:
+**
+** int sqlite3_multiplex_initialize(
+** const char *zOrigVfsName, // The underlying real VFS
+** int makeDefault // True to make multiplex the default VFS
+** );
+**
+** The procedure call above will create and register a new VFS shim named
+** "multiplex". The multiplex VFS will use the VFS named by zOrigVfsName to
+** do the actual disk I/O. (The zOrigVfsName parameter may be NULL, in
+** which case the default VFS at the moment sqlite3_multiplex_initialize()
+** is called will be used as the underlying real VFS.)
+**
+** If the makeDefault parameter is TRUE then multiplex becomes the new
+** default VFS. Otherwise, you can use the multiplex VFS by specifying
+** "multiplex" as the 4th parameter to sqlite3_open_v2() or by employing
+** URI filenames and adding "vfs=multiplex" as a parameter to the filename
+** URI.
+**
+** The multiplex VFS allows databases up to 32 GiB in size. But it splits
+** the files up into smaller pieces, so that they will work even on
+** filesystems that do not support large files. The default chunk size
+** is 2147418112 bytes (which is 64KiB less than 2GiB) but this can be
+** changed at compile-time by defining the SQLITE_MULTIPLEX_CHUNK_SIZE
+** macro. Use the "chunksize=NNNN" query parameter with a URI filename
+** in order to select an alternative chunk size for individual connections
+** at run-time.
+*/
+#include "sqlite3.h"
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include "test_multiplex.h"
+
+#ifndef SQLITE_CORE
+ #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
+#endif
+#include "sqlite3ext.h"
+
/*
-** 2010 October 28
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains a VFS "shim" - a layer that sits in between the
-** pager and the real VFS - that breaks up a very large database file
-** into two or more smaller files on disk. This is useful, for example,
-** in order to support large, multi-gigabyte databases on older filesystems
-** that limit the maximum file size to 2 GiB.
-**
-** USAGE:
-**
-** Compile this source file and link it with your application. Then
-** at start-time, invoke the following procedure:
-**
-** int sqlite3_multiplex_initialize(
-** const char *zOrigVfsName, // The underlying real VFS
-** int makeDefault // True to make multiplex the default VFS
-** );
-**
-** The procedure call above will create and register a new VFS shim named
-** "multiplex". The multiplex VFS will use the VFS named by zOrigVfsName to
-** do the actual disk I/O. (The zOrigVfsName parameter may be NULL, in
-** which case the default VFS at the moment sqlite3_multiplex_initialize()
-** is called will be used as the underlying real VFS.)
-**
-** If the makeDefault parameter is TRUE then multiplex becomes the new
-** default VFS. Otherwise, you can use the multiplex VFS by specifying
-** "multiplex" as the 4th parameter to sqlite3_open_v2() or by employing
-** URI filenames and adding "vfs=multiplex" as a parameter to the filename
-** URI.
-**
-** The multiplex VFS allows databases up to 32 GiB in size. But it splits
-** the files up into smaller pieces, so that they will work even on
-** filesystems that do not support large files. The default chunk size
-** is 2147418112 bytes (which is 64KiB less than 2GiB) but this can be
-** changed at compile-time by defining the SQLITE_MULTIPLEX_CHUNK_SIZE
-** macro. Use the "chunksize=NNNN" query parameter with a URI filename
-** in order to select an alternative chunk size for individual connections
-** at run-time.
-*/
-#include "sqlite3.h"
-#include <string.h>
-#include <assert.h>
-#include <stdlib.h>
-#include "test_multiplex.h"
-
-#ifndef SQLITE_CORE
- #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
-#endif
-#include "sqlite3ext.h"
-
-/*
-** These should be defined to be the same as the values in
-** sqliteInt.h. They are defined separately here so that
-** the multiplex VFS shim can be built as a loadable
-** module.
-*/
-#define UNUSED_PARAMETER(x) (void)(x)
-#define MAX_PAGE_SIZE 0x10000
-#define DEFAULT_SECTOR_SIZE 0x1000
-
-/* Maximum chunk number */
-#define MX_CHUNK_NUMBER 299
-
-/* First chunk for rollback journal files */
-#define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400
-#define SQLITE_MULTIPLEX_WAL_8_3_OFFSET 700
-
-
-/************************ Shim Definitions ******************************/
-
-#ifndef SQLITE_MULTIPLEX_VFS_NAME
-# define SQLITE_MULTIPLEX_VFS_NAME "multiplex"
-#endif
-
-/* This is the limit on the chunk size. It may be changed by calling
-** the xFileControl() interface. It will be rounded up to a
-** multiple of MAX_PAGE_SIZE. We default it here to 2GiB less 64KiB.
-*/
-#ifndef SQLITE_MULTIPLEX_CHUNK_SIZE
-# define SQLITE_MULTIPLEX_CHUNK_SIZE 2147418112
-#endif
-
-/* This used to be the default limit on number of chunks, but
-** it is no longer enforced. There is currently no limit to the
-** number of chunks.
-**
-** May be changed by calling the xFileControl() interface.
-*/
-#ifndef SQLITE_MULTIPLEX_MAX_CHUNKS
-# define SQLITE_MULTIPLEX_MAX_CHUNKS 12
-#endif
-
-/************************ Object Definitions ******************************/
-
-/* Forward declaration of all object types */
-typedef struct multiplexGroup multiplexGroup;
-typedef struct multiplexConn multiplexConn;
-
-/*
-** A "multiplex group" is a collection of files that collectively
-** makeup a single SQLite DB file. This allows the size of the DB
-** to exceed the limits imposed by the file system.
-**
-** There is an instance of the following object for each defined multiplex
-** group.
-*/
-struct multiplexGroup {
- struct multiplexReal { /* For each chunk */
- sqlite3_file *p; /* Handle for the chunk */
- char *z; /* Name of this chunk */
- } *aReal; /* list of all chunks */
- int nReal; /* Number of chunks */
- char *zName; /* Base filename of this group */
- int nName; /* Length of base filename */
- int flags; /* Flags used for original opening */
- unsigned int szChunk; /* Chunk size used for this group */
- unsigned char bEnabled; /* TRUE to use Multiplex VFS for this file */
- unsigned char bTruncate; /* TRUE to enable truncation of databases */
-};
-
-/*
-** An instance of the following object represents each open connection
-** to a file that is multiplex'ed. This object is a
-** subclass of sqlite3_file. The sqlite3_file object for the underlying
-** VFS is appended to this structure.
-*/
-struct multiplexConn {
- sqlite3_file base; /* Base class - must be first */
- multiplexGroup *pGroup; /* The underlying group of files */
-};
-
-/************************* Global Variables **********************************/
-/*
-** All global variables used by this file are containing within the following
-** gMultiplex structure.
-*/
-static struct {
- /* The pOrigVfs is the real, original underlying VFS implementation.
- ** Most operations pass-through to the real VFS. This value is read-only
- ** during operation. It is only modified at start-time and thus does not
- ** require a mutex.
- */
- sqlite3_vfs *pOrigVfs;
-
- /* The sThisVfs is the VFS structure used by this shim. It is initialized
- ** at start-time and thus does not require a mutex
- */
- sqlite3_vfs sThisVfs;
-
- /* The sIoMethods defines the methods used by sqlite3_file objects
- ** associated with this shim. It is initialized at start-time and does
- ** not require a mutex.
- **
- ** When the underlying VFS is called to open a file, it might return
- ** either a version 1 or a version 2 sqlite3_file object. This shim
- ** has to create a wrapper sqlite3_file of the same version. Hence
- ** there are two I/O method structures, one for version 1 and the other
- ** for version 2.
- */
- sqlite3_io_methods sIoMethodsV1;
- sqlite3_io_methods sIoMethodsV2;
-
- /* True when this shim has been initialized.
- */
- int isInitialized;
-} gMultiplex;
-
-/************************* Utility Routines *********************************/
-/*
-** Compute a string length that is limited to what can be stored in
-** lower 30 bits of a 32-bit signed integer.
-**
-** The value returned will never be negative. Nor will it ever be greater
-** than the actual length of the string. For very long strings (greater
-** than 1GiB) the value returned might be less than the true string length.
-*/
-static int multiplexStrlen30(const char *z){
- const char *z2 = z;
- if( z==0 ) return 0;
- while( *z2 ){ z2++; }
- return 0x3fffffff & (int)(z2 - z);
-}
-
-/*
-** Generate the file-name for chunk iChunk of the group with base name
-** zBase. The file-name is written to buffer zOut before returning. Buffer
-** zOut must be allocated by the caller so that it is at least (nBase+5)
-** bytes in size, where nBase is the length of zBase, not including the
-** nul-terminator.
-**
-** If iChunk is 0 (or 400 - the number for the first journal file chunk),
-** the output is a copy of the input string. Otherwise, if
-** SQLITE_ENABLE_8_3_NAMES is not defined or the input buffer does not contain
-** a "." character, then the output is a copy of the input string with the
-** three-digit zero-padded decimal representation if iChunk appended to it.
-** For example:
-**
-** zBase="test.db", iChunk=4 -> zOut="test.db004"
-**
-** Or, if SQLITE_ENABLE_8_3_NAMES is defined and the input buffer contains
-** a "." character, then everything after the "." is replaced by the
-** three-digit representation of iChunk.
-**
-** zBase="test.db", iChunk=4 -> zOut="test.004"
-**
-** The output buffer string is terminated by 2 0x00 bytes. This makes it safe
-** to pass to sqlite3_uri_parameter() and similar.
-*/
-static void multiplexFilename(
- const char *zBase, /* Filename for chunk 0 */
- int nBase, /* Size of zBase in bytes (without \0) */
- int flags, /* Flags used to open file */
- int iChunk, /* Chunk to generate filename for */
- char *zOut /* Buffer to write generated name to */
-){
- int n = nBase;
- memcpy(zOut, zBase, n+1);
- if( iChunk!=0 && iChunk<=MX_CHUNK_NUMBER ){
-#ifdef SQLITE_ENABLE_8_3_NAMES
- int i;
- for(i=n-1; i>0 && i>=n-4 && zOut[i]!='.'; i--){}
- if( i>=n-4 ) n = i+1;
- if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
- /* The extensions on overflow files for main databases are 001, 002,
- ** 003 and so forth. To avoid name collisions, add 400 to the
- ** extensions of journal files so that they are 401, 402, 403, ....
- */
- iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET;
- }else if( flags & SQLITE_OPEN_WAL ){
- /* To avoid name collisions, add 700 to the
- ** extensions of WAL files so that they are 701, 702, 703, ....
- */
- iChunk += SQLITE_MULTIPLEX_WAL_8_3_OFFSET;
- }
-#endif
- sqlite3_snprintf(4,&zOut[n],"%03d",iChunk);
- n += 3;
- }
-
- assert( zOut[n]=='\0' );
- zOut[n+1] = '\0';
-}
-
-/* Compute the filename for the iChunk-th chunk
-*/
-static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){
- if( iChunk>=pGroup->nReal ){
- struct multiplexReal *p;
- p = sqlite3_realloc64(pGroup->aReal, (iChunk+1)*sizeof(*p));
- if( p==0 ){
- return SQLITE_NOMEM;
- }
- memset(&p[pGroup->nReal], 0, sizeof(p[0])*(iChunk+1-pGroup->nReal));
- pGroup->aReal = p;
- pGroup->nReal = iChunk+1;
- }
- if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){
- char *z;
- int n = pGroup->nName;
+** These should be defined to be the same as the values in
+** sqliteInt.h. They are defined separately here so that
+** the multiplex VFS shim can be built as a loadable
+** module.
+*/
+#define UNUSED_PARAMETER(x) (void)(x)
+#define MAX_PAGE_SIZE 0x10000
+#define DEFAULT_SECTOR_SIZE 0x1000
+
+/* Maximum chunk number */
+#define MX_CHUNK_NUMBER 299
+
+/* First chunk for rollback journal files */
+#define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400
+#define SQLITE_MULTIPLEX_WAL_8_3_OFFSET 700
+
+
+/************************ Shim Definitions ******************************/
+
+#ifndef SQLITE_MULTIPLEX_VFS_NAME
+# define SQLITE_MULTIPLEX_VFS_NAME "multiplex"
+#endif
+
+/* This is the limit on the chunk size. It may be changed by calling
+** the xFileControl() interface. It will be rounded up to a
+** multiple of MAX_PAGE_SIZE. We default it here to 2GiB less 64KiB.
+*/
+#ifndef SQLITE_MULTIPLEX_CHUNK_SIZE
+# define SQLITE_MULTIPLEX_CHUNK_SIZE 2147418112
+#endif
+
+/* This used to be the default limit on number of chunks, but
+** it is no longer enforced. There is currently no limit to the
+** number of chunks.
+**
+** May be changed by calling the xFileControl() interface.
+*/
+#ifndef SQLITE_MULTIPLEX_MAX_CHUNKS
+# define SQLITE_MULTIPLEX_MAX_CHUNKS 12
+#endif
+
+/************************ Object Definitions ******************************/
+
+/* Forward declaration of all object types */
+typedef struct multiplexGroup multiplexGroup;
+typedef struct multiplexConn multiplexConn;
+
+/*
+** A "multiplex group" is a collection of files that collectively
+** makeup a single SQLite DB file. This allows the size of the DB
+** to exceed the limits imposed by the file system.
+**
+** There is an instance of the following object for each defined multiplex
+** group.
+*/
+struct multiplexGroup {
+ struct multiplexReal { /* For each chunk */
+ sqlite3_file *p; /* Handle for the chunk */
+ char *z; /* Name of this chunk */
+ } *aReal; /* list of all chunks */
+ int nReal; /* Number of chunks */
+ char *zName; /* Base filename of this group */
+ int nName; /* Length of base filename */
+ int flags; /* Flags used for original opening */
+ unsigned int szChunk; /* Chunk size used for this group */
+ unsigned char bEnabled; /* TRUE to use Multiplex VFS for this file */
+ unsigned char bTruncate; /* TRUE to enable truncation of databases */
+};
+
+/*
+** An instance of the following object represents each open connection
+** to a file that is multiplex'ed. This object is a
+** subclass of sqlite3_file. The sqlite3_file object for the underlying
+** VFS is appended to this structure.
+*/
+struct multiplexConn {
+ sqlite3_file base; /* Base class - must be first */
+ multiplexGroup *pGroup; /* The underlying group of files */
+};
+
+/************************* Global Variables **********************************/
+/*
+** All global variables used by this file are containing within the following
+** gMultiplex structure.
+*/
+static struct {
+ /* The pOrigVfs is the real, original underlying VFS implementation.
+ ** Most operations pass-through to the real VFS. This value is read-only
+ ** during operation. It is only modified at start-time and thus does not
+ ** require a mutex.
+ */
+ sqlite3_vfs *pOrigVfs;
+
+ /* The sThisVfs is the VFS structure used by this shim. It is initialized
+ ** at start-time and thus does not require a mutex
+ */
+ sqlite3_vfs sThisVfs;
+
+ /* The sIoMethods defines the methods used by sqlite3_file objects
+ ** associated with this shim. It is initialized at start-time and does
+ ** not require a mutex.
+ **
+ ** When the underlying VFS is called to open a file, it might return
+ ** either a version 1 or a version 2 sqlite3_file object. This shim
+ ** has to create a wrapper sqlite3_file of the same version. Hence
+ ** there are two I/O method structures, one for version 1 and the other
+ ** for version 2.
+ */
+ sqlite3_io_methods sIoMethodsV1;
+ sqlite3_io_methods sIoMethodsV2;
+
+ /* True when this shim has been initialized.
+ */
+ int isInitialized;
+} gMultiplex;
+
+/************************* Utility Routines *********************************/
+/*
+** Compute a string length that is limited to what can be stored in
+** lower 30 bits of a 32-bit signed integer.
+**
+** The value returned will never be negative. Nor will it ever be greater
+** than the actual length of the string. For very long strings (greater
+** than 1GiB) the value returned might be less than the true string length.
+*/
+static int multiplexStrlen30(const char *z){
+ const char *z2 = z;
+ if( z==0 ) return 0;
+ while( *z2 ){ z2++; }
+ return 0x3fffffff & (int)(z2 - z);
+}
+
+/*
+** Generate the file-name for chunk iChunk of the group with base name
+** zBase. The file-name is written to buffer zOut before returning. Buffer
+** zOut must be allocated by the caller so that it is at least (nBase+5)
+** bytes in size, where nBase is the length of zBase, not including the
+** nul-terminator.
+**
+** If iChunk is 0 (or 400 - the number for the first journal file chunk),
+** the output is a copy of the input string. Otherwise, if
+** SQLITE_ENABLE_8_3_NAMES is not defined or the input buffer does not contain
+** a "." character, then the output is a copy of the input string with the
+** three-digit zero-padded decimal representation if iChunk appended to it.
+** For example:
+**
+** zBase="test.db", iChunk=4 -> zOut="test.db004"
+**
+** Or, if SQLITE_ENABLE_8_3_NAMES is defined and the input buffer contains
+** a "." character, then everything after the "." is replaced by the
+** three-digit representation of iChunk.
+**
+** zBase="test.db", iChunk=4 -> zOut="test.004"
+**
+** The output buffer string is terminated by 2 0x00 bytes. This makes it safe
+** to pass to sqlite3_uri_parameter() and similar.
+*/
+static void multiplexFilename(
+ const char *zBase, /* Filename for chunk 0 */
+ int nBase, /* Size of zBase in bytes (without \0) */
+ int flags, /* Flags used to open file */
+ int iChunk, /* Chunk to generate filename for */
+ char *zOut /* Buffer to write generated name to */
+){
+ int n = nBase;
+ memcpy(zOut, zBase, n+1);
+ if( iChunk!=0 && iChunk<=MX_CHUNK_NUMBER ){
+#ifdef SQLITE_ENABLE_8_3_NAMES
+ int i;
+ for(i=n-1; i>0 && i>=n-4 && zOut[i]!='.'; i--){}
+ if( i>=n-4 ) n = i+1;
+ if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
+ /* The extensions on overflow files for main databases are 001, 002,
+ ** 003 and so forth. To avoid name collisions, add 400 to the
+ ** extensions of journal files so that they are 401, 402, 403, ....
+ */
+ iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET;
+ }else if( flags & SQLITE_OPEN_WAL ){
+ /* To avoid name collisions, add 700 to the
+ ** extensions of WAL files so that they are 701, 702, 703, ....
+ */
+ iChunk += SQLITE_MULTIPLEX_WAL_8_3_OFFSET;
+ }
+#endif
+ sqlite3_snprintf(4,&zOut[n],"%03d",iChunk);
+ n += 3;
+ }
+
+ assert( zOut[n]=='\0' );
+ zOut[n+1] = '\0';
+}
+
+/* Compute the filename for the iChunk-th chunk
+*/
+static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){
+ if( iChunk>=pGroup->nReal ){
+ struct multiplexReal *p;
+ p = sqlite3_realloc64(pGroup->aReal, (iChunk+1)*sizeof(*p));
+ if( p==0 ){
+ return SQLITE_NOMEM;
+ }
+ memset(&p[pGroup->nReal], 0, sizeof(p[0])*(iChunk+1-pGroup->nReal));
+ pGroup->aReal = p;
+ pGroup->nReal = iChunk+1;
+ }
+ if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){
+ char *z;
+ int n = pGroup->nName;
z = sqlite3_malloc64( n+5 );
- if( z==0 ){
- return SQLITE_NOMEM;
- }
- multiplexFilename(pGroup->zName, pGroup->nName, pGroup->flags, iChunk, z);
+ if( z==0 ){
+ return SQLITE_NOMEM;
+ }
+ multiplexFilename(pGroup->zName, pGroup->nName, pGroup->flags, iChunk, z);
pGroup->aReal[iChunk].z = sqlite3_create_filename(z,"","",0,0);
sqlite3_free(z);
if( pGroup->aReal[iChunk].z==0 ) return SQLITE_NOMEM;
- }
- return SQLITE_OK;
-}
-
-/* Translate an sqlite3_file* that is really a multiplexGroup* into
-** the sqlite3_file* for the underlying original VFS.
-**
-** For chunk 0, the pGroup->flags determines whether or not a new file
-** is created if it does not already exist. For chunks 1 and higher, the
-** file is created only if createFlag is 1.
-*/
-static sqlite3_file *multiplexSubOpen(
- multiplexGroup *pGroup, /* The multiplexor group */
- int iChunk, /* Which chunk to open. 0==original file */
- int *rc, /* Result code in and out */
- int *pOutFlags, /* Output flags */
- int createFlag /* True to create if iChunk>0 */
-){
- sqlite3_file *pSubOpen = 0;
- sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */
-
-#ifdef SQLITE_ENABLE_8_3_NAMES
- /* If JOURNAL_8_3_OFFSET is set to (say) 400, then any overflow files are
- ** part of a database journal are named db.401, db.402, and so on. A
- ** database may therefore not grow to larger than 400 chunks. Attempting
- ** to open chunk 401 indicates the database is full. */
- if( iChunk>=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){
- sqlite3_log(SQLITE_FULL, "multiplexed chunk overflow: %s", pGroup->zName);
- *rc = SQLITE_FULL;
- return 0;
- }
-#endif
-
- *rc = multiplexSubFilename(pGroup, iChunk);
- if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){
- int flags, bExists;
- flags = pGroup->flags;
- if( createFlag ){
- flags |= SQLITE_OPEN_CREATE;
- }else if( iChunk==0 ){
- /* Fall through */
- }else if( pGroup->aReal[iChunk].z==0 ){
- return 0;
- }else{
- *rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[iChunk].z,
- SQLITE_ACCESS_EXISTS, &bExists);
- if( *rc || !bExists ){
- if( *rc ){
- sqlite3_log(*rc, "multiplexor.xAccess failure on %s",
- pGroup->aReal[iChunk].z);
- }
- return 0;
- }
- flags &= ~SQLITE_OPEN_CREATE;
- }
- pSubOpen = sqlite3_malloc64( pOrigVfs->szOsFile );
- if( pSubOpen==0 ){
- *rc = SQLITE_IOERR_NOMEM;
- return 0;
- }
- pGroup->aReal[iChunk].p = pSubOpen;
- *rc = pOrigVfs->xOpen(pOrigVfs, pGroup->aReal[iChunk].z, pSubOpen,
- flags, pOutFlags);
- if( (*rc)!=SQLITE_OK ){
- sqlite3_log(*rc, "multiplexor.xOpen failure on %s",
- pGroup->aReal[iChunk].z);
- sqlite3_free(pSubOpen);
- pGroup->aReal[iChunk].p = 0;
- return 0;
- }
- }
- return pSubOpen;
-}
-
-/*
-** Return the size, in bytes, of chunk number iChunk. If that chunk
-** does not exist, then return 0. This function does not distingish between
-** non-existant files and zero-length files.
-*/
-static sqlite3_int64 multiplexSubSize(
- multiplexGroup *pGroup, /* The multiplexor group */
- int iChunk, /* Which chunk to open. 0==original file */
- int *rc /* Result code in and out */
-){
- sqlite3_file *pSub;
- sqlite3_int64 sz = 0;
-
- if( *rc ) return 0;
- pSub = multiplexSubOpen(pGroup, iChunk, rc, NULL, 0);
- if( pSub==0 ) return 0;
- *rc = pSub->pMethods->xFileSize(pSub, &sz);
- return sz;
-}
-
-/*
-** This is the implementation of the multiplex_control() SQL function.
-*/
-static void multiplexControlFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int rc = SQLITE_OK;
- sqlite3 *db = sqlite3_context_db_handle(context);
- int op = 0;
- int iVal;
-
- if( !db || argc!=2 ){
- rc = SQLITE_ERROR;
- }else{
- /* extract params */
- op = sqlite3_value_int(argv[0]);
- iVal = sqlite3_value_int(argv[1]);
- /* map function op to file_control op */
- switch( op ){
- case 1:
- op = MULTIPLEX_CTRL_ENABLE;
- break;
- case 2:
- op = MULTIPLEX_CTRL_SET_CHUNK_SIZE;
- break;
- case 3:
- op = MULTIPLEX_CTRL_SET_MAX_CHUNKS;
- break;
- default:
- rc = SQLITE_NOTFOUND;
- break;
- }
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3_file_control(db, 0, op, &iVal);
- }
- sqlite3_result_error_code(context, rc);
-}
-
-/*
-** This is the entry point to register the auto-extension for the
-** multiplex_control() function.
-*/
-static int multiplexFuncInit(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- int rc;
- rc = sqlite3_create_function(db, "multiplex_control", 2, SQLITE_ANY,
- 0, multiplexControlFunc, 0, 0);
- return rc;
-}
-
-/*
-** Close a single sub-file in the connection group.
-*/
-static void multiplexSubClose(
- multiplexGroup *pGroup,
- int iChunk,
- sqlite3_vfs *pOrigVfs
-){
- sqlite3_file *pSubOpen = pGroup->aReal[iChunk].p;
- if( pSubOpen ){
- pSubOpen->pMethods->xClose(pSubOpen);
- if( pOrigVfs && pGroup->aReal[iChunk].z ){
- pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0);
- }
- sqlite3_free(pGroup->aReal[iChunk].p);
- }
+ }
+ return SQLITE_OK;
+}
+
+/* Translate an sqlite3_file* that is really a multiplexGroup* into
+** the sqlite3_file* for the underlying original VFS.
+**
+** For chunk 0, the pGroup->flags determines whether or not a new file
+** is created if it does not already exist. For chunks 1 and higher, the
+** file is created only if createFlag is 1.
+*/
+static sqlite3_file *multiplexSubOpen(
+ multiplexGroup *pGroup, /* The multiplexor group */
+ int iChunk, /* Which chunk to open. 0==original file */
+ int *rc, /* Result code in and out */
+ int *pOutFlags, /* Output flags */
+ int createFlag /* True to create if iChunk>0 */
+){
+ sqlite3_file *pSubOpen = 0;
+ sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */
+
+#ifdef SQLITE_ENABLE_8_3_NAMES
+ /* If JOURNAL_8_3_OFFSET is set to (say) 400, then any overflow files are
+ ** part of a database journal are named db.401, db.402, and so on. A
+ ** database may therefore not grow to larger than 400 chunks. Attempting
+ ** to open chunk 401 indicates the database is full. */
+ if( iChunk>=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){
+ sqlite3_log(SQLITE_FULL, "multiplexed chunk overflow: %s", pGroup->zName);
+ *rc = SQLITE_FULL;
+ return 0;
+ }
+#endif
+
+ *rc = multiplexSubFilename(pGroup, iChunk);
+ if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){
+ int flags, bExists;
+ flags = pGroup->flags;
+ if( createFlag ){
+ flags |= SQLITE_OPEN_CREATE;
+ }else if( iChunk==0 ){
+ /* Fall through */
+ }else if( pGroup->aReal[iChunk].z==0 ){
+ return 0;
+ }else{
+ *rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[iChunk].z,
+ SQLITE_ACCESS_EXISTS, &bExists);
+ if( *rc || !bExists ){
+ if( *rc ){
+ sqlite3_log(*rc, "multiplexor.xAccess failure on %s",
+ pGroup->aReal[iChunk].z);
+ }
+ return 0;
+ }
+ flags &= ~SQLITE_OPEN_CREATE;
+ }
+ pSubOpen = sqlite3_malloc64( pOrigVfs->szOsFile );
+ if( pSubOpen==0 ){
+ *rc = SQLITE_IOERR_NOMEM;
+ return 0;
+ }
+ pGroup->aReal[iChunk].p = pSubOpen;
+ *rc = pOrigVfs->xOpen(pOrigVfs, pGroup->aReal[iChunk].z, pSubOpen,
+ flags, pOutFlags);
+ if( (*rc)!=SQLITE_OK ){
+ sqlite3_log(*rc, "multiplexor.xOpen failure on %s",
+ pGroup->aReal[iChunk].z);
+ sqlite3_free(pSubOpen);
+ pGroup->aReal[iChunk].p = 0;
+ return 0;
+ }
+ }
+ return pSubOpen;
+}
+
+/*
+** Return the size, in bytes, of chunk number iChunk. If that chunk
+** does not exist, then return 0. This function does not distingish between
+** non-existant files and zero-length files.
+*/
+static sqlite3_int64 multiplexSubSize(
+ multiplexGroup *pGroup, /* The multiplexor group */
+ int iChunk, /* Which chunk to open. 0==original file */
+ int *rc /* Result code in and out */
+){
+ sqlite3_file *pSub;
+ sqlite3_int64 sz = 0;
+
+ if( *rc ) return 0;
+ pSub = multiplexSubOpen(pGroup, iChunk, rc, NULL, 0);
+ if( pSub==0 ) return 0;
+ *rc = pSub->pMethods->xFileSize(pSub, &sz);
+ return sz;
+}
+
+/*
+** This is the implementation of the multiplex_control() SQL function.
+*/
+static void multiplexControlFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int rc = SQLITE_OK;
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ int op = 0;
+ int iVal;
+
+ if( !db || argc!=2 ){
+ rc = SQLITE_ERROR;
+ }else{
+ /* extract params */
+ op = sqlite3_value_int(argv[0]);
+ iVal = sqlite3_value_int(argv[1]);
+ /* map function op to file_control op */
+ switch( op ){
+ case 1:
+ op = MULTIPLEX_CTRL_ENABLE;
+ break;
+ case 2:
+ op = MULTIPLEX_CTRL_SET_CHUNK_SIZE;
+ break;
+ case 3:
+ op = MULTIPLEX_CTRL_SET_MAX_CHUNKS;
+ break;
+ default:
+ rc = SQLITE_NOTFOUND;
+ break;
+ }
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_file_control(db, 0, op, &iVal);
+ }
+ sqlite3_result_error_code(context, rc);
+}
+
+/*
+** This is the entry point to register the auto-extension for the
+** multiplex_control() function.
+*/
+static int multiplexFuncInit(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ int rc;
+ rc = sqlite3_create_function(db, "multiplex_control", 2, SQLITE_ANY,
+ 0, multiplexControlFunc, 0, 0);
+ return rc;
+}
+
+/*
+** Close a single sub-file in the connection group.
+*/
+static void multiplexSubClose(
+ multiplexGroup *pGroup,
+ int iChunk,
+ sqlite3_vfs *pOrigVfs
+){
+ sqlite3_file *pSubOpen = pGroup->aReal[iChunk].p;
+ if( pSubOpen ){
+ pSubOpen->pMethods->xClose(pSubOpen);
+ if( pOrigVfs && pGroup->aReal[iChunk].z ){
+ pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0);
+ }
+ sqlite3_free(pGroup->aReal[iChunk].p);
+ }
sqlite3_free_filename(pGroup->aReal[iChunk].z);
- memset(&pGroup->aReal[iChunk], 0, sizeof(pGroup->aReal[iChunk]));
-}
-
-/*
-** Deallocate memory held by a multiplexGroup
-*/
-static void multiplexFreeComponents(multiplexGroup *pGroup){
- int i;
- for(i=0; i<pGroup->nReal; i++){ multiplexSubClose(pGroup, i, 0); }
- sqlite3_free(pGroup->aReal);
- pGroup->aReal = 0;
- pGroup->nReal = 0;
-}
-
-
-/************************* VFS Method Wrappers *****************************/
-
-/*
-** This is the xOpen method used for the "multiplex" VFS.
-**
-** Most of the work is done by the underlying original VFS. This method
-** simply links the new file into the appropriate multiplex group if it is a
-** file that needs to be tracked.
-*/
-static int multiplexOpen(
- sqlite3_vfs *pVfs, /* The multiplex VFS */
- const char *zName, /* Name of file to be opened */
- sqlite3_file *pConn, /* Fill in this file descriptor */
- int flags, /* Flags to control the opening */
- int *pOutFlags /* Flags showing results of opening */
-){
- int rc = SQLITE_OK; /* Result code */
- multiplexConn *pMultiplexOpen; /* The new multiplex file descriptor */
- multiplexGroup *pGroup = 0; /* Corresponding multiplexGroup object */
- sqlite3_file *pSubOpen = 0; /* Real file descriptor */
- sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */
- int nName = 0;
- int sz = 0;
- char *zToFree = 0;
-
- UNUSED_PARAMETER(pVfs);
- memset(pConn, 0, pVfs->szOsFile);
- assert( zName || (flags & SQLITE_OPEN_DELETEONCLOSE) );
-
- /* We need to create a group structure and manage
- ** access to this group of files.
- */
- pMultiplexOpen = (multiplexConn*)pConn;
-
- if( rc==SQLITE_OK ){
- /* allocate space for group */
- nName = zName ? multiplexStrlen30(zName) : 0;
- sz = sizeof(multiplexGroup) /* multiplexGroup */
- + nName + 1; /* zName */
- pGroup = sqlite3_malloc64( sz );
- if( pGroup==0 ){
- rc = SQLITE_NOMEM;
- }
- }
-
- if( rc==SQLITE_OK ){
- const char *zUri = (flags & SQLITE_OPEN_URI) ? zName : 0;
- /* assign pointers to extra space allocated */
- memset(pGroup, 0, sz);
- pMultiplexOpen->pGroup = pGroup;
- pGroup->bEnabled = (unsigned char)-1;
- pGroup->bTruncate = (unsigned char)sqlite3_uri_boolean(zUri, "truncate",
- (flags & SQLITE_OPEN_MAIN_DB)==0);
- pGroup->szChunk = (int)sqlite3_uri_int64(zUri, "chunksize",
- SQLITE_MULTIPLEX_CHUNK_SIZE);
- pGroup->szChunk = (pGroup->szChunk+0xffff)&~0xffff;
- if( zName ){
- char *p = (char *)&pGroup[1];
- pGroup->zName = p;
- memcpy(pGroup->zName, zName, nName+1);
- pGroup->nName = nName;
- }
- if( pGroup->bEnabled ){
- /* Make sure that the chunksize is such that the pending byte does not
- ** falls at the end of a chunk. A region of up to 64K following
- ** the pending byte is never written, so if the pending byte occurs
- ** near the end of a chunk, that chunk will be too small. */
-#ifndef SQLITE_OMIT_WSD
- extern int sqlite3PendingByte;
-#else
- int sqlite3PendingByte = 0x40000000;
-#endif
- while( (sqlite3PendingByte % pGroup->szChunk)>=(pGroup->szChunk-65536) ){
- pGroup->szChunk += 65536;
- }
- }
+ memset(&pGroup->aReal[iChunk], 0, sizeof(pGroup->aReal[iChunk]));
+}
+
+/*
+** Deallocate memory held by a multiplexGroup
+*/
+static void multiplexFreeComponents(multiplexGroup *pGroup){
+ int i;
+ for(i=0; i<pGroup->nReal; i++){ multiplexSubClose(pGroup, i, 0); }
+ sqlite3_free(pGroup->aReal);
+ pGroup->aReal = 0;
+ pGroup->nReal = 0;
+}
+
+
+/************************* VFS Method Wrappers *****************************/
+
+/*
+** This is the xOpen method used for the "multiplex" VFS.
+**
+** Most of the work is done by the underlying original VFS. This method
+** simply links the new file into the appropriate multiplex group if it is a
+** file that needs to be tracked.
+*/
+static int multiplexOpen(
+ sqlite3_vfs *pVfs, /* The multiplex VFS */
+ const char *zName, /* Name of file to be opened */
+ sqlite3_file *pConn, /* Fill in this file descriptor */
+ int flags, /* Flags to control the opening */
+ int *pOutFlags /* Flags showing results of opening */
+){
+ int rc = SQLITE_OK; /* Result code */
+ multiplexConn *pMultiplexOpen; /* The new multiplex file descriptor */
+ multiplexGroup *pGroup = 0; /* Corresponding multiplexGroup object */
+ sqlite3_file *pSubOpen = 0; /* Real file descriptor */
+ sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */
+ int nName = 0;
+ int sz = 0;
+ char *zToFree = 0;
+
+ UNUSED_PARAMETER(pVfs);
+ memset(pConn, 0, pVfs->szOsFile);
+ assert( zName || (flags & SQLITE_OPEN_DELETEONCLOSE) );
+
+ /* We need to create a group structure and manage
+ ** access to this group of files.
+ */
+ pMultiplexOpen = (multiplexConn*)pConn;
+
+ if( rc==SQLITE_OK ){
+ /* allocate space for group */
+ nName = zName ? multiplexStrlen30(zName) : 0;
+ sz = sizeof(multiplexGroup) /* multiplexGroup */
+ + nName + 1; /* zName */
+ pGroup = sqlite3_malloc64( sz );
+ if( pGroup==0 ){
+ rc = SQLITE_NOMEM;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ const char *zUri = (flags & SQLITE_OPEN_URI) ? zName : 0;
+ /* assign pointers to extra space allocated */
+ memset(pGroup, 0, sz);
+ pMultiplexOpen->pGroup = pGroup;
+ pGroup->bEnabled = (unsigned char)-1;
+ pGroup->bTruncate = (unsigned char)sqlite3_uri_boolean(zUri, "truncate",
+ (flags & SQLITE_OPEN_MAIN_DB)==0);
+ pGroup->szChunk = (int)sqlite3_uri_int64(zUri, "chunksize",
+ SQLITE_MULTIPLEX_CHUNK_SIZE);
+ pGroup->szChunk = (pGroup->szChunk+0xffff)&~0xffff;
+ if( zName ){
+ char *p = (char *)&pGroup[1];
+ pGroup->zName = p;
+ memcpy(pGroup->zName, zName, nName+1);
+ pGroup->nName = nName;
+ }
+ if( pGroup->bEnabled ){
+ /* Make sure that the chunksize is such that the pending byte does not
+ ** falls at the end of a chunk. A region of up to 64K following
+ ** the pending byte is never written, so if the pending byte occurs
+ ** near the end of a chunk, that chunk will be too small. */
+#ifndef SQLITE_OMIT_WSD
+ extern int sqlite3PendingByte;
+#else
+ int sqlite3PendingByte = 0x40000000;
+#endif
+ while( (sqlite3PendingByte % pGroup->szChunk)>=(pGroup->szChunk-65536) ){
+ pGroup->szChunk += 65536;
+ }
+ }
pGroup->flags = (flags & ~SQLITE_OPEN_URI);
- rc = multiplexSubFilename(pGroup, 1);
- if( rc==SQLITE_OK ){
- pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags, 0);
- if( pSubOpen==0 && rc==SQLITE_OK ) rc = SQLITE_CANTOPEN;
- }
- if( rc==SQLITE_OK ){
- sqlite3_int64 sz64;
-
- rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz64);
- if( rc==SQLITE_OK && zName ){
- int bExists;
+ rc = multiplexSubFilename(pGroup, 1);
+ if( rc==SQLITE_OK ){
+ pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags, 0);
+ if( pSubOpen==0 && rc==SQLITE_OK ) rc = SQLITE_CANTOPEN;
+ }
+ if( rc==SQLITE_OK ){
+ sqlite3_int64 sz64;
+
+ rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz64);
+ if( rc==SQLITE_OK && zName ){
+ int bExists;
if( flags & SQLITE_OPEN_SUPER_JOURNAL ){
- pGroup->bEnabled = 0;
- }else
- if( sz64==0 ){
- if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
- /* If opening a main journal file and the first chunk is zero
- ** bytes in size, delete any subsequent chunks from the
- ** file-system. */
- int iChunk = 1;
- do {
- rc = pOrigVfs->xAccess(pOrigVfs,
- pGroup->aReal[iChunk].z, SQLITE_ACCESS_EXISTS, &bExists
- );
- if( rc==SQLITE_OK && bExists ){
- rc = pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0);
- if( rc==SQLITE_OK ){
- rc = multiplexSubFilename(pGroup, ++iChunk);
- }
- }
- }while( rc==SQLITE_OK && bExists );
- }
- }else{
- /* If the first overflow file exists and if the size of the main file
- ** is different from the chunk size, that means the chunk size is set
- ** set incorrectly. So fix it.
- **
- ** Or, if the first overflow file does not exist and the main file is
- ** larger than the chunk size, that means the chunk size is too small.
- ** But we have no way of determining the intended chunk size, so
- ** just disable the multiplexor all togethre.
- */
- rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z,
- SQLITE_ACCESS_EXISTS, &bExists);
- bExists = multiplexSubSize(pGroup, 1, &rc)>0;
- if( rc==SQLITE_OK && bExists && sz64==(sz64&0xffff0000) && sz64>0
- && sz64!=pGroup->szChunk ){
- pGroup->szChunk = (int)sz64;
- }else if( rc==SQLITE_OK && !bExists && sz64>pGroup->szChunk ){
- pGroup->bEnabled = 0;
- }
- }
- }
- }
-
- if( rc==SQLITE_OK ){
- if( pSubOpen->pMethods->iVersion==1 ){
+ pGroup->bEnabled = 0;
+ }else
+ if( sz64==0 ){
+ if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
+ /* If opening a main journal file and the first chunk is zero
+ ** bytes in size, delete any subsequent chunks from the
+ ** file-system. */
+ int iChunk = 1;
+ do {
+ rc = pOrigVfs->xAccess(pOrigVfs,
+ pGroup->aReal[iChunk].z, SQLITE_ACCESS_EXISTS, &bExists
+ );
+ if( rc==SQLITE_OK && bExists ){
+ rc = pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0);
+ if( rc==SQLITE_OK ){
+ rc = multiplexSubFilename(pGroup, ++iChunk);
+ }
+ }
+ }while( rc==SQLITE_OK && bExists );
+ }
+ }else{
+ /* If the first overflow file exists and if the size of the main file
+ ** is different from the chunk size, that means the chunk size is set
+ ** set incorrectly. So fix it.
+ **
+ ** Or, if the first overflow file does not exist and the main file is
+ ** larger than the chunk size, that means the chunk size is too small.
+ ** But we have no way of determining the intended chunk size, so
+ ** just disable the multiplexor all togethre.
+ */
+ rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z,
+ SQLITE_ACCESS_EXISTS, &bExists);
+ bExists = multiplexSubSize(pGroup, 1, &rc)>0;
+ if( rc==SQLITE_OK && bExists && sz64==(sz64&0xffff0000) && sz64>0
+ && sz64!=pGroup->szChunk ){
+ pGroup->szChunk = (int)sz64;
+ }else if( rc==SQLITE_OK && !bExists && sz64>pGroup->szChunk ){
+ pGroup->bEnabled = 0;
+ }
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ if( pSubOpen->pMethods->iVersion==1 ){
pConn->pMethods = &gMultiplex.sIoMethodsV1;
- }else{
+ }else{
pConn->pMethods = &gMultiplex.sIoMethodsV2;
- }
- }else{
- multiplexFreeComponents(pGroup);
- sqlite3_free(pGroup);
- }
- }
- sqlite3_free(zToFree);
- return rc;
-}
-
-/*
-** This is the xDelete method used for the "multiplex" VFS.
-** It attempts to delete the filename specified.
-*/
-static int multiplexDelete(
- sqlite3_vfs *pVfs, /* The multiplex VFS */
- const char *zName, /* Name of file to delete */
- int syncDir
-){
- int rc;
- sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */
- rc = pOrigVfs->xDelete(pOrigVfs, zName, syncDir);
- if( rc==SQLITE_OK ){
- /* If the main chunk was deleted successfully, also delete any subsequent
- ** chunks - starting with the last (highest numbered).
- */
- int nName = (int)strlen(zName);
- char *z;
- z = sqlite3_malloc64(nName + 5);
- if( z==0 ){
- rc = SQLITE_IOERR_NOMEM;
- }else{
- int iChunk = 0;
- int bExists;
- do{
- multiplexFilename(zName, nName, SQLITE_OPEN_MAIN_JOURNAL, ++iChunk, z);
- rc = pOrigVfs->xAccess(pOrigVfs, z, SQLITE_ACCESS_EXISTS, &bExists);
- }while( rc==SQLITE_OK && bExists );
- while( rc==SQLITE_OK && iChunk>1 ){
- multiplexFilename(zName, nName, SQLITE_OPEN_MAIN_JOURNAL, --iChunk, z);
- rc = pOrigVfs->xDelete(pOrigVfs, z, syncDir);
- }
- if( rc==SQLITE_OK ){
- iChunk = 0;
- do{
- multiplexFilename(zName, nName, SQLITE_OPEN_WAL, ++iChunk, z);
- rc = pOrigVfs->xAccess(pOrigVfs, z, SQLITE_ACCESS_EXISTS, &bExists);
- }while( rc==SQLITE_OK && bExists );
- while( rc==SQLITE_OK && iChunk>1 ){
- multiplexFilename(zName, nName, SQLITE_OPEN_WAL, --iChunk, z);
- rc = pOrigVfs->xDelete(pOrigVfs, z, syncDir);
- }
- }
- }
- sqlite3_free(z);
- }
- return rc;
-}
-
-static int multiplexAccess(sqlite3_vfs *a, const char *b, int c, int *d){
- return gMultiplex.pOrigVfs->xAccess(gMultiplex.pOrigVfs, b, c, d);
-}
-static int multiplexFullPathname(sqlite3_vfs *a, const char *b, int c, char *d){
- return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, b, c, d);
-}
-static void *multiplexDlOpen(sqlite3_vfs *a, const char *b){
- return gMultiplex.pOrigVfs->xDlOpen(gMultiplex.pOrigVfs, b);
-}
-static void multiplexDlError(sqlite3_vfs *a, int b, char *c){
- gMultiplex.pOrigVfs->xDlError(gMultiplex.pOrigVfs, b, c);
-}
-static void (*multiplexDlSym(sqlite3_vfs *a, void *b, const char *c))(void){
- return gMultiplex.pOrigVfs->xDlSym(gMultiplex.pOrigVfs, b, c);
-}
-static void multiplexDlClose(sqlite3_vfs *a, void *b){
- gMultiplex.pOrigVfs->xDlClose(gMultiplex.pOrigVfs, b);
-}
-static int multiplexRandomness(sqlite3_vfs *a, int b, char *c){
- return gMultiplex.pOrigVfs->xRandomness(gMultiplex.pOrigVfs, b, c);
-}
-static int multiplexSleep(sqlite3_vfs *a, int b){
- return gMultiplex.pOrigVfs->xSleep(gMultiplex.pOrigVfs, b);
-}
-static int multiplexCurrentTime(sqlite3_vfs *a, double *b){
- return gMultiplex.pOrigVfs->xCurrentTime(gMultiplex.pOrigVfs, b);
-}
-static int multiplexGetLastError(sqlite3_vfs *a, int b, char *c){
- if( gMultiplex.pOrigVfs->xGetLastError ){
- return gMultiplex.pOrigVfs->xGetLastError(gMultiplex.pOrigVfs, b, c);
- }else{
- return 0;
- }
-}
-static int multiplexCurrentTimeInt64(sqlite3_vfs *a, sqlite3_int64 *b){
- return gMultiplex.pOrigVfs->xCurrentTimeInt64(gMultiplex.pOrigVfs, b);
-}
-
-/************************ I/O Method Wrappers *******************************/
-
-/* xClose requests get passed through to the original VFS.
-** We loop over all open chunk handles and close them.
-** The group structure for this file is unlinked from
-** our list of groups and freed.
-*/
-static int multiplexClose(sqlite3_file *pConn){
- multiplexConn *p = (multiplexConn*)pConn;
- multiplexGroup *pGroup = p->pGroup;
- int rc = SQLITE_OK;
- multiplexFreeComponents(pGroup);
- sqlite3_free(pGroup);
- return rc;
-}
-
-/* Pass xRead requests thru to the original VFS after
-** determining the correct chunk to operate on.
-** Break up reads across chunk boundaries.
-*/
-static int multiplexRead(
- sqlite3_file *pConn,
- void *pBuf,
- int iAmt,
- sqlite3_int64 iOfst
-){
- multiplexConn *p = (multiplexConn*)pConn;
- multiplexGroup *pGroup = p->pGroup;
- int rc = SQLITE_OK;
- if( !pGroup->bEnabled ){
- sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
- if( pSubOpen==0 ){
- rc = SQLITE_IOERR_READ;
- }else{
- rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, iOfst);
- }
- }else{
- while( iAmt > 0 ){
- int i = (int)(iOfst / pGroup->szChunk);
- sqlite3_file *pSubOpen;
- pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1);
- if( pSubOpen ){
- int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk;
- if( extra<0 ) extra = 0;
- iAmt -= extra;
- rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt,
- iOfst % pGroup->szChunk);
- if( rc!=SQLITE_OK ) break;
- pBuf = (char *)pBuf + iAmt;
- iOfst += iAmt;
- iAmt = extra;
- }else{
- rc = SQLITE_IOERR_READ;
- break;
- }
- }
- }
-
- return rc;
-}
-
-/* Pass xWrite requests thru to the original VFS after
-** determining the correct chunk to operate on.
-** Break up writes across chunk boundaries.
-*/
-static int multiplexWrite(
- sqlite3_file *pConn,
- const void *pBuf,
- int iAmt,
- sqlite3_int64 iOfst
-){
- multiplexConn *p = (multiplexConn*)pConn;
- multiplexGroup *pGroup = p->pGroup;
- int rc = SQLITE_OK;
- if( !pGroup->bEnabled ){
- sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
- if( pSubOpen==0 ){
- rc = SQLITE_IOERR_WRITE;
- }else{
- rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst);
- }
- }else{
- while( rc==SQLITE_OK && iAmt>0 ){
- int i = (int)(iOfst / pGroup->szChunk);
- sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1);
- if( pSubOpen ){
- int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) -
- pGroup->szChunk;
- if( extra<0 ) extra = 0;
- iAmt -= extra;
- rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt,
- iOfst % pGroup->szChunk);
- pBuf = (char *)pBuf + iAmt;
- iOfst += iAmt;
- iAmt = extra;
- }
- }
- }
- return rc;
-}
-
-/* Pass xTruncate requests thru to the original VFS after
-** determining the correct chunk to operate on. Delete any
-** chunks above the truncate mark.
-*/
-static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){
- multiplexConn *p = (multiplexConn*)pConn;
- multiplexGroup *pGroup = p->pGroup;
- int rc = SQLITE_OK;
- if( !pGroup->bEnabled ){
- sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
- if( pSubOpen==0 ){
- rc = SQLITE_IOERR_TRUNCATE;
- }else{
- rc = pSubOpen->pMethods->xTruncate(pSubOpen, size);
- }
- }else{
- int i;
- int iBaseGroup = (int)(size / pGroup->szChunk);
- sqlite3_file *pSubOpen;
- sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */
- /* delete the chunks above the truncate limit */
- for(i = pGroup->nReal-1; i>iBaseGroup && rc==SQLITE_OK; i--){
- if( pGroup->bTruncate ){
- multiplexSubClose(pGroup, i, pOrigVfs);
- }else{
- pSubOpen = multiplexSubOpen(pGroup, i, &rc, 0, 0);
- if( pSubOpen ){
- rc = pSubOpen->pMethods->xTruncate(pSubOpen, 0);
- }
- }
- }
- if( rc==SQLITE_OK ){
- pSubOpen = multiplexSubOpen(pGroup, iBaseGroup, &rc, 0, 0);
- if( pSubOpen ){
- rc = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk);
- }
- }
- if( rc ) rc = SQLITE_IOERR_TRUNCATE;
- }
- return rc;
-}
-
-/* Pass xSync requests through to the original VFS without change
-*/
-static int multiplexSync(sqlite3_file *pConn, int flags){
- multiplexConn *p = (multiplexConn*)pConn;
- multiplexGroup *pGroup = p->pGroup;
- int rc = SQLITE_OK;
- int i;
- for(i=0; i<pGroup->nReal; i++){
- sqlite3_file *pSubOpen = pGroup->aReal[i].p;
- if( pSubOpen ){
- int rc2 = pSubOpen->pMethods->xSync(pSubOpen, flags);
- if( rc2!=SQLITE_OK ) rc = rc2;
- }
- }
- return rc;
-}
-
-/* Pass xFileSize requests through to the original VFS.
-** Aggregate the size of all the chunks before returning.
-*/
-static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){
- multiplexConn *p = (multiplexConn*)pConn;
- multiplexGroup *pGroup = p->pGroup;
- int rc = SQLITE_OK;
- int i;
- if( !pGroup->bEnabled ){
- sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
- if( pSubOpen==0 ){
- rc = SQLITE_IOERR_FSTAT;
- }else{
- rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize);
- }
- }else{
- *pSize = 0;
- for(i=0; rc==SQLITE_OK; i++){
- sqlite3_int64 sz = multiplexSubSize(pGroup, i, &rc);
- if( sz==0 ) break;
- *pSize = i*(sqlite3_int64)pGroup->szChunk + sz;
- }
- }
- return rc;
-}
-
-/* Pass xLock requests through to the original VFS unchanged.
-*/
-static int multiplexLock(sqlite3_file *pConn, int lock){
- multiplexConn *p = (multiplexConn*)pConn;
- int rc;
- sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
- if( pSubOpen ){
- return pSubOpen->pMethods->xLock(pSubOpen, lock);
- }
- return SQLITE_BUSY;
-}
-
-/* Pass xUnlock requests through to the original VFS unchanged.
-*/
-static int multiplexUnlock(sqlite3_file *pConn, int lock){
- multiplexConn *p = (multiplexConn*)pConn;
- int rc;
- sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
- if( pSubOpen ){
- return pSubOpen->pMethods->xUnlock(pSubOpen, lock);
- }
- return SQLITE_IOERR_UNLOCK;
-}
-
-/* Pass xCheckReservedLock requests through to the original VFS unchanged.
-*/
-static int multiplexCheckReservedLock(sqlite3_file *pConn, int *pResOut){
- multiplexConn *p = (multiplexConn*)pConn;
- int rc;
- sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
- if( pSubOpen ){
- return pSubOpen->pMethods->xCheckReservedLock(pSubOpen, pResOut);
- }
- return SQLITE_IOERR_CHECKRESERVEDLOCK;
-}
-
-/* Pass xFileControl requests through to the original VFS unchanged,
-** except for any MULTIPLEX_CTRL_* requests here.
-*/
-static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
- multiplexConn *p = (multiplexConn*)pConn;
- multiplexGroup *pGroup = p->pGroup;
- int rc = SQLITE_ERROR;
- sqlite3_file *pSubOpen;
-
- if( !gMultiplex.isInitialized ) return SQLITE_MISUSE;
- switch( op ){
- case MULTIPLEX_CTRL_ENABLE:
- if( pArg ) {
- int bEnabled = *(int *)pArg;
- pGroup->bEnabled = (unsigned char)bEnabled;
- rc = SQLITE_OK;
- }
- break;
- case MULTIPLEX_CTRL_SET_CHUNK_SIZE:
- if( pArg ) {
- unsigned int szChunk = *(unsigned*)pArg;
- if( szChunk<1 ){
- rc = SQLITE_MISUSE;
- }else{
- /* Round up to nearest multiple of MAX_PAGE_SIZE. */
- szChunk = (szChunk + (MAX_PAGE_SIZE-1));
- szChunk &= ~(MAX_PAGE_SIZE-1);
- pGroup->szChunk = szChunk;
- rc = SQLITE_OK;
- }
- }
- break;
- case MULTIPLEX_CTRL_SET_MAX_CHUNKS:
- rc = SQLITE_OK;
- break;
- case SQLITE_FCNTL_SIZE_HINT:
- case SQLITE_FCNTL_CHUNK_SIZE:
- /* no-op these */
- rc = SQLITE_OK;
- break;
- case SQLITE_FCNTL_PRAGMA: {
- char **aFcntl = (char**)pArg;
- /*
- ** EVIDENCE-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA
- ** file control is an array of pointers to strings (char**) in which the
- ** second element of the array is the name of the pragma and the third
- ** element is the argument to the pragma or NULL if the pragma has no
- ** argument.
- */
+ }
+ }else{
+ multiplexFreeComponents(pGroup);
+ sqlite3_free(pGroup);
+ }
+ }
+ sqlite3_free(zToFree);
+ return rc;
+}
+
+/*
+** This is the xDelete method used for the "multiplex" VFS.
+** It attempts to delete the filename specified.
+*/
+static int multiplexDelete(
+ sqlite3_vfs *pVfs, /* The multiplex VFS */
+ const char *zName, /* Name of file to delete */
+ int syncDir
+){
+ int rc;
+ sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */
+ rc = pOrigVfs->xDelete(pOrigVfs, zName, syncDir);
+ if( rc==SQLITE_OK ){
+ /* If the main chunk was deleted successfully, also delete any subsequent
+ ** chunks - starting with the last (highest numbered).
+ */
+ int nName = (int)strlen(zName);
+ char *z;
+ z = sqlite3_malloc64(nName + 5);
+ if( z==0 ){
+ rc = SQLITE_IOERR_NOMEM;
+ }else{
+ int iChunk = 0;
+ int bExists;
+ do{
+ multiplexFilename(zName, nName, SQLITE_OPEN_MAIN_JOURNAL, ++iChunk, z);
+ rc = pOrigVfs->xAccess(pOrigVfs, z, SQLITE_ACCESS_EXISTS, &bExists);
+ }while( rc==SQLITE_OK && bExists );
+ while( rc==SQLITE_OK && iChunk>1 ){
+ multiplexFilename(zName, nName, SQLITE_OPEN_MAIN_JOURNAL, --iChunk, z);
+ rc = pOrigVfs->xDelete(pOrigVfs, z, syncDir);
+ }
+ if( rc==SQLITE_OK ){
+ iChunk = 0;
+ do{
+ multiplexFilename(zName, nName, SQLITE_OPEN_WAL, ++iChunk, z);
+ rc = pOrigVfs->xAccess(pOrigVfs, z, SQLITE_ACCESS_EXISTS, &bExists);
+ }while( rc==SQLITE_OK && bExists );
+ while( rc==SQLITE_OK && iChunk>1 ){
+ multiplexFilename(zName, nName, SQLITE_OPEN_WAL, --iChunk, z);
+ rc = pOrigVfs->xDelete(pOrigVfs, z, syncDir);
+ }
+ }
+ }
+ sqlite3_free(z);
+ }
+ return rc;
+}
+
+static int multiplexAccess(sqlite3_vfs *a, const char *b, int c, int *d){
+ return gMultiplex.pOrigVfs->xAccess(gMultiplex.pOrigVfs, b, c, d);
+}
+static int multiplexFullPathname(sqlite3_vfs *a, const char *b, int c, char *d){
+ return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, b, c, d);
+}
+static void *multiplexDlOpen(sqlite3_vfs *a, const char *b){
+ return gMultiplex.pOrigVfs->xDlOpen(gMultiplex.pOrigVfs, b);
+}
+static void multiplexDlError(sqlite3_vfs *a, int b, char *c){
+ gMultiplex.pOrigVfs->xDlError(gMultiplex.pOrigVfs, b, c);
+}
+static void (*multiplexDlSym(sqlite3_vfs *a, void *b, const char *c))(void){
+ return gMultiplex.pOrigVfs->xDlSym(gMultiplex.pOrigVfs, b, c);
+}
+static void multiplexDlClose(sqlite3_vfs *a, void *b){
+ gMultiplex.pOrigVfs->xDlClose(gMultiplex.pOrigVfs, b);
+}
+static int multiplexRandomness(sqlite3_vfs *a, int b, char *c){
+ return gMultiplex.pOrigVfs->xRandomness(gMultiplex.pOrigVfs, b, c);
+}
+static int multiplexSleep(sqlite3_vfs *a, int b){
+ return gMultiplex.pOrigVfs->xSleep(gMultiplex.pOrigVfs, b);
+}
+static int multiplexCurrentTime(sqlite3_vfs *a, double *b){
+ return gMultiplex.pOrigVfs->xCurrentTime(gMultiplex.pOrigVfs, b);
+}
+static int multiplexGetLastError(sqlite3_vfs *a, int b, char *c){
+ if( gMultiplex.pOrigVfs->xGetLastError ){
+ return gMultiplex.pOrigVfs->xGetLastError(gMultiplex.pOrigVfs, b, c);
+ }else{
+ return 0;
+ }
+}
+static int multiplexCurrentTimeInt64(sqlite3_vfs *a, sqlite3_int64 *b){
+ return gMultiplex.pOrigVfs->xCurrentTimeInt64(gMultiplex.pOrigVfs, b);
+}
+
+/************************ I/O Method Wrappers *******************************/
+
+/* xClose requests get passed through to the original VFS.
+** We loop over all open chunk handles and close them.
+** The group structure for this file is unlinked from
+** our list of groups and freed.
+*/
+static int multiplexClose(sqlite3_file *pConn){
+ multiplexConn *p = (multiplexConn*)pConn;
+ multiplexGroup *pGroup = p->pGroup;
+ int rc = SQLITE_OK;
+ multiplexFreeComponents(pGroup);
+ sqlite3_free(pGroup);
+ return rc;
+}
+
+/* Pass xRead requests thru to the original VFS after
+** determining the correct chunk to operate on.
+** Break up reads across chunk boundaries.
+*/
+static int multiplexRead(
+ sqlite3_file *pConn,
+ void *pBuf,
+ int iAmt,
+ sqlite3_int64 iOfst
+){
+ multiplexConn *p = (multiplexConn*)pConn;
+ multiplexGroup *pGroup = p->pGroup;
+ int rc = SQLITE_OK;
+ if( !pGroup->bEnabled ){
+ sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen==0 ){
+ rc = SQLITE_IOERR_READ;
+ }else{
+ rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, iOfst);
+ }
+ }else{
+ while( iAmt > 0 ){
+ int i = (int)(iOfst / pGroup->szChunk);
+ sqlite3_file *pSubOpen;
+ pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1);
+ if( pSubOpen ){
+ int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk;
+ if( extra<0 ) extra = 0;
+ iAmt -= extra;
+ rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt,
+ iOfst % pGroup->szChunk);
+ if( rc!=SQLITE_OK ) break;
+ pBuf = (char *)pBuf + iAmt;
+ iOfst += iAmt;
+ iAmt = extra;
+ }else{
+ rc = SQLITE_IOERR_READ;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/* Pass xWrite requests thru to the original VFS after
+** determining the correct chunk to operate on.
+** Break up writes across chunk boundaries.
+*/
+static int multiplexWrite(
+ sqlite3_file *pConn,
+ const void *pBuf,
+ int iAmt,
+ sqlite3_int64 iOfst
+){
+ multiplexConn *p = (multiplexConn*)pConn;
+ multiplexGroup *pGroup = p->pGroup;
+ int rc = SQLITE_OK;
+ if( !pGroup->bEnabled ){
+ sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen==0 ){
+ rc = SQLITE_IOERR_WRITE;
+ }else{
+ rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst);
+ }
+ }else{
+ while( rc==SQLITE_OK && iAmt>0 ){
+ int i = (int)(iOfst / pGroup->szChunk);
+ sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1);
+ if( pSubOpen ){
+ int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) -
+ pGroup->szChunk;
+ if( extra<0 ) extra = 0;
+ iAmt -= extra;
+ rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt,
+ iOfst % pGroup->szChunk);
+ pBuf = (char *)pBuf + iAmt;
+ iOfst += iAmt;
+ iAmt = extra;
+ }
+ }
+ }
+ return rc;
+}
+
+/* Pass xTruncate requests thru to the original VFS after
+** determining the correct chunk to operate on. Delete any
+** chunks above the truncate mark.
+*/
+static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){
+ multiplexConn *p = (multiplexConn*)pConn;
+ multiplexGroup *pGroup = p->pGroup;
+ int rc = SQLITE_OK;
+ if( !pGroup->bEnabled ){
+ sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen==0 ){
+ rc = SQLITE_IOERR_TRUNCATE;
+ }else{
+ rc = pSubOpen->pMethods->xTruncate(pSubOpen, size);
+ }
+ }else{
+ int i;
+ int iBaseGroup = (int)(size / pGroup->szChunk);
+ sqlite3_file *pSubOpen;
+ sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */
+ /* delete the chunks above the truncate limit */
+ for(i = pGroup->nReal-1; i>iBaseGroup && rc==SQLITE_OK; i--){
+ if( pGroup->bTruncate ){
+ multiplexSubClose(pGroup, i, pOrigVfs);
+ }else{
+ pSubOpen = multiplexSubOpen(pGroup, i, &rc, 0, 0);
+ if( pSubOpen ){
+ rc = pSubOpen->pMethods->xTruncate(pSubOpen, 0);
+ }
+ }
+ }
+ if( rc==SQLITE_OK ){
+ pSubOpen = multiplexSubOpen(pGroup, iBaseGroup, &rc, 0, 0);
+ if( pSubOpen ){
+ rc = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk);
+ }
+ }
+ if( rc ) rc = SQLITE_IOERR_TRUNCATE;
+ }
+ return rc;
+}
+
+/* Pass xSync requests through to the original VFS without change
+*/
+static int multiplexSync(sqlite3_file *pConn, int flags){
+ multiplexConn *p = (multiplexConn*)pConn;
+ multiplexGroup *pGroup = p->pGroup;
+ int rc = SQLITE_OK;
+ int i;
+ for(i=0; i<pGroup->nReal; i++){
+ sqlite3_file *pSubOpen = pGroup->aReal[i].p;
+ if( pSubOpen ){
+ int rc2 = pSubOpen->pMethods->xSync(pSubOpen, flags);
+ if( rc2!=SQLITE_OK ) rc = rc2;
+ }
+ }
+ return rc;
+}
+
+/* Pass xFileSize requests through to the original VFS.
+** Aggregate the size of all the chunks before returning.
+*/
+static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){
+ multiplexConn *p = (multiplexConn*)pConn;
+ multiplexGroup *pGroup = p->pGroup;
+ int rc = SQLITE_OK;
+ int i;
+ if( !pGroup->bEnabled ){
+ sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen==0 ){
+ rc = SQLITE_IOERR_FSTAT;
+ }else{
+ rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize);
+ }
+ }else{
+ *pSize = 0;
+ for(i=0; rc==SQLITE_OK; i++){
+ sqlite3_int64 sz = multiplexSubSize(pGroup, i, &rc);
+ if( sz==0 ) break;
+ *pSize = i*(sqlite3_int64)pGroup->szChunk + sz;
+ }
+ }
+ return rc;
+}
+
+/* Pass xLock requests through to the original VFS unchanged.
+*/
+static int multiplexLock(sqlite3_file *pConn, int lock){
+ multiplexConn *p = (multiplexConn*)pConn;
+ int rc;
+ sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen ){
+ return pSubOpen->pMethods->xLock(pSubOpen, lock);
+ }
+ return SQLITE_BUSY;
+}
+
+/* Pass xUnlock requests through to the original VFS unchanged.
+*/
+static int multiplexUnlock(sqlite3_file *pConn, int lock){
+ multiplexConn *p = (multiplexConn*)pConn;
+ int rc;
+ sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen ){
+ return pSubOpen->pMethods->xUnlock(pSubOpen, lock);
+ }
+ return SQLITE_IOERR_UNLOCK;
+}
+
+/* Pass xCheckReservedLock requests through to the original VFS unchanged.
+*/
+static int multiplexCheckReservedLock(sqlite3_file *pConn, int *pResOut){
+ multiplexConn *p = (multiplexConn*)pConn;
+ int rc;
+ sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen ){
+ return pSubOpen->pMethods->xCheckReservedLock(pSubOpen, pResOut);
+ }
+ return SQLITE_IOERR_CHECKRESERVEDLOCK;
+}
+
+/* Pass xFileControl requests through to the original VFS unchanged,
+** except for any MULTIPLEX_CTRL_* requests here.
+*/
+static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
+ multiplexConn *p = (multiplexConn*)pConn;
+ multiplexGroup *pGroup = p->pGroup;
+ int rc = SQLITE_ERROR;
+ sqlite3_file *pSubOpen;
+
+ if( !gMultiplex.isInitialized ) return SQLITE_MISUSE;
+ switch( op ){
+ case MULTIPLEX_CTRL_ENABLE:
+ if( pArg ) {
+ int bEnabled = *(int *)pArg;
+ pGroup->bEnabled = (unsigned char)bEnabled;
+ rc = SQLITE_OK;
+ }
+ break;
+ case MULTIPLEX_CTRL_SET_CHUNK_SIZE:
+ if( pArg ) {
+ unsigned int szChunk = *(unsigned*)pArg;
+ if( szChunk<1 ){
+ rc = SQLITE_MISUSE;
+ }else{
+ /* Round up to nearest multiple of MAX_PAGE_SIZE. */
+ szChunk = (szChunk + (MAX_PAGE_SIZE-1));
+ szChunk &= ~(MAX_PAGE_SIZE-1);
+ pGroup->szChunk = szChunk;
+ rc = SQLITE_OK;
+ }
+ }
+ break;
+ case MULTIPLEX_CTRL_SET_MAX_CHUNKS:
+ rc = SQLITE_OK;
+ break;
+ case SQLITE_FCNTL_SIZE_HINT:
+ case SQLITE_FCNTL_CHUNK_SIZE:
+ /* no-op these */
+ rc = SQLITE_OK;
+ break;
+ case SQLITE_FCNTL_PRAGMA: {
+ char **aFcntl = (char**)pArg;
+ /*
+ ** EVIDENCE-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA
+ ** file control is an array of pointers to strings (char**) in which the
+ ** second element of the array is the name of the pragma and the third
+ ** element is the argument to the pragma or NULL if the pragma has no
+ ** argument.
+ */
if( aFcntl[1] && sqlite3_strnicmp(aFcntl[1],"multiplex_",10)==0 ){
sqlite3_int64 sz = 0;
(void)multiplexFileSize(pConn, &sz);
@@ -983,7 +983,7 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
|| sqlite3_stricmp(aFcntl[2], "0")==0 ){
pGroup->bTruncate = 0;
}
- }
+ }
/* EVIDENCE-OF: R-27806-26076 The handler for an SQLITE_FCNTL_PRAGMA
** file control can optionally make the first element of the char**
** argument point to a string obtained from sqlite3_mprintf() or the
@@ -993,13 +993,13 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
aFcntl[0] = sqlite3_mprintf(pGroup->bTruncate ? "on" : "off");
rc = SQLITE_OK;
break;
- }
+ }
/*
** PRAGMA multiplex_enabled;
**
** Return 0 or 1 depending on whether the multiplexor is enabled or
** disabled, respectively.
- */
+ */
if( sqlite3_stricmp(aFcntl[1],"multiplex_enabled")==0 ){
aFcntl[0] = sqlite3_mprintf("%d", pGroup->bEnabled!=0);
rc = SQLITE_OK;
@@ -1035,342 +1035,342 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
rc = SQLITE_OK;
break;
}
- }
- /* If the multiplexor does not handle the pragma, pass it through
- ** into the default case. */
- }
- default:
- pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
- if( pSubOpen ){
- rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg);
- if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
- *(char**)pArg = sqlite3_mprintf("multiplex/%z", *(char**)pArg);
- }
- }
- break;
- }
- return rc;
-}
-
-/* Pass xSectorSize requests through to the original VFS unchanged.
-*/
-static int multiplexSectorSize(sqlite3_file *pConn){
- multiplexConn *p = (multiplexConn*)pConn;
- int rc;
- sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
- if( pSubOpen && pSubOpen->pMethods->xSectorSize ){
- return pSubOpen->pMethods->xSectorSize(pSubOpen);
- }
- return DEFAULT_SECTOR_SIZE;
-}
-
-/* Pass xDeviceCharacteristics requests through to the original VFS unchanged.
-*/
-static int multiplexDeviceCharacteristics(sqlite3_file *pConn){
- multiplexConn *p = (multiplexConn*)pConn;
- int rc;
- sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
- if( pSubOpen ){
- return pSubOpen->pMethods->xDeviceCharacteristics(pSubOpen);
- }
- return 0;
-}
-
-/* Pass xShmMap requests through to the original VFS unchanged.
-*/
-static int multiplexShmMap(
- sqlite3_file *pConn, /* Handle open on database file */
- int iRegion, /* Region to retrieve */
- int szRegion, /* Size of regions */
- int bExtend, /* True to extend file if necessary */
- void volatile **pp /* OUT: Mapped memory */
-){
- multiplexConn *p = (multiplexConn*)pConn;
- int rc;
- sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
- if( pSubOpen ){
- return pSubOpen->pMethods->xShmMap(pSubOpen, iRegion, szRegion, bExtend,pp);
- }
- return SQLITE_IOERR;
-}
-
-/* Pass xShmLock requests through to the original VFS unchanged.
-*/
-static int multiplexShmLock(
- sqlite3_file *pConn, /* Database file holding the shared memory */
- int ofst, /* First lock to acquire or release */
- int n, /* Number of locks to acquire or release */
- int flags /* What to do with the lock */
-){
- multiplexConn *p = (multiplexConn*)pConn;
- int rc;
- sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
- if( pSubOpen ){
- return pSubOpen->pMethods->xShmLock(pSubOpen, ofst, n, flags);
- }
- return SQLITE_BUSY;
-}
-
-/* Pass xShmBarrier requests through to the original VFS unchanged.
-*/
-static void multiplexShmBarrier(sqlite3_file *pConn){
- multiplexConn *p = (multiplexConn*)pConn;
- int rc;
- sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
- if( pSubOpen ){
- pSubOpen->pMethods->xShmBarrier(pSubOpen);
- }
-}
-
-/* Pass xShmUnmap requests through to the original VFS unchanged.
-*/
-static int multiplexShmUnmap(sqlite3_file *pConn, int deleteFlag){
- multiplexConn *p = (multiplexConn*)pConn;
- int rc;
- sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
- if( pSubOpen ){
- return pSubOpen->pMethods->xShmUnmap(pSubOpen, deleteFlag);
- }
- return SQLITE_OK;
-}
-
-/************************** Public Interfaces *****************************/
-/*
-** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize()
-**
-** Use the VFS named zOrigVfsName as the VFS that does the actual work.
-** Use the default if zOrigVfsName==NULL.
-**
-** The multiplex VFS shim is named "multiplex". It will become the default
-** VFS if makeDefault is non-zero.
-**
-** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once
-** during start-up.
-*/
-int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){
- sqlite3_vfs *pOrigVfs;
- if( gMultiplex.isInitialized ) return SQLITE_MISUSE;
- pOrigVfs = sqlite3_vfs_find(zOrigVfsName);
- if( pOrigVfs==0 ) return SQLITE_ERROR;
- assert( pOrigVfs!=&gMultiplex.sThisVfs );
- gMultiplex.isInitialized = 1;
- gMultiplex.pOrigVfs = pOrigVfs;
- gMultiplex.sThisVfs = *pOrigVfs;
- gMultiplex.sThisVfs.szOsFile += sizeof(multiplexConn);
- gMultiplex.sThisVfs.zName = SQLITE_MULTIPLEX_VFS_NAME;
- gMultiplex.sThisVfs.xOpen = multiplexOpen;
- gMultiplex.sThisVfs.xDelete = multiplexDelete;
- gMultiplex.sThisVfs.xAccess = multiplexAccess;
- gMultiplex.sThisVfs.xFullPathname = multiplexFullPathname;
- gMultiplex.sThisVfs.xDlOpen = multiplexDlOpen;
- gMultiplex.sThisVfs.xDlError = multiplexDlError;
- gMultiplex.sThisVfs.xDlSym = multiplexDlSym;
- gMultiplex.sThisVfs.xDlClose = multiplexDlClose;
- gMultiplex.sThisVfs.xRandomness = multiplexRandomness;
- gMultiplex.sThisVfs.xSleep = multiplexSleep;
- gMultiplex.sThisVfs.xCurrentTime = multiplexCurrentTime;
- gMultiplex.sThisVfs.xGetLastError = multiplexGetLastError;
- gMultiplex.sThisVfs.xCurrentTimeInt64 = multiplexCurrentTimeInt64;
-
- gMultiplex.sIoMethodsV1.iVersion = 1;
- gMultiplex.sIoMethodsV1.xClose = multiplexClose;
- gMultiplex.sIoMethodsV1.xRead = multiplexRead;
- gMultiplex.sIoMethodsV1.xWrite = multiplexWrite;
- gMultiplex.sIoMethodsV1.xTruncate = multiplexTruncate;
- gMultiplex.sIoMethodsV1.xSync = multiplexSync;
- gMultiplex.sIoMethodsV1.xFileSize = multiplexFileSize;
- gMultiplex.sIoMethodsV1.xLock = multiplexLock;
- gMultiplex.sIoMethodsV1.xUnlock = multiplexUnlock;
- gMultiplex.sIoMethodsV1.xCheckReservedLock = multiplexCheckReservedLock;
- gMultiplex.sIoMethodsV1.xFileControl = multiplexFileControl;
- gMultiplex.sIoMethodsV1.xSectorSize = multiplexSectorSize;
- gMultiplex.sIoMethodsV1.xDeviceCharacteristics =
- multiplexDeviceCharacteristics;
- gMultiplex.sIoMethodsV2 = gMultiplex.sIoMethodsV1;
- gMultiplex.sIoMethodsV2.iVersion = 2;
- gMultiplex.sIoMethodsV2.xShmMap = multiplexShmMap;
- gMultiplex.sIoMethodsV2.xShmLock = multiplexShmLock;
- gMultiplex.sIoMethodsV2.xShmBarrier = multiplexShmBarrier;
- gMultiplex.sIoMethodsV2.xShmUnmap = multiplexShmUnmap;
- sqlite3_vfs_register(&gMultiplex.sThisVfs, makeDefault);
-
- sqlite3_auto_extension((void(*)(void))multiplexFuncInit);
-
- return SQLITE_OK;
-}
-
-/*
-** CAPI: Shutdown the multiplex system - sqlite3_multiplex_shutdown()
-**
-** All SQLite database connections must be closed before calling this
-** routine.
-**
-** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while
-** shutting down in order to free all remaining multiplex groups.
-*/
-int sqlite3_multiplex_shutdown(int eForce){
- int rc = SQLITE_OK;
- if( gMultiplex.isInitialized==0 ) return SQLITE_MISUSE;
- gMultiplex.isInitialized = 0;
- sqlite3_vfs_unregister(&gMultiplex.sThisVfs);
- memset(&gMultiplex, 0, sizeof(gMultiplex));
- return rc;
-}
-
-/***************************** Test Code ***********************************/
-#ifdef SQLITE_TEST
-#if defined(INCLUDE_SQLITE_TCL_H)
+ }
+ /* If the multiplexor does not handle the pragma, pass it through
+ ** into the default case. */
+ }
+ default:
+ pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen ){
+ rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg);
+ if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
+ *(char**)pArg = sqlite3_mprintf("multiplex/%z", *(char**)pArg);
+ }
+ }
+ break;
+ }
+ return rc;
+}
+
+/* Pass xSectorSize requests through to the original VFS unchanged.
+*/
+static int multiplexSectorSize(sqlite3_file *pConn){
+ multiplexConn *p = (multiplexConn*)pConn;
+ int rc;
+ sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen && pSubOpen->pMethods->xSectorSize ){
+ return pSubOpen->pMethods->xSectorSize(pSubOpen);
+ }
+ return DEFAULT_SECTOR_SIZE;
+}
+
+/* Pass xDeviceCharacteristics requests through to the original VFS unchanged.
+*/
+static int multiplexDeviceCharacteristics(sqlite3_file *pConn){
+ multiplexConn *p = (multiplexConn*)pConn;
+ int rc;
+ sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen ){
+ return pSubOpen->pMethods->xDeviceCharacteristics(pSubOpen);
+ }
+ return 0;
+}
+
+/* Pass xShmMap requests through to the original VFS unchanged.
+*/
+static int multiplexShmMap(
+ sqlite3_file *pConn, /* Handle open on database file */
+ int iRegion, /* Region to retrieve */
+ int szRegion, /* Size of regions */
+ int bExtend, /* True to extend file if necessary */
+ void volatile **pp /* OUT: Mapped memory */
+){
+ multiplexConn *p = (multiplexConn*)pConn;
+ int rc;
+ sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen ){
+ return pSubOpen->pMethods->xShmMap(pSubOpen, iRegion, szRegion, bExtend,pp);
+ }
+ return SQLITE_IOERR;
+}
+
+/* Pass xShmLock requests through to the original VFS unchanged.
+*/
+static int multiplexShmLock(
+ sqlite3_file *pConn, /* Database file holding the shared memory */
+ int ofst, /* First lock to acquire or release */
+ int n, /* Number of locks to acquire or release */
+ int flags /* What to do with the lock */
+){
+ multiplexConn *p = (multiplexConn*)pConn;
+ int rc;
+ sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen ){
+ return pSubOpen->pMethods->xShmLock(pSubOpen, ofst, n, flags);
+ }
+ return SQLITE_BUSY;
+}
+
+/* Pass xShmBarrier requests through to the original VFS unchanged.
+*/
+static void multiplexShmBarrier(sqlite3_file *pConn){
+ multiplexConn *p = (multiplexConn*)pConn;
+ int rc;
+ sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen ){
+ pSubOpen->pMethods->xShmBarrier(pSubOpen);
+ }
+}
+
+/* Pass xShmUnmap requests through to the original VFS unchanged.
+*/
+static int multiplexShmUnmap(sqlite3_file *pConn, int deleteFlag){
+ multiplexConn *p = (multiplexConn*)pConn;
+ int rc;
+ sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
+ if( pSubOpen ){
+ return pSubOpen->pMethods->xShmUnmap(pSubOpen, deleteFlag);
+ }
+ return SQLITE_OK;
+}
+
+/************************** Public Interfaces *****************************/
+/*
+** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize()
+**
+** Use the VFS named zOrigVfsName as the VFS that does the actual work.
+** Use the default if zOrigVfsName==NULL.
+**
+** The multiplex VFS shim is named "multiplex". It will become the default
+** VFS if makeDefault is non-zero.
+**
+** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once
+** during start-up.
+*/
+int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){
+ sqlite3_vfs *pOrigVfs;
+ if( gMultiplex.isInitialized ) return SQLITE_MISUSE;
+ pOrigVfs = sqlite3_vfs_find(zOrigVfsName);
+ if( pOrigVfs==0 ) return SQLITE_ERROR;
+ assert( pOrigVfs!=&gMultiplex.sThisVfs );
+ gMultiplex.isInitialized = 1;
+ gMultiplex.pOrigVfs = pOrigVfs;
+ gMultiplex.sThisVfs = *pOrigVfs;
+ gMultiplex.sThisVfs.szOsFile += sizeof(multiplexConn);
+ gMultiplex.sThisVfs.zName = SQLITE_MULTIPLEX_VFS_NAME;
+ gMultiplex.sThisVfs.xOpen = multiplexOpen;
+ gMultiplex.sThisVfs.xDelete = multiplexDelete;
+ gMultiplex.sThisVfs.xAccess = multiplexAccess;
+ gMultiplex.sThisVfs.xFullPathname = multiplexFullPathname;
+ gMultiplex.sThisVfs.xDlOpen = multiplexDlOpen;
+ gMultiplex.sThisVfs.xDlError = multiplexDlError;
+ gMultiplex.sThisVfs.xDlSym = multiplexDlSym;
+ gMultiplex.sThisVfs.xDlClose = multiplexDlClose;
+ gMultiplex.sThisVfs.xRandomness = multiplexRandomness;
+ gMultiplex.sThisVfs.xSleep = multiplexSleep;
+ gMultiplex.sThisVfs.xCurrentTime = multiplexCurrentTime;
+ gMultiplex.sThisVfs.xGetLastError = multiplexGetLastError;
+ gMultiplex.sThisVfs.xCurrentTimeInt64 = multiplexCurrentTimeInt64;
+
+ gMultiplex.sIoMethodsV1.iVersion = 1;
+ gMultiplex.sIoMethodsV1.xClose = multiplexClose;
+ gMultiplex.sIoMethodsV1.xRead = multiplexRead;
+ gMultiplex.sIoMethodsV1.xWrite = multiplexWrite;
+ gMultiplex.sIoMethodsV1.xTruncate = multiplexTruncate;
+ gMultiplex.sIoMethodsV1.xSync = multiplexSync;
+ gMultiplex.sIoMethodsV1.xFileSize = multiplexFileSize;
+ gMultiplex.sIoMethodsV1.xLock = multiplexLock;
+ gMultiplex.sIoMethodsV1.xUnlock = multiplexUnlock;
+ gMultiplex.sIoMethodsV1.xCheckReservedLock = multiplexCheckReservedLock;
+ gMultiplex.sIoMethodsV1.xFileControl = multiplexFileControl;
+ gMultiplex.sIoMethodsV1.xSectorSize = multiplexSectorSize;
+ gMultiplex.sIoMethodsV1.xDeviceCharacteristics =
+ multiplexDeviceCharacteristics;
+ gMultiplex.sIoMethodsV2 = gMultiplex.sIoMethodsV1;
+ gMultiplex.sIoMethodsV2.iVersion = 2;
+ gMultiplex.sIoMethodsV2.xShmMap = multiplexShmMap;
+ gMultiplex.sIoMethodsV2.xShmLock = multiplexShmLock;
+ gMultiplex.sIoMethodsV2.xShmBarrier = multiplexShmBarrier;
+ gMultiplex.sIoMethodsV2.xShmUnmap = multiplexShmUnmap;
+ sqlite3_vfs_register(&gMultiplex.sThisVfs, makeDefault);
+
+ sqlite3_auto_extension((void(*)(void))multiplexFuncInit);
+
+ return SQLITE_OK;
+}
+
+/*
+** CAPI: Shutdown the multiplex system - sqlite3_multiplex_shutdown()
+**
+** All SQLite database connections must be closed before calling this
+** routine.
+**
+** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while
+** shutting down in order to free all remaining multiplex groups.
+*/
+int sqlite3_multiplex_shutdown(int eForce){
+ int rc = SQLITE_OK;
+ if( gMultiplex.isInitialized==0 ) return SQLITE_MISUSE;
+ gMultiplex.isInitialized = 0;
+ sqlite3_vfs_unregister(&gMultiplex.sThisVfs);
+ memset(&gMultiplex, 0, sizeof(gMultiplex));
+ return rc;
+}
+
+/***************************** Test Code ***********************************/
+#ifdef SQLITE_TEST
+#if defined(INCLUDE_SQLITE_TCL_H)
# error #include "sqlite_tcl.h"
-#else
-# include "tcl.h"
-# ifndef SQLITE_TCLAPI
-# define SQLITE_TCLAPI
-# endif
-#endif
-extern const char *sqlite3ErrName(int);
-
-
-/*
-** tclcmd: sqlite3_multiplex_initialize NAME MAKEDEFAULT
-*/
-static int SQLITE_TCLAPI test_multiplex_initialize(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- const char *zName; /* Name of new multiplex VFS */
- int makeDefault; /* True to make the new VFS the default */
- int rc; /* Value returned by multiplex_initialize() */
-
- UNUSED_PARAMETER(clientData);
-
- /* Process arguments */
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "NAME MAKEDEFAULT");
- return TCL_ERROR;
- }
- zName = Tcl_GetString(objv[1]);
- if( Tcl_GetBooleanFromObj(interp, objv[2], &makeDefault) ) return TCL_ERROR;
- if( zName[0]=='\0' ) zName = 0;
-
- /* Call sqlite3_multiplex_initialize() */
- rc = sqlite3_multiplex_initialize(zName, makeDefault);
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
-
- return TCL_OK;
-}
-
-/*
-** tclcmd: sqlite3_multiplex_shutdown
-*/
-static int SQLITE_TCLAPI test_multiplex_shutdown(
- void * clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int rc; /* Value returned by multiplex_shutdown() */
-
- UNUSED_PARAMETER(clientData);
-
- if( objc==2 && strcmp(Tcl_GetString(objv[1]),"-force")!=0 ){
- objc = 3;
- }
- if( (objc!=1 && objc!=2) ){
- Tcl_WrongNumArgs(interp, 1, objv, "?-force?");
- return TCL_ERROR;
- }
-
- /* Call sqlite3_multiplex_shutdown() */
- rc = sqlite3_multiplex_shutdown(objc==2);
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
-
- return TCL_OK;
-}
-
-/*
-** Tclcmd: test_multiplex_control HANDLE DBNAME SUB-COMMAND ?INT-VALUE?
-*/
-static int SQLITE_TCLAPI test_multiplex_control(
- ClientData cd,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
- int rc; /* Return code from file_control() */
- int idx; /* Index in aSub[] */
- Tcl_CmdInfo cmdInfo; /* Command info structure for HANDLE */
- sqlite3 *db; /* Underlying db handle for HANDLE */
- int iValue = 0;
- void *pArg = 0;
-
- struct SubCommand {
- const char *zName;
- int op;
- int argtype;
- } aSub[] = {
- { "enable", MULTIPLEX_CTRL_ENABLE, 1 },
- { "chunk_size", MULTIPLEX_CTRL_SET_CHUNK_SIZE, 1 },
- { "max_chunks", MULTIPLEX_CTRL_SET_MAX_CHUNKS, 1 },
- { 0, 0, 0 }
- };
-
- if( objc!=5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "HANDLE DBNAME SUB-COMMAND INT-VALUE");
- return TCL_ERROR;
- }
-
- if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
- Tcl_AppendResult(interp, "expected database handle, got \"", 0);
- Tcl_AppendResult(interp, Tcl_GetString(objv[1]), "\"", 0);
- return TCL_ERROR;
- }else{
- db = *(sqlite3 **)cmdInfo.objClientData;
- }
-
- rc = Tcl_GetIndexFromObjStruct(
- interp, objv[3], aSub, sizeof(aSub[0]), "sub-command", 0, &idx
- );
- if( rc!=TCL_OK ) return rc;
-
- switch( aSub[idx].argtype ){
- case 1:
- if( Tcl_GetIntFromObj(interp, objv[4], &iValue) ){
- return TCL_ERROR;
- }
- pArg = (void *)&iValue;
- break;
- default:
- Tcl_WrongNumArgs(interp, 4, objv, "SUB-COMMAND");
- return TCL_ERROR;
- }
-
- rc = sqlite3_file_control(db, Tcl_GetString(objv[2]), aSub[idx].op, pArg);
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
- return (rc==SQLITE_OK) ? TCL_OK : TCL_ERROR;
-}
-
-/*
-** This routine registers the custom TCL commands defined in this
-** module. This should be the only procedure visible from outside
-** of this module.
-*/
-int Sqlitemultiplex_Init(Tcl_Interp *interp){
- static struct {
- char *zName;
- Tcl_ObjCmdProc *xProc;
- } aCmd[] = {
- { "sqlite3_multiplex_initialize", test_multiplex_initialize },
- { "sqlite3_multiplex_shutdown", test_multiplex_shutdown },
- { "sqlite3_multiplex_control", test_multiplex_control },
- };
- int i;
-
- for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
- Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
- }
-
- return TCL_OK;
-}
-#endif
+#else
+# include "tcl.h"
+# ifndef SQLITE_TCLAPI
+# define SQLITE_TCLAPI
+# endif
+#endif
+extern const char *sqlite3ErrName(int);
+
+
+/*
+** tclcmd: sqlite3_multiplex_initialize NAME MAKEDEFAULT
+*/
+static int SQLITE_TCLAPI test_multiplex_initialize(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ const char *zName; /* Name of new multiplex VFS */
+ int makeDefault; /* True to make the new VFS the default */
+ int rc; /* Value returned by multiplex_initialize() */
+
+ UNUSED_PARAMETER(clientData);
+
+ /* Process arguments */
+ if( objc!=3 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "NAME MAKEDEFAULT");
+ return TCL_ERROR;
+ }
+ zName = Tcl_GetString(objv[1]);
+ if( Tcl_GetBooleanFromObj(interp, objv[2], &makeDefault) ) return TCL_ERROR;
+ if( zName[0]=='\0' ) zName = 0;
+
+ /* Call sqlite3_multiplex_initialize() */
+ rc = sqlite3_multiplex_initialize(zName, makeDefault);
+ Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
+
+ return TCL_OK;
+}
+
+/*
+** tclcmd: sqlite3_multiplex_shutdown
+*/
+static int SQLITE_TCLAPI test_multiplex_shutdown(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ int rc; /* Value returned by multiplex_shutdown() */
+
+ UNUSED_PARAMETER(clientData);
+
+ if( objc==2 && strcmp(Tcl_GetString(objv[1]),"-force")!=0 ){
+ objc = 3;
+ }
+ if( (objc!=1 && objc!=2) ){
+ Tcl_WrongNumArgs(interp, 1, objv, "?-force?");
+ return TCL_ERROR;
+ }
+
+ /* Call sqlite3_multiplex_shutdown() */
+ rc = sqlite3_multiplex_shutdown(objc==2);
+ Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
+
+ return TCL_OK;
+}
+
+/*
+** Tclcmd: test_multiplex_control HANDLE DBNAME SUB-COMMAND ?INT-VALUE?
+*/
+static int SQLITE_TCLAPI test_multiplex_control(
+ ClientData cd,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ int rc; /* Return code from file_control() */
+ int idx; /* Index in aSub[] */
+ Tcl_CmdInfo cmdInfo; /* Command info structure for HANDLE */
+ sqlite3 *db; /* Underlying db handle for HANDLE */
+ int iValue = 0;
+ void *pArg = 0;
+
+ struct SubCommand {
+ const char *zName;
+ int op;
+ int argtype;
+ } aSub[] = {
+ { "enable", MULTIPLEX_CTRL_ENABLE, 1 },
+ { "chunk_size", MULTIPLEX_CTRL_SET_CHUNK_SIZE, 1 },
+ { "max_chunks", MULTIPLEX_CTRL_SET_MAX_CHUNKS, 1 },
+ { 0, 0, 0 }
+ };
+
+ if( objc!=5 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "HANDLE DBNAME SUB-COMMAND INT-VALUE");
+ return TCL_ERROR;
+ }
+
+ if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
+ Tcl_AppendResult(interp, "expected database handle, got \"", 0);
+ Tcl_AppendResult(interp, Tcl_GetString(objv[1]), "\"", 0);
+ return TCL_ERROR;
+ }else{
+ db = *(sqlite3 **)cmdInfo.objClientData;
+ }
+
+ rc = Tcl_GetIndexFromObjStruct(
+ interp, objv[3], aSub, sizeof(aSub[0]), "sub-command", 0, &idx
+ );
+ if( rc!=TCL_OK ) return rc;
+
+ switch( aSub[idx].argtype ){
+ case 1:
+ if( Tcl_GetIntFromObj(interp, objv[4], &iValue) ){
+ return TCL_ERROR;
+ }
+ pArg = (void *)&iValue;
+ break;
+ default:
+ Tcl_WrongNumArgs(interp, 4, objv, "SUB-COMMAND");
+ return TCL_ERROR;
+ }
+
+ rc = sqlite3_file_control(db, Tcl_GetString(objv[2]), aSub[idx].op, pArg);
+ Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
+ return (rc==SQLITE_OK) ? TCL_OK : TCL_ERROR;
+}
+
+/*
+** This routine registers the custom TCL commands defined in this
+** module. This should be the only procedure visible from outside
+** of this module.
+*/
+int Sqlitemultiplex_Init(Tcl_Interp *interp){
+ static struct {
+ char *zName;
+ Tcl_ObjCmdProc *xProc;
+ } aCmd[] = {
+ { "sqlite3_multiplex_initialize", test_multiplex_initialize },
+ { "sqlite3_multiplex_shutdown", test_multiplex_shutdown },
+ { "sqlite3_multiplex_control", test_multiplex_control },
+ };
+ int i;
+
+ for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
+ Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
+ }
+
+ return TCL_OK;
+}
+#endif
diff --git a/contrib/libs/sqlite3/test_multiplex.h b/contrib/libs/sqlite3/test_multiplex.h
index 3df7881bcf3..790c778a359 100644
--- a/contrib/libs/sqlite3/test_multiplex.h
+++ b/contrib/libs/sqlite3/test_multiplex.h
@@ -1,99 +1,99 @@
-/*
-** 2011 March 18
-**
-** 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 a VFS "shim" - a layer that sits in between the
-** pager and the real VFS.
-**
-** This particular shim enforces a multiplex system on DB files.
-** This shim shards/partitions a single DB file into smaller
-** "chunks" such that the total DB file size may exceed the maximum
-** file size of the underlying file system.
-**
-*/
-
-#ifndef SQLITE_TEST_MULTIPLEX_H
-#define SQLITE_TEST_MULTIPLEX_H
-
-/*
-** CAPI: File-control Operations Supported by Multiplex VFS
-**
-** Values interpreted by the xFileControl method of a Multiplex VFS db file-handle.
-**
-** MULTIPLEX_CTRL_ENABLE:
-** This file control is used to enable or disable the multiplex
-** shim.
-**
-** MULTIPLEX_CTRL_SET_CHUNK_SIZE:
-** This file control is used to set the maximum allowed chunk
-** size for a multiplex file set. The chunk size should be
-** a multiple of SQLITE_MAX_PAGE_SIZE, and will be rounded up
-** if not.
-**
-** MULTIPLEX_CTRL_SET_MAX_CHUNKS:
-** This file control is used to set the maximum number of chunks
-** allowed to be used for a mutliplex file set.
-*/
-#define MULTIPLEX_CTRL_ENABLE 214014
-#define MULTIPLEX_CTRL_SET_CHUNK_SIZE 214015
-#define MULTIPLEX_CTRL_SET_MAX_CHUNKS 214016
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
-** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize()
-**
-** Use the VFS named zOrigVfsName as the VFS that does the actual work.
-** Use the default if zOrigVfsName==NULL.
-**
-** The multiplex VFS shim is named "multiplex". It will become the default
-** VFS if makeDefault is non-zero.
-**
-** An auto-extension is registered which will make the function
-** multiplex_control() available to database connections. This
-** function gives access to the xFileControl interface of the
-** multiplex VFS shim.
-**
-** SELECT multiplex_control(<op>,<val>);
-**
-** <op>=1 MULTIPLEX_CTRL_ENABLE
-** <val>=0 disable
-** <val>=1 enable
-**
-** <op>=2 MULTIPLEX_CTRL_SET_CHUNK_SIZE
-** <val> int, chunk size
-**
-** <op>=3 MULTIPLEX_CTRL_SET_MAX_CHUNKS
-** <val> int, max chunks
-**
-** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once
-** during start-up.
-*/
-extern int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault);
-
-/*
-** CAPI: Shutdown the multiplex system - sqlite3_multiplex_shutdown()
-**
-** All SQLite database connections must be closed before calling this
-** routine.
-**
-** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while
-** shutting down in order to free all remaining multiplex groups.
-*/
-extern int sqlite3_multiplex_shutdown(int eForce);
-
-#ifdef __cplusplus
-} /* End of the 'extern "C"' block */
-#endif
-
-#endif /* SQLITE_TEST_MULTIPLEX_H */
+/*
+** 2011 March 18
+**
+** 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 a VFS "shim" - a layer that sits in between the
+** pager and the real VFS.
+**
+** This particular shim enforces a multiplex system on DB files.
+** This shim shards/partitions a single DB file into smaller
+** "chunks" such that the total DB file size may exceed the maximum
+** file size of the underlying file system.
+**
+*/
+
+#ifndef SQLITE_TEST_MULTIPLEX_H
+#define SQLITE_TEST_MULTIPLEX_H
+
+/*
+** CAPI: File-control Operations Supported by Multiplex VFS
+**
+** Values interpreted by the xFileControl method of a Multiplex VFS db file-handle.
+**
+** MULTIPLEX_CTRL_ENABLE:
+** This file control is used to enable or disable the multiplex
+** shim.
+**
+** MULTIPLEX_CTRL_SET_CHUNK_SIZE:
+** This file control is used to set the maximum allowed chunk
+** size for a multiplex file set. The chunk size should be
+** a multiple of SQLITE_MAX_PAGE_SIZE, and will be rounded up
+** if not.
+**
+** MULTIPLEX_CTRL_SET_MAX_CHUNKS:
+** This file control is used to set the maximum number of chunks
+** allowed to be used for a mutliplex file set.
+*/
+#define MULTIPLEX_CTRL_ENABLE 214014
+#define MULTIPLEX_CTRL_SET_CHUNK_SIZE 214015
+#define MULTIPLEX_CTRL_SET_MAX_CHUNKS 214016
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize()
+**
+** Use the VFS named zOrigVfsName as the VFS that does the actual work.
+** Use the default if zOrigVfsName==NULL.
+**
+** The multiplex VFS shim is named "multiplex". It will become the default
+** VFS if makeDefault is non-zero.
+**
+** An auto-extension is registered which will make the function
+** multiplex_control() available to database connections. This
+** function gives access to the xFileControl interface of the
+** multiplex VFS shim.
+**
+** SELECT multiplex_control(<op>,<val>);
+**
+** <op>=1 MULTIPLEX_CTRL_ENABLE
+** <val>=0 disable
+** <val>=1 enable
+**
+** <op>=2 MULTIPLEX_CTRL_SET_CHUNK_SIZE
+** <val> int, chunk size
+**
+** <op>=3 MULTIPLEX_CTRL_SET_MAX_CHUNKS
+** <val> int, max chunks
+**
+** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once
+** during start-up.
+*/
+extern int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault);
+
+/*
+** CAPI: Shutdown the multiplex system - sqlite3_multiplex_shutdown()
+**
+** All SQLite database connections must be closed before calling this
+** routine.
+**
+** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while
+** shutting down in order to free all remaining multiplex groups.
+*/
+extern int sqlite3_multiplex_shutdown(int eForce);
+
+#ifdef __cplusplus
+} /* End of the 'extern "C"' block */
+#endif
+
+#endif /* SQLITE_TEST_MULTIPLEX_H */